OPDEF(MINT_NEWOBJ_STRING_UNOPT, "newobj_string_unopt", 4, 1, 0, MintOpMethodToken)
OPDEF(MINT_NEWOBJ_SLOW, "newobj_slow", 4, 1, 1, MintOpMethodToken)
-OPDEF(MINT_NEWOBJ_ARRAY, "newobj_array", 5, 1, 1, MintOpMethodToken)
+OPDEF(MINT_NEWOBJ_ARRAY, "newobj_array", 5, 1, 1, MintOpClassToken)
OPDEF(MINT_NEWOBJ_STRING, "newobj_string", 4, 1, 1, MintOpMethodToken)
OPDEF(MINT_NEWOBJ, "newobj", 5, 1, 1, MintOpMethodToken)
-OPDEF(MINT_NEWOBJ_INLINED, "newobj_inlined", 3, 1, 0, MintOpMethodToken)
+OPDEF(MINT_NEWOBJ_INLINED, "newobj_inlined", 3, 1, 0, MintOpVTableToken)
OPDEF(MINT_NEWOBJ_VT, "newobj_vt", 5, 1, 1, MintOpMethodToken)
-OPDEF(MINT_NEWOBJ_VT_INLINED, "newobj_vt_inlined", 4, 1, 1, MintOpMethodToken)
+OPDEF(MINT_NEWOBJ_VT_INLINED, "newobj_vt_inlined", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_INITOBJ, "initobj", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_CASTCLASS, "castclass", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_ISINST, "isinst", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_ISINST_INTERFACE, "isinst.interface", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_CASTCLASS_COMMON, "castclass.common", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_ISINST_COMMON, "isinst.common", 4, 1, 1, MintOpClassToken)
-OPDEF(MINT_NEWARR, "newarr", 4, 1, 1, MintOpClassToken)
+OPDEF(MINT_NEWARR, "newarr", 4, 1, 1, MintOpVTableToken)
OPDEF(MINT_NEWSTR, "newstr", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_BOX, "box", 4, 1, 1, MintOpShortInt)
-OPDEF(MINT_BOX_VT, "box.vt", 4, 1, 1, MintOpShortInt)
-OPDEF(MINT_BOX_PTR, "box.ptr", 4, 1, 1, MintOpShortInt)
-OPDEF(MINT_BOX_NULLABLE_PTR, "box.nullable.ptr", 4, 1, 1, MintOpShortInt)
+OPDEF(MINT_BOX, "box", 4, 1, 1, MintOpVTableToken)
+OPDEF(MINT_BOX_VT, "box.vt", 4, 1, 1, MintOpVTableToken)
+OPDEF(MINT_BOX_PTR, "box.ptr", 4, 1, 1, MintOpVTableToken)
+OPDEF(MINT_BOX_NULLABLE_PTR, "box.nullable.ptr", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_UNBOX, "unbox", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_LDFTN, "ldftn", 3, 1, 0, MintOpMethodToken)
-OPDEF(MINT_LDFTN_ADDR, "ldftn_addr", 3, 1, 0, MintOpMethodToken)
-OPDEF(MINT_LDFTN_DYNAMIC, "ldftn.dynamic", 3, 1, 1, MintOpMethodToken)
+OPDEF(MINT_LDFTN_ADDR, "ldftn_addr", 3, 1, 0, MintOpShortInt)
+OPDEF(MINT_LDFTN_DYNAMIC, "ldftn.dynamic", 3, 1, 1, MintOpShortInt)
OPDEF(MINT_LDVIRTFTN, "ldvirtftn", 4, 1, 1, MintOpMethodToken)
OPDEF(MINT_CPOBJ, "cpobj", 4, 0, 2, MintOpClassToken)
OPDEF(MINT_CPOBJ_VT, "cpobj.vt", 4, 0, 2, MintOpClassToken)
OPDEF(MINT_CALLVIRT_FAST, "callvirt.fast", 5, 1, 1, MintOpMethodToken)
OPDEF(MINT_CALL_DELEGATE, "call.delegate", 5, 1, 1, MintOpTwoShorts)
OPDEF(MINT_CALLI, "calli", 4, 1, 2, MintOpNoArgs)
-OPDEF(MINT_CALLI_NAT, "calli.nat", 8, 1, 2, MintOpMethodToken)
-OPDEF(MINT_CALLI_NAT_DYNAMIC, "calli.nat.dynamic", 5, 1, 2, MintOpMethodToken)
-OPDEF(MINT_CALLI_NAT_FAST, "calli.nat.fast", 7, 1, 2, MintOpMethodToken)
+OPDEF(MINT_CALLI_NAT, "calli.nat", 8, 1, 2, MintOpTwoShorts)
+OPDEF(MINT_CALLI_NAT_DYNAMIC, "calli.nat.dynamic", 5, 1, 2, MintOpShortInt)
+OPDEF(MINT_CALLI_NAT_FAST, "calli.nat.fast", 7, 1, 2, MintOpTwoShorts)
OPDEF(MINT_CALL_VARARG, "call.vararg", 6, 1, 1, MintOpMethodToken)
OPDEF(MINT_TAILCALL, "tailcall", 4, 0, 1, MintOpMethodToken)
OPDEF(MINT_TAILCALL_VIRT, "tailcall.virt", 5, 0, 1, MintOpMethodToken)
* ip is the address where the arguments of the instruction are located
*/
static char*
-dump_interp_ins_data (InterpInst *ins, gint32 ins_offset, const guint16 *data, int opcode)
+dump_interp_ins_data (InterpInst *ins, gint32 ins_offset, const guint16 *data, int opcode, gpointer *data_items)
{
GString *str = g_string_new ("");
- guint32 token;
int target;
switch (mono_interp_opargtype [opcode]) {
case MintOpShortInt:
g_string_append_printf (str, " %d", *(gint16*)data);
break;
- case MintOpClassToken:
- case MintOpMethodToken:
- case MintOpFieldToken:
- token = * (guint16 *) data;
- g_string_append_printf (str, " %u", token);
+ case MintOpClassToken: {
+ MonoClass *klass = (MonoClass*)data_items [*(guint16*)data];
+ g_string_append_printf (str, " %s.%s", m_class_get_name_space (klass), m_class_get_name (klass));
+ break;
+ }
+ case MintOpVTableToken: {
+ MonoVTable *vtable = (MonoVTable*)data_items [*(guint16*)data];
+ g_string_append_printf (str, " %s.%s", m_class_get_name_space (vtable->klass), m_class_get_name (vtable->klass));
+ break;
+ }
+ case MintOpMethodToken: {
+ InterpMethod *imethod = (InterpMethod*)data_items [*(guint16*)data];
+ char *name = mono_method_full_name (imethod->method, TRUE);
+ g_string_append_printf (str, " %s", name);
+ g_free (name);
break;
+ }
case MintOpInt:
g_string_append_printf (str, " %d", (gint32)READ32 (data));
break;
}
static void
-dump_interp_compacted_ins (const guint16 *ip, const guint16 *start)
+dump_interp_compacted_ins (const guint16 *ip, const guint16 *start, gpointer *data_items)
{
int opcode = *ip;
int ins_offset = GPTRDIFF_TO_INT (ip - start);
} else {
g_string_append_printf (str, " nil],");
}
- char *ins_data = dump_interp_ins_data (NULL, ins_offset, ip, opcode);
+ char *ins_data = dump_interp_ins_data (NULL, ins_offset, ip, opcode, data_items);
g_print ("%s%s\n", str->str, ins_data);
g_string_free (str, TRUE);
g_free (ins_data);
}
static void
-dump_interp_code (const guint16 *start, const guint16* end)
+dump_interp_code (const guint16 *start, const guint16* end, gpointer *data_items)
{
const guint16 *p = start;
while (p < end) {
- dump_interp_compacted_ins (p, start);
+ dump_interp_compacted_ins (p, start, data_items);
p = mono_interp_dis_mintop_len (p);
}
}
static void
-dump_interp_inst (InterpInst *ins)
+dump_interp_inst (InterpInst *ins, gpointer *data_items)
{
int opcode = ins->opcode;
GString *str = g_string_new ("");
// LDLOCA has special semantics, it has data in sregs [0], but it doesn't have any sregs
g_string_append_printf (str, " %d", ins->sregs [0]);
} else {
- char *descr = dump_interp_ins_data (ins, ins->il_offset, &ins->data [0], ins->opcode);
+ char *descr = dump_interp_ins_data (ins, ins->il_offset, &ins->data [0], ins->opcode, data_items);
g_string_append_printf (str, "%s", descr);
g_free (descr);
}
}
static void
-dump_interp_bb (InterpBasicBlock *bb)
+dump_interp_bb (InterpBasicBlock *bb, gpointer *data_items)
{
g_print ("BB%d:\n", bb->index);
for (InterpInst *ins = bb->first_ins; ins != NULL; ins = ins->next) {
// Avoid some noise
if (ins->opcode != MINT_NOP && ins->opcode != MINT_IL_SEQ_POINT)
- dump_interp_inst (ins);
+ dump_interp_inst (ins, data_items);
}
}
g_free (name);
start = (guint8*) jinfo->code_start;
- dump_interp_code ((const guint16*)start, (const guint16*)(start + jinfo->code_size));
+ dump_interp_code ((const guint16*)start, (const guint16*)(start + jinfo->code_size), imethod->data_items);
}
/* For debug use */
{
g_print ("Unoptimized IR:\n");
for (InterpBasicBlock *bb = td->entry_bb; bb != NULL; bb = bb->next_bb)
- dump_interp_bb (bb);
+ dump_interp_bb (bb, td->data_items);
}
if (td->locals [dreg].flags & INTERP_LOCAL_FLAG_DEAD) {
if (td->verbose_level) {
g_print ("kill dead ins:\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
if (ins->opcode == MINT_LDLOCA_S) {
if (td->verbose_level) {
g_print ("Fold unop :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
local_ref_count [sreg]--;
if (td->verbose_level) {
g_print ("Fold unop cond br :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
mono_interp_stats.constant_folds++;
if (td->verbose_level) {
g_print ("Fold binop :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
local_ref_count [sreg1]--;
}
if (td->verbose_level) {
g_print ("Fold binop cond br :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
mono_interp_stats.constant_folds++;
if (td->verbose_level) {
g_print ("Fold simd create:\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
local_defs [dreg].ins = ins;
*psreg = cprop_local;
local_ref_count [cprop_local]++;
if (td->verbose_level)
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
} else if (!local_defs [sreg].ins) {
td->locals [sreg].flags |= INTERP_LOCAL_FLAG_UNKNOWN_USE;
}
td->local_ref_count [def_ins->sregs [i]]--;
if (td->verbose_level) {
g_print ("kill unused local def:\n\t");
- dump_interp_inst (def_ins);
+ dump_interp_inst (def_ins, td->data_items);
}
interp_clear_ins (def_ins);
}
gint32 dreg = ins->dreg;
if (td->verbose_level && ins->opcode != MINT_NOP && ins->opcode != MINT_IL_SEQ_POINT)
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
for (int i = 0; i < num_sregs; i++) {
if (sregs [i] == MINT_CALL_ARGS_SREG) {
mono_interp_stats.copy_propagations++;
if (td->verbose_level) {
g_print ("cprop loc %d -> ct :\n\t", sreg);
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
} else if (local_defs [sreg].ins != NULL &&
(td->locals [sreg].flags & INTERP_LOCAL_FLAG_EXECUTION_STACK) &&
if (td->verbose_level) {
g_print ("cprop dreg:\n\t");
- dump_interp_inst (def);
+ dump_interp_inst (def, td->data_items);
g_print ("\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
} else {
if (td->verbose_level)
ins->sregs [0] = sreg;
if (td->verbose_level) {
g_print ("Replace idempotent binop :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
if (td->verbose_level) {
g_print ("Replace ldloca/ldind pair :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
if (td->verbose_level) {
g_print ("Replace ldloca/ldfld pair :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
if (td->verbose_level) {
g_print ("Replace ldloca/initobj pair :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
}
if (td->verbose_level) {
g_print ("Replace ldloca/ldobj_vt pair :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
}
} else if (MINT_IS_STIND (opcode)) {
if (td->verbose_level) {
g_print ("Replace ldloca/stind pair :\n\t");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
}
if (td->verbose_level) {
g_print ("Replace ldloca/stfld pair (off %p) :\n\t", (void *)(uintptr_t) ldloca->il_offset);
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
needs_retry = TRUE;
}
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
} else if (opcode == MINT_ADD_I4 || opcode == MINT_ADD_I8 ||
local_ref_count [sreg_imm]--;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
} else if (opcode == MINT_SUB_I4 || opcode == MINT_SUB_I8) {
local_ref_count [sreg_imm]--;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
} else if (opcode == MINT_MUL_I4_IMM || opcode == MINT_MUL_I8_IMM) {
local_ref_count [sreg]--;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
local_ref_count [sreg_imm]--;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
} else if (opcode == MINT_SHL_I4 || opcode == MINT_SHL_I8) {
int amount_var = ins->sregs [1];
interp_clear_ins (ins);
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
local_ref_count [sreg_imm]--;
if (td->verbose_level) {
g_print ("lower div.un: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("method %s:%s, superins: ", m_class_get_name (td->method->klass), td->method->name);
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
def->dreg == obj_sreg && local_ref_count [obj_sreg] == 1) {
if (td->verbose_level) {
g_print ("remove redundant cknull (%s): ", td->method->name);
- dump_interp_inst (def);
+ dump_interp_inst (def, td->data_items);
}
ins->sregs [0] = def->sregs [0];
interp_clear_ins (def);
local_ref_count [sreg_imm]--;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_ins);
+ dump_interp_inst (new_ins, td->data_items);
}
}
} else {
ins->opcode = GINT_TO_OPCODE (condbr_op);
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
}
}
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
// The newly added opcode could be part of further superinstructions. Retry
ins = ins->prev;
ins->opcode = GINT_TO_OPCODE (condbr_op);
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
}
}
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("superins: ");
- dump_interp_inst (new_inst);
+ dump_interp_inst (new_inst, td->data_items);
}
}
}
if (td->verbose_level) {
g_print ("\tins_index %d\t", ins_index);
- dump_interp_inst (ins);
+ dump_interp_inst (ins, td->data_items);
}
// Expire source vars. We first mark them as not alive and then compact the array
g_print ("Runtime method: %s %p\n", mono_method_full_name (method, TRUE), rtm);
g_print ("Locals size %d\n", td->total_locals_size);
g_print ("Calculated stack height: %d, stated height: %d\n", td->max_stack_height, header->max_stack);
- dump_interp_code (td->new_code, td->new_code_end);
+ dump_interp_code (td->new_code, td->new_code_end, td->data_items);
}
/* Check if we use excessive stack space */