@@ -2085,7 +2085,7 @@ void CodeGen::genEmitUnwindDebugGCandEH()
20852085
20862086 genIPmappingGen ();
20872087
2088- INDEBUG ( genDumpPreciseDebugInfo () );
2088+ genReportRichDebugInfo ( );
20892089
20902090 /* Finalize the Local Var info in terms of generated code */
20912091
@@ -7416,12 +7416,7 @@ void CodeGen::genIPmappingGen()
74167416 return ;
74177417 }
74187418
7419- #ifdef DEBUG
7420- if (verbose)
7421- {
7422- printf (" *************** In genIPmappingGen()\n " );
7423- }
7424- #endif
7419+ JITDUMP (" *************** In genIPmappingGen()\n " );
74257420
74267421 if (compiler->genIPmappings .size () <= 0 )
74277422 {
@@ -7560,11 +7555,20 @@ void CodeGen::genIPmappingGen()
75607555}
75617556
75627557#ifdef DEBUG
7563- void CodeGen::genDumpPreciseDebugInfoInlineTree (FILE* file, InlineContext* context, bool * first)
7558+ // ------------------------------------------------------------------------
7559+ // genReportRichDebugInfoInlineTreeToFile:
7560+ // Recursively process a context in the inline tree and write information about it to a file.
7561+ //
7562+ // Parameters:
7563+ // file - the file
7564+ // context - the context
7565+ // first - whether this is the first of the siblings being written out
7566+ //
7567+ void CodeGen::genReportRichDebugInfoInlineTreeToFile (FILE* file, InlineContext* context, bool * first)
75647568{
75657569 if (context->GetSibling () != nullptr )
75667570 {
7567- genDumpPreciseDebugInfoInlineTree (file, context->GetSibling (), first);
7571+ genReportRichDebugInfoInlineTreeToFile (file, context->GetSibling (), first);
75687572 }
75697573
75707574 if (context->IsSuccess ())
@@ -7577,42 +7581,53 @@ void CodeGen::genDumpPreciseDebugInfoInlineTree(FILE* file, InlineContext* conte
75777581 *first = false ;
75787582
75797583 fprintf (file, " {\" Ordinal\" :%u," , context->GetOrdinal ());
7580- fprintf (file, " \" MethodID\" :%lld," , (INT64)context->GetCallee ());
7584+ fprintf (file, " \" MethodID\" :%lld," , (int64_t )context->GetCallee ());
7585+ fprintf (file, " \" ILOffset\" :%u," , context->GetLocation ().GetOffset ());
7586+ fprintf (file, " \" LocationFlags\" :%u," , (uint32_t )context->GetLocation ().EncodeSourceTypes ());
7587+ fprintf (file, " \" ExactILOffset\" :%u," , context->GetActualCallOffset ());
75817588 const char * className;
75827589 const char * methodName = compiler->eeGetMethodName (context->GetCallee (), &className);
75837590 fprintf (file, " \" MethodName\" :\" %s\" ," , methodName);
75847591 fprintf (file, " \" Inlinees\" :[" );
75857592 if (context->GetChild () != nullptr )
75867593 {
75877594 bool childFirst = true ;
7588- genDumpPreciseDebugInfoInlineTree (file, context->GetChild (), &childFirst);
7595+ genReportRichDebugInfoInlineTreeToFile (file, context->GetChild (), &childFirst);
75897596 }
75907597 fprintf (file, " ]}" );
75917598 }
75927599}
75937600
7594- void CodeGen::genDumpPreciseDebugInfo ()
7601+ // ------------------------------------------------------------------------
7602+ // genReportRichDebugInfoToFile:
7603+ // Write rich debug info in JSON format to file specified by environment variable.
7604+ //
7605+ void CodeGen::genReportRichDebugInfoToFile ()
75957606{
7596- if (JitConfig.JitDumpPreciseDebugInfoFile () == nullptr )
7607+ if (JitConfig.WriteRichDebugInfoFile () == nullptr )
7608+ {
75977609 return ;
7610+ }
75987611
75997612 static CritSecObject s_critSect;
76007613 CritSecHolder holder (s_critSect);
76017614
7602- FILE* file = _wfopen (JitConfig.JitDumpPreciseDebugInfoFile (), W (" a" ));
7615+ FILE* file = _wfopen (JitConfig.WriteRichDebugInfoFile (), W (" a" ));
76037616 if (file == nullptr )
7617+ {
76047618 return ;
7619+ }
76057620
76067621 // MethodID in ETW events are the method handles.
76077622 fprintf (file, " {\" MethodID\" :%lld," , (INT64)compiler->info .compMethodHnd );
76087623 // Print inline tree.
76097624 fprintf (file, " \" InlineTree\" :" );
76107625
76117626 bool first = true ;
7612- genDumpPreciseDebugInfoInlineTree (file, compiler->compInlineContext , &first);
7627+ genReportRichDebugInfoInlineTreeToFile (file, compiler->compInlineContext , &first);
76137628 fprintf (file, " ,\" Mappings\" :[" );
76147629 first = true ;
7615- for (PreciseIPMapping & mapping : compiler->genPreciseIPmappings )
7630+ for (RichIPMapping & mapping : compiler->genRichIPmappings )
76167631 {
76177632 if (!first)
76187633 {
@@ -7631,14 +7646,106 @@ void CodeGen::genDumpPreciseDebugInfo()
76317646 fclose (file);
76327647}
76337648
7634- void CodeGen::genAddPreciseIPMappingHere (const DebugInfo& di)
7649+ #endif
7650+
7651+ // ------------------------------------------------------------------------
7652+ // genRecordRichDebugInfoInlineTree:
7653+ // Recursively process a context in the inline tree and record information
7654+ // about it.
7655+ //
7656+ // Parameters:
7657+ // context - the inline context
7658+ // nodes - the array to record into
7659+ //
7660+ void CodeGen::genRecordRichDebugInfoInlineTree (InlineContext* context, ICorDebugInfo::InlineTreeNode* nodes)
7661+ {
7662+ if (context->IsSuccess ())
7663+ {
7664+ // We expect 1 + NumInlines unique ordinals
7665+ assert (context->GetOrdinal () <= compiler->m_inlineStrategy ->GetInlineCount ());
7666+
7667+ ICorDebugInfo::InlineTreeNode* node = &nodes[context->GetOrdinal ()];
7668+ node->Method = context->GetCallee ();
7669+ node->ILOffset = context->GetActualCallOffset ();
7670+ node->Child = context->GetChild () == nullptr ? 0 : context->GetChild ()->GetOrdinal ();
7671+ node->Sibling = context->GetSibling () == nullptr ? 0 : context->GetSibling ()->GetOrdinal ();
7672+ }
7673+
7674+ if (context->GetSibling () != nullptr )
7675+ {
7676+ genRecordRichDebugInfoInlineTree (context->GetSibling (), nodes);
7677+ }
7678+
7679+ if (context->GetChild () != nullptr )
7680+ {
7681+ genRecordRichDebugInfoInlineTree (context->GetChild (), nodes);
7682+ }
7683+ }
7684+
7685+ // ------------------------------------------------------------------------
7686+ // genReportRichDebugInfo:
7687+ // If enabled, report rich debugging information to file and/or EE.
7688+ //
7689+ void CodeGen::genReportRichDebugInfo ()
7690+ {
7691+ INDEBUG (genReportRichDebugInfoToFile ());
7692+
7693+ if (JitConfig.RichDebugInfo () == 0 )
7694+ {
7695+ return ;
7696+ }
7697+
7698+ unsigned numContexts = 1 + compiler->m_inlineStrategy ->GetInlineCount ();
7699+ unsigned numRichMappings = static_cast <unsigned >(compiler->genRichIPmappings .size ());
7700+
7701+ ICorDebugInfo::InlineTreeNode* inlineTree = static_cast <ICorDebugInfo::InlineTreeNode*>(
7702+ compiler->info .compCompHnd ->allocateArray (numContexts * sizeof (ICorDebugInfo::InlineTreeNode)));
7703+ ICorDebugInfo::RichOffsetMapping* mappings = static_cast <ICorDebugInfo::RichOffsetMapping*>(
7704+ compiler->info .compCompHnd ->allocateArray (numRichMappings * sizeof (ICorDebugInfo::RichOffsetMapping)));
7705+
7706+ memset (inlineTree, 0 , numContexts * sizeof (ICorDebugInfo::InlineTreeNode));
7707+ memset (mappings, 0 , numRichMappings * sizeof (ICorDebugInfo::RichOffsetMapping));
7708+
7709+ genRecordRichDebugInfoInlineTree (compiler->compInlineContext , inlineTree);
7710+
7711+ #ifdef DEBUG
7712+ for (unsigned i = 0 ; i < numContexts; i++)
7713+ {
7714+ assert (inlineTree[i].Method != NO_METHOD_HANDLE);
7715+ }
7716+ #endif
7717+
7718+ size_t mappingIndex = 0 ;
7719+ for (const RichIPMapping& richMapping : compiler->genRichIPmappings )
7720+ {
7721+ ICorDebugInfo::RichOffsetMapping* mapping = &mappings[mappingIndex];
7722+ assert (richMapping.debugInfo .IsValid ());
7723+ mapping->NativeOffset = richMapping.nativeLoc .CodeOffset (GetEmitter ());
7724+ mapping->Inlinee = richMapping.debugInfo .GetInlineContext ()->GetOrdinal ();
7725+ mapping->ILOffset = richMapping.debugInfo .GetLocation ().GetOffset ();
7726+ mapping->Source = richMapping.debugInfo .GetLocation ().EncodeSourceTypes ();
7727+
7728+ mappingIndex++;
7729+ }
7730+
7731+ compiler->info .compCompHnd ->reportRichMappings (inlineTree, numContexts, mappings, numRichMappings);
7732+ }
7733+
7734+ // ------------------------------------------------------------------------
7735+ // genAddRichIPMappingHere:
7736+ // Create a rich IP mapping at the current emit location using the specified
7737+ // debug information.
7738+ //
7739+ // Parameters:
7740+ // di - the debug information
7741+ //
7742+ void CodeGen::genAddRichIPMappingHere (const DebugInfo& di)
76357743{
7636- PreciseIPMapping mapping;
7744+ RichIPMapping mapping;
76377745 mapping.nativeLoc .CaptureLocation (GetEmitter ());
76387746 mapping.debugInfo = di;
7639- compiler->genPreciseIPmappings .push_back (mapping);
7747+ compiler->genRichIPmappings .push_back (mapping);
76407748}
7641- #endif
76427749
76437750/* ============================================================================
76447751 *
0 commit comments