From: Vlad Brezae Date: Thu, 29 Jun 2023 14:26:23 +0000 (+0300) Subject: [mono][interp] Improve verbose output of dumped instructions (#88185) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~1321 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=205ac7665ce00fa5b61e1d9b0a5254e67df68cf6;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [mono][interp] Improve verbose output of dumped instructions (#88185) * [mono][interp] Improve verbose logging of instruction data Dump the method/class name instead of an index. * [mono][interp] Fix ins data type for various instructions Also add new data type for MonoVTable --- diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index 61b7a8a..fa73d20 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -357,12 +357,12 @@ OPDEF(MINT_MOV_STACK_UNOPT, "mov_stack_unopt", 4, 0, 0, MintOpTwoShorts) 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) @@ -370,16 +370,16 @@ OPDEF(MINT_CASTCLASS_INTERFACE, "castclass.interface", 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) @@ -688,9 +688,9 @@ OPDEF(MINT_CALL, "call", 4, 1, 1, MintOpMethodToken) 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) diff --git a/src/mono/mono/mini/interp/mintops.h b/src/mono/mono/mini/interp/mintops.h index 3006ee5..03fbf93 100644 --- a/src/mono/mono/mini/interp/mintops.h +++ b/src/mono/mono/mini/interp/mintops.h @@ -23,6 +23,7 @@ typedef enum MintOpMethodToken, MintOpFieldToken, MintOpClassToken, + MintOpVTableToken, MintOpTwoShorts, MintOpTwoInts, MintOpShortAndInt, diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 7848b7f..f416818 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1390,10 +1390,9 @@ alloc_global_var_offset (TransformData *td, int var) * 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]) { @@ -1414,12 +1413,23 @@ dump_interp_ins_data (InterpInst *ins, gint32 ins_offset, const guint16 *data, i 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; @@ -1497,7 +1507,7 @@ dump_interp_ins_data (InterpInst *ins, gint32 ins_offset, const guint16 *data, i } 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); @@ -1518,24 +1528,24 @@ dump_interp_compacted_ins (const guint16 *ip, const guint16 *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 (""); @@ -1570,7 +1580,7 @@ dump_interp_inst (InterpInst *ins) // 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); } @@ -1605,13 +1615,13 @@ get_interp_bb_links (InterpBasicBlock *bb) } 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); } } @@ -1631,7 +1641,7 @@ mono_interp_print_code (InterpMethod *imethod) 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 */ @@ -1640,7 +1650,7 @@ mono_interp_print_td_code (TransformData *td) { 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); } @@ -8948,7 +8958,7 @@ interp_local_deadce (TransformData *td) 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) { @@ -9069,7 +9079,7 @@ interp_fold_unop (TransformData *td, LocalValue *local_defs, InterpInst *ins) 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]--; @@ -9130,7 +9140,7 @@ interp_fold_unop_cond_br (TransformData *td, InterpBasicBlock *cbb, LocalValue * 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++; @@ -9259,7 +9269,7 @@ interp_fold_binop (TransformData *td, LocalValue *local_defs, InterpInst *ins, g 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]--; @@ -9331,7 +9341,7 @@ interp_fold_binop_cond_br (TransformData *td, InterpBasicBlock *cbb, LocalValue } 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++; @@ -9395,7 +9405,7 @@ interp_fold_simd_create (TransformData *td, InterpBasicBlock *cbb, LocalValue *l 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; @@ -9426,7 +9436,7 @@ cprop_sreg (TransformData *td, InterpInst *ins, int *psreg, LocalValue *local_de *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; } @@ -9463,7 +9473,7 @@ clear_unused_defs (TransformData *td, int var, void *data) 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); } @@ -9515,7 +9525,7 @@ retry: 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) { @@ -9587,7 +9597,7 @@ retry: 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) && @@ -9621,9 +9631,9 @@ retry: 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) @@ -9686,7 +9696,7 @@ retry: 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; } @@ -9717,7 +9727,7 @@ retry: 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; } @@ -9757,7 +9767,7 @@ retry: 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; } @@ -9778,7 +9788,7 @@ retry: 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; } @@ -9807,7 +9817,7 @@ retry: } 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)) { @@ -9825,7 +9835,7 @@ retry: 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; } @@ -9869,7 +9879,7 @@ retry: } 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; } @@ -10070,7 +10080,7 @@ interp_super_instructions (TransformData *td) 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 || @@ -10103,7 +10113,7 @@ interp_super_instructions (TransformData *td) 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) { @@ -10121,7 +10131,7 @@ interp_super_instructions (TransformData *td) 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) { @@ -10141,7 +10151,7 @@ interp_super_instructions (TransformData *td) local_ref_count [sreg]--; if (td->verbose_level) { g_print ("superins: "); - dump_interp_inst (new_inst); + dump_interp_inst (new_inst, td->data_items); } } } @@ -10160,7 +10170,7 @@ interp_super_instructions (TransformData *td) 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]; @@ -10189,7 +10199,7 @@ interp_super_instructions (TransformData *td) interp_clear_ins (ins); if (td->verbose_level) { g_print ("superins: "); - dump_interp_inst (new_inst); + dump_interp_inst (new_inst, td->data_items); } } } @@ -10224,7 +10234,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10253,7 +10263,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10290,7 +10300,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10319,7 +10329,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10334,7 +10344,7 @@ interp_super_instructions (TransformData *td) 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); @@ -10360,7 +10370,7 @@ interp_super_instructions (TransformData *td) 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 { @@ -10372,7 +10382,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10420,7 +10430,7 @@ interp_super_instructions (TransformData *td) 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; @@ -10436,7 +10446,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10455,7 +10465,7 @@ interp_super_instructions (TransformData *td) 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); } } } @@ -10878,7 +10888,7 @@ interp_alloc_offsets (TransformData *td) 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 @@ -11131,7 +11141,7 @@ retry: 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 */