Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/mono/mono into wasm-sdk-p…
Browse files Browse the repository at this point in the history
…ackages

Commit migrated from mono/mono@81b0163
  • Loading branch information
kjpou1 committed Apr 16, 2019
2 parents 2146bfe + 635e502 commit ec2da1a
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 94 deletions.
21 changes: 18 additions & 3 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,21 @@ arch_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean extern
g_assert_not_reached ();
#endif
}

static void
arch_emit_label_address (MonoAotCompile *acfg, const char *target, gboolean external_call, gboolean thumb, MonoJumpInfo *ji, int *call_size)
{
#if defined(TARGET_ARM) && defined(TARGET_ANDROID)
/* binutils ld does not support branch islands on arm32 */
if (!thumb) {
emit_unset_mode (acfg);
fprintf (acfg->fp, "ldr pc,=%s\n", target);
fprintf (acfg->fp, ".ltorg\n");
*call_size = 8;
} else
#endif
arch_emit_direct_call (acfg, target, external_call, thumb, ji, call_size);
}
#endif

/*
Expand Down Expand Up @@ -6032,7 +6047,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
if (direct_call) {
int call_size;

arch_emit_direct_call (acfg, direct_call_target, external_call, FALSE, patch_info, &call_size);
arch_emit_label_address (acfg, direct_call_target, external_call, FALSE, patch_info, &call_size);
i += call_size - INST_LEN;
} else {
int code_size;
Expand Down Expand Up @@ -9796,9 +9811,9 @@ emit_code (MonoAotCompile *acfg)
int call_size;

if (!ignore_cfg (acfg->cfgs [i])) {
arch_emit_direct_call (acfg, acfg->cfgs [i]->asm_symbol, FALSE, acfg->thumb_mixed && acfg->cfgs [i]->compile_llvm, NULL, &call_size);
arch_emit_label_address (acfg, acfg->cfgs [i]->asm_symbol, FALSE, acfg->thumb_mixed && acfg->cfgs [i]->compile_llvm, NULL, &call_size);
} else {
arch_emit_direct_call (acfg, symbol, FALSE, FALSE, NULL, &call_size);
arch_emit_label_address (acfg, symbol, FALSE, FALSE, NULL, &call_size);
}
#endif
}
Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/aot-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1946,13 +1946,20 @@ get_call_table_entry (void *table, int index)
guint32 ins;
gint32 offset;

ins_addr = (guint32 *)table + (index * 2);
if ((guint32) *ins_addr == (guint32 ) 0xe51ff004) { // ldr pc, =<label>
return *((char **) (ins_addr + 1));
}

ins_addr = (guint32*)table + index;
ins = *ins_addr;
if ((ins >> ARMCOND_SHIFT) == ARMCOND_NV) {
/* blx */
offset = (((int)(((ins & 0xffffff) << 1) | ((ins >> 24) & 0x1))) << 7) >> 7;
return (char*)ins_addr + (offset * 2) + 8 + 1;
} else {
g_assert ((ins >> ARMCOND_SHIFT) == ARMCOND_AL);
/* bl */
offset = (((int)ins & 0xffffff) << 8) >> 8;
return (char*)ins_addr + (offset * 4) + 8;
}
Expand Down
70 changes: 42 additions & 28 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4841,27 +4841,33 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, FrameClause
MINT_IN_CASE(MINT_LDSFLD_O) LDSFLD(p, gpointer); MINT_IN_BREAK;
MINT_IN_CASE(MINT_LDSFLD_P) LDSFLD(p, gpointer); MINT_IN_BREAK;

MINT_IN_CASE(MINT_LDSFLD) {
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (imethod->domain, field);
EXCEPTION_CHECKPOINT;
stackval_from_data (field->type, sp, addr, FALSE);
ip += 2;
++sp;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_LDSFLD_VT) {
// FIXME This is still 30 times slower than JIT. Could we optimize it even further ?
MonoVTable *vtable = (MonoVTable*) imethod->data_items [*(guint16*)(ip + 1)];
gpointer addr = imethod->data_items [*(guint16*)(ip + 2)];
MonoClass *klass = (MonoClass*) imethod->data_items [*(guint16*)(ip + 3)];
i32 = READ32(ip + 3);
INIT_VTABLE (vtable);
sp->data.p = vt_sp;
mono_value_copy_internal (vt_sp, addr, klass);

int size = mono_class_value_size (klass, NULL);
vt_sp += ALIGN_TO (size, MINT_VT_ALIGNMENT);
ip += 4;
memcpy (vt_sp, addr, i32);
vt_sp += ALIGN_TO (i32, MINT_VT_ALIGNMENT);
ip += 5;
++sp;
MINT_IN_BREAK;
}

MINT_IN_CASE(MINT_LDSSFLD_SLOW)
MINT_IN_CASE(MINT_LDSSFLD_VT_SLOW) {
gboolean is_vt = *ip == MINT_LDSSFLD_VT_SLOW;
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (imethod->domain, field);
EXCEPTION_CHECKPOINT;
if (is_vt) {
int size = READ32 (ip + 2);
sp->data.p = vt_sp;
vt_sp += ALIGN_TO (size, MINT_VT_ALIGNMENT);
}
stackval_from_data (field->type, sp, addr, FALSE);
ip += (is_vt ? 4 : 2);
++sp;
MINT_IN_BREAK;
}
Expand All @@ -4885,28 +4891,36 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, FrameClause
MINT_IN_CASE(MINT_STSFLD_P) STSFLD(p, gpointer); MINT_IN_BREAK;
MINT_IN_CASE(MINT_STSFLD_O) STSFLD(p, gpointer); MINT_IN_BREAK;

MINT_IN_CASE(MINT_STSFLD) {
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (imethod->domain, field);
EXCEPTION_CHECKPOINT;
ip += 2;
--sp;
stackval_to_data (field->type, sp, addr, FALSE);
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_STSFLD_VT) {
MonoVTable *vtable = (MonoVTable*) imethod->data_items [*(guint16*)(ip + 1)];
gpointer addr = imethod->data_items [*(guint16*)(ip + 2)];
MonoClass *klass = (MonoClass*) imethod->data_items [*(guint16*)(ip + 3)];
i32 = READ32(ip + 3);
INIT_VTABLE (vtable);
mono_value_copy_internal (addr, sp [-1].data.vt, klass);

int size = mono_class_value_size (klass, NULL);
vt_sp -= ALIGN_TO (size, MINT_VT_ALIGNMENT);
memcpy (addr, sp [-1].data.vt, i32);
vt_sp -= ALIGN_TO (i32, MINT_VT_ALIGNMENT);
ip += 4;
--sp;
MINT_IN_BREAK;
}

MINT_IN_CASE(MINT_STSSFLD_SLOW)
MINT_IN_CASE(MINT_STSSFLD_VT_SLOW) {
gboolean is_vt = *ip == MINT_STSSFLD_VT_SLOW;
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (imethod->domain, field);
EXCEPTION_CHECKPOINT;
--sp;
stackval_to_data (field->type, sp, addr, FALSE);
if (is_vt) {
int size = READ32 (ip + 2);
vt_sp -= ALIGN_TO (size, MINT_VT_ALIGNMENT);
ip += 4;
} else {
ip += 2;
}
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_STOBJ_VT) {
int size;
c = (MonoClass*)imethod->data_items[* (guint16 *)(ip + 1)];
Expand Down
10 changes: 6 additions & 4 deletions src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ OPDEF(MINT_STFLD_R8_UNALIGNED, "stfld.r8.unaligned", 2, MintOpUShortInt)
OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken)
OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 2, MintOpUShortInt)

OPDEF(MINT_LDSFLD, "ldsfld", 2, MintOpFieldToken)
OPDEF(MINT_LDSSFLD_SLOW, "ldssfld.slow", 2, MintOpFieldToken)
OPDEF(MINT_LDSSFLD_VT_SLOW, "ldssfld.vt.slow", 4, MintOpFieldToken)
OPDEF(MINT_LDSFLD_I1, "ldsfld.i1", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_U1, "ldsfld.u1", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_I2, "ldsfld.i2", 3, MintOpUShortInt)
Expand All @@ -118,9 +119,10 @@ OPDEF(MINT_LDSFLD_R4, "ldsfld.r4", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_R8, "ldsfld.r8", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_O, "ldsfld.o", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_P, "ldsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 4, MintOpTwoShorts)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 5, MintOpTwoShorts)

OPDEF(MINT_STSFLD, "stsfld", 2, MintOpUShortInt)
OPDEF(MINT_STSSFLD_SLOW, "stssfld.slow", 2, MintOpFieldToken)
OPDEF(MINT_STSSFLD_VT_SLOW, "stssfld.vt.slow", 4, MintOpFieldToken)
OPDEF(MINT_STSFLD_I1, "stsfld.i1", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_U1, "stsfld.u1", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_I2, "stsfld.i2", 3, MintOpUShortInt)
Expand All @@ -131,7 +133,7 @@ OPDEF(MINT_STSFLD_R4, "stsfld.r4", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_R8, "stsfld.r8", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_O, "stsfld.o", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_P, "stsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_VT, "stsfld.vt", 4, MintOpTwoShorts)
OPDEF(MINT_STSFLD_VT, "stsfld.vt", 5, MintOpTwoShorts)
OPDEF(MINT_LDSFLDA, "ldsflda", 2, MintOpUShortInt)

OPDEF(MINT_LDLOC_I1, "ldloc.i1", 2, MintOpUShortInt)
Expand Down
105 changes: 67 additions & 38 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,55 @@ interp_emit_stobj (TransformData *td, MonoClass *klass)
td->sp -= 2;
}

static void
interp_emit_ldsfld (TransformData *td, MonoClassField *field, MonoClass *field_class, int mt, MonoError *error)
{
if (mono_class_field_is_special_static (field)) {
interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSSFLD_VT_SLOW : MINT_LDSSFLD_SLOW);
td->last_ins->data [0] = get_data_item_index (td, field);
if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (field_class, NULL);
WRITE32_INS(td->last_ins, 1, &size);
}
} else {
MonoVTable *vtable = mono_class_vtable_checked (td->rtm->domain, field->parent, error);
return_if_nok (error);

interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSFLD_VT : (MINT_LDSFLD_I1 + mt - MINT_TYPE_I1));
td->last_ins->data [0] = get_data_item_index (td, vtable);
td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);

if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (field_class, NULL);
WRITE32_INS(td->last_ins, 2, &size);
}
}
}

static void
interp_emit_stsfld (TransformData *td, MonoClassField *field, MonoClass *field_class, int mt, MonoError *error)
{
if (mono_class_field_is_special_static (field)) {
interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSSFLD_VT_SLOW : MINT_STSSFLD_SLOW);
td->last_ins->data [0] = get_data_item_index (td, field);
if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (field_class, NULL);
WRITE32_INS(td->last_ins, 1, &size);
}
} else {
MonoVTable *vtable = mono_class_vtable_checked (td->rtm->domain, field->parent, error);
return_if_nok (error);

interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
td->last_ins->data [0] = get_data_item_index (td, vtable);
td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);

if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (field_class, NULL);
WRITE32_INS(td->last_ins, 2, &size);
}
}
}

static gboolean
generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, MonoGenericContext *generic_context, MonoError *error)
Expand Down Expand Up @@ -3990,8 +4039,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
if (is_static) {
interp_add_ins (td, MINT_POP);
td->last_ins->data [0] = 0;
interp_add_ins (td, mt == MINT_TYPE_VT ? MINT_LDSFLD_VT : MINT_LDSFLD);
td->last_ins->data [0] = get_data_item_index (td, field);
interp_emit_ldsfld (td, field, field_klass, mt, error);
goto_if_nok (error, exit);
} else {
int opcode = MINT_LDFLD_I1 + mt - MINT_TYPE_I1;
#ifdef NO_UNALIGNED_ACCESS
Expand Down Expand Up @@ -4041,6 +4090,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
goto_if_nok (error, exit);
MonoType *ftype = mono_field_get_type_internal (field);
gboolean is_static = !!(ftype->attrs & FIELD_ATTRIBUTE_STATIC);
MonoClass *field_klass = mono_class_from_mono_type_internal (ftype);
mono_class_init_internal (klass);
mt = mint_type (ftype);

Expand All @@ -4057,12 +4107,11 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
if (is_static) {
interp_add_ins (td, MINT_POP);
td->last_ins->data [0] = 1;
interp_add_ins (td, mt == MINT_TYPE_VT ? MINT_STSFLD_VT : MINT_STSFLD);
td->last_ins->data [0] = get_data_item_index (td, field);
interp_emit_stsfld (td, field, field_klass, mt, error);
goto_if_nok (error, exit);

/* the vtable of the field might not be initialized at this point */
MonoClass *fld_klass = mono_class_from_mono_type_internal (field->type);
mono_class_vtable_checked (domain, fld_klass, error);
mono_class_vtable_checked (domain, field_klass, error);
goto_if_nok (error, exit);
} else {
int opcode = MINT_STFLD_I1 + mt - MINT_TYPE_I1;
Expand All @@ -4076,15 +4125,13 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
td->last_ins->data [1] = get_data_item_index (td, field);

/* the vtable of the field might not be initialized at this point */
MonoClass *fld_klass = mono_class_from_mono_type_internal (field->type);
mono_class_vtable_checked (domain, fld_klass, error);
mono_class_vtable_checked (domain, field_klass, error);
goto_if_nok (error, exit);
}
}
}
if (mt == MINT_TYPE_VT) {
MonoClass *klass = mono_class_from_mono_type_internal (ftype);
int size = mono_class_value_size (klass, NULL);
int size = mono_class_value_size (field_klass, NULL);
POP_VT (td, size);
}
td->ip += 5;
Expand All @@ -4109,22 +4156,13 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
MonoType *ftype = mono_field_get_type_internal (field);
mt = mint_type (ftype);
klass = mono_class_from_mono_type_internal (ftype);
if (mono_class_field_is_special_static (field)) {
interp_add_ins (td, MINT_LDSFLD);
td->last_ins->data [0] = get_data_item_index (td, field);
} else {
MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
goto_if_nok (error, exit);

interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSFLD_VT : (MINT_LDSFLD_I1 + mt - MINT_TYPE_I1));
td->last_ins->data [0] = get_data_item_index (td, vtable);
td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);
interp_emit_ldsfld (td, field, klass, mt, error);
goto_if_nok (error, exit);

if (mt == MINT_TYPE_VT) {
td->last_ins->data [2] = get_data_item_index (td, klass);
int size = mono_class_value_size (klass, NULL);
PUSH_VT(td, size);
}
if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (klass, NULL);
PUSH_VT(td, size);
}
td->ip += 5;
PUSH_TYPE(td, stack_type [mt], klass);
Expand All @@ -4143,21 +4181,12 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
mono_class_vtable_checked (domain, fld_klass, error);
goto_if_nok (error, exit);

if (mono_class_field_is_special_static (field)) {
interp_add_ins (td, MINT_STSFLD);
td->last_ins->data [0] = get_data_item_index (td, field);
} else {
MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
goto_if_nok (error, exit);
interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
td->last_ins->data [0] = get_data_item_index (td, vtable);
td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);
interp_emit_stsfld (td, field, fld_klass, mt, error);
goto_if_nok (error, exit);

if (mt == MINT_TYPE_VT) {
td->last_ins->data [2] = get_data_item_index (td, fld_klass);
int size = mono_class_value_size (fld_klass, NULL);
POP_VT(td, size);
}
if (mt == MINT_TYPE_VT) {
int size = mono_class_value_size (fld_klass, NULL);
POP_VT(td, size);
}
td->ip += 5;
--td->sp;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3760,7 +3760,7 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
header.has_clauses)
return FALSE;

if (cfg->method->flags & METHOD_ATTRIBUTE_REQSECOBJ)
if (method->flags & METHOD_ATTRIBUTE_REQSECOBJ)
/* Used to mark methods containing StackCrawlMark locals */
return FALSE;

Expand Down
10 changes: 7 additions & 3 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3654,7 +3654,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
cinfo->rgctx_arg = TRUE;
if (call->imt_arg_reg)
cinfo->imt_arg = TRUE;
if (call->method && needs_extra_arg (ctx, call->method))
if (!call->rgctx_arg_reg && call->method && needs_extra_arg (ctx, call->method))
cinfo->dummy_arg = TRUE;

vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
Expand Down Expand Up @@ -3843,7 +3843,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
/*
* Collect and convert arguments
*/
nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg + 1;
nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg + call->cinfo->dummy_arg + 1;
len = sizeof (LLVMValueRef) * nargs;
args = g_newa (LLVMValueRef, nargs);
memset (args, 0, len);
Expand Down Expand Up @@ -3980,8 +3980,12 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,

l = l->next;
}
if (call->cinfo->dummy_arg)


if (call->cinfo->dummy_arg) {
g_assert (call->cinfo->dummy_arg_pindex < nargs);
args [call->cinfo->dummy_arg_pindex] = LLVMConstNull (ctx->module->ptr_type);
}

// FIXME: Align call sites

Expand Down
Loading

0 comments on commit ec2da1a

Please sign in to comment.