From 3ecbd8b4b4dc283207ffe6be60b78842d3767602 Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 16 Nov 2023 20:16:42 -0800 Subject: [PATCH 1/3] Added DOTNET_JitDisasmHexDumpFile --- src/coreclr/jit/codegencommon.cpp | 20 +++++++++++ src/coreclr/jit/compiler.cpp | 8 +++++ src/coreclr/jit/compiler.h | 35 ++++++++++--------- src/coreclr/jit/jitconfigvalues.h | 4 +++ .../superpmi-shim-collector/jithost.cpp | 1 + 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 225700208b4a2d..23a858182736cd 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2097,6 +2097,26 @@ void CodeGen::genEmitUnwindDebugGCandEH() getDisAssembler().disAsmCode((BYTE*)*codePtr, finalHotCodeSize, (BYTE*)coldCodePtr, finalColdCodeSize); #endif // LATE_DISASM +#ifdef DEBUG + if ((compiler->opts.disAsm || compiler->verbose) && compiler->opts.disAsmHexDumpFile) + { + FILE* hexDmpf; + errno_t ec = _wfopen_s(&hexDmpf, compiler->opts.disAsmHexDumpFile, W("at")); // NOTE: file append mode + if (ec == 0) + { + assert(hexDmpf); + + BYTE* addr = (BYTE*)*codePtr + compiler->GetEmitter()->writeableOffset; + for (unsigned int i = 0; i < codeSize; i++) + { + fprintf(hexDmpf, "%02X", *addr++); + } + + fclose(hexDmpf); + } + } +#endif // DEBUG + /* Report any exception handlers to the VM */ genReportEH(); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 355403baa92684..690f0d8b160b4a 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2847,6 +2847,8 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.compLongAddress = false; opts.optRepeat = false; + opts.disAsmHexDumpFile = nullptr; + #ifdef LATE_DISASM opts.doLateDisasm = false; #endif // LATE_DISASM @@ -2931,6 +2933,12 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.doLateDisasm = true; #endif // LATE_DISASM + const WCHAR* disAsmHexDumpFile = JitConfig.JitDisasmHexDumpFile(); + if (disAsmHexDumpFile != nullptr) + { + opts.disAsmHexDumpFile = disAsmHexDumpFile; + } + // This one applies to both Ngen/Jit Disasm output: DOTNET_JitDasmWithAddress=1 if (JitConfig.JitDasmWithAddress() != 0) { diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 48a3278077f622..ec50b1b7067e8e 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9705,23 +9705,24 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool disAlignment; // Display alignment boundaries in disassembly code bool disCodeBytes; // Display instruction code bytes in disassembly code #ifdef DEBUG - bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH - bool dspCode; // Display native code generated - bool dspEHTable; // Display the EH table reported to the VM - bool dspDebugInfo; // Display the Debug info reported to the VM - bool dspInstrs; // Display the IL instructions intermixed with the native code output - bool dspLines; // Display source-code lines intermixed with native code output - bool dmpHex; // Display raw bytes in hex of native code output - bool varNames; // Display variables names in native code output - bool disAsmSpilled; // Display native code when any register spilling occurs - bool disasmWithGC; // Display GC info interleaved with disassembly. - bool disAddr; // Display process address next to each instruction in disassembly code - bool disAsm2; // Display native code after it is generated using external disassembler - bool dspOrder; // Display names of each of the methods that we ngen/jit - bool dspUnwind; // Display the unwind info output - bool compLongAddress; // Force using large pseudo instructions for long address - // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) - bool dspGCtbls; // Display the GC tables + bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH + bool dspCode; // Display native code generated + bool dspEHTable; // Display the EH table reported to the VM + bool dspDebugInfo; // Display the Debug info reported to the VM + bool dspInstrs; // Display the IL instructions intermixed with the native code output + bool dspLines; // Display source-code lines intermixed with native code output + bool dmpHex; // Display raw bytes in hex of native code output + bool varNames; // Display variables names in native code output + bool disAsmSpilled; // Display native code when any register spilling occurs + bool disasmWithGC; // Display GC info interleaved with disassembly. + bool disAddr; // Display process address next to each instruction in disassembly code + bool disAsm2; // Display native code after it is generated using external disassembler + bool dspOrder; // Display names of each of the methods that we ngen/jit + bool dspUnwind; // Display the unwind info output + bool compLongAddress; // Force using large pseudo instructions for long address + // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) + bool dspGCtbls; // Display the GC tables + const WCHAR* disAsmHexDumpFile; // Writes the raw bytes in hex of native code to the specified file #endif // Default numbers used to perform loop alignment. All the numbers are chosen diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 65afd348819e11..9e1b1470362956 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -676,6 +676,10 @@ CONFIG_INTEGER(JitEnableCrossBlockLocalAssertionProp, W("JitEnableCrossBlockLoca CONFIG_STRING(JitFunctionFile, W("JitFunctionFile")) #endif // DEBUG +#if defined(DEBUG) +CONFIG_STRING(JitDisasmHexDumpFile, W("JitDisasmHexDumpFile")) +#endif // DEBUG + #if defined(DEBUG) #if defined(TARGET_ARM64) // JitSaveFpLrWithCalleeSavedRegisters: diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp index 2917fdab80cb43..35610f325f5344 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp @@ -86,6 +86,7 @@ bool RecordVariable(const WCHAR* key) W("JitInlinePolicyDumpXml"), W("JitInlineReplayFile"), W("JitFunctionFile") + W("JitDisasmHexDumpFile") }; for (const WCHAR* ignoredVar : s_ignoredVars) From 1e899a596b9e14984fc688f565f8919f7a98c75d Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 17 Nov 2023 12:42:01 -0800 Subject: [PATCH 2/3] Feedback. Removed old hexdmp code as it was not being used. --- src/coreclr/jit/codegencommon.cpp | 100 ++++-------------- src/coreclr/jit/compiler.cpp | 9 -- src/coreclr/jit/compiler.h | 34 +++--- src/coreclr/jit/jitconfigvalues.h | 3 +- src/coreclr/jit/utils.cpp | 13 +-- src/coreclr/jit/utils.h | 2 +- .../superpmi-shim-collector/jithost.cpp | 3 +- 7 files changed, 45 insertions(+), 119 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 23a858182736cd..e0a56103f8438b 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2098,21 +2098,31 @@ void CodeGen::genEmitUnwindDebugGCandEH() #endif // LATE_DISASM #ifdef DEBUG - if ((compiler->opts.disAsm || compiler->verbose) && compiler->opts.disAsmHexDumpFile) + if (JitConfig.JitRawHexCode().contains(compiler->info.compMethodHnd, compiler->info.compClassHnd, + &compiler->info.compMethodInfo->args)) { - FILE* hexDmpf; - errno_t ec = _wfopen_s(&hexDmpf, compiler->opts.disAsmHexDumpFile, W("at")); // NOTE: file append mode - if (ec == 0) - { - assert(hexDmpf); + BYTE* addr = (BYTE*)*codePtr + compiler->GetEmitter()->writeableOffset; - BYTE* addr = (BYTE*)*codePtr + compiler->GetEmitter()->writeableOffset; - for (unsigned int i = 0; i < codeSize; i++) + const WCHAR* rawHexCodeFilePath = JitConfig.JitRawHexCodeFile(); + if (rawHexCodeFilePath) + { + FILE* hexDmpf; + errno_t ec = _wfopen_s(&hexDmpf, rawHexCodeFilePath, W("at")); // NOTE: file append mode + if (ec == 0) { - fprintf(hexDmpf, "%02X", *addr++); + assert(hexDmpf); + hexDump(hexDmpf, addr, codeSize); + fclose(hexDmpf); } + } + else + { + FILE* dmpf = jitstdout(); - fclose(hexDmpf); + fprintf(dmpf, "Generated native code for %s:\n", compiler->info.compFullName); + fprintf(dmpf, "\n"); + hexDump(dmpf, addr, codeSize); + fprintf(dmpf, "\n\n"); } } #endif // DEBUG @@ -2121,74 +2131,8 @@ void CodeGen::genEmitUnwindDebugGCandEH() genReportEH(); -#ifdef JIT32_GCENCODER -#ifdef DEBUG - void* infoPtr = -#endif // DEBUG -#endif - // Create and store the GC info for this method. - genCreateAndStoreGCInfo(codeSize, prologSize, epilogSize DEBUGARG(codePtr)); - -#ifdef DEBUG - FILE* dmpf = jitstdout(); - - compiler->opts.dmpHex = false; - if (!strcmp(compiler->info.compMethodName, "opts.dmpHex = true; - } - } - if (compiler->opts.dmpHex) - { - size_t consSize = GetEmitter()->emitDataSize(); - - fprintf(dmpf, "Generated code for %s:\n", compiler->info.compFullName); - fprintf(dmpf, "\n"); - - if (codeSize) - { - fprintf(dmpf, " Code at %p [%04X bytes]\n", dspPtr(*codePtr), codeSize); - } - if (consSize) - { - fprintf(dmpf, " Const at %p [%04X bytes]\n", dspPtr(consPtr), consSize); - } -#ifdef JIT32_GCENCODER - size_t infoSize = compiler->compInfoBlkSize; - if (infoSize) - fprintf(dmpf, " Info at %p [%04X bytes]\n", dspPtr(infoPtr), infoSize); -#endif // JIT32_GCENCODER - - fprintf(dmpf, "\n"); - - if (codeSize) - { - hexDump(dmpf, "Code", (BYTE*)*codePtr, codeSize); - } - if (consSize) - { - hexDump(dmpf, "Const", (BYTE*)consPtr, consSize); - } -#ifdef JIT32_GCENCODER - if (infoSize) - hexDump(dmpf, "Info", (BYTE*)infoPtr, infoSize); -#endif // JIT32_GCENCODER - - fflush(dmpf); - } - - if (dmpf != jitstdout()) - { - fclose(dmpf); - } - -#endif // DEBUG + // Create and store the GC info for this method. + genCreateAndStoreGCInfo(codeSize, prologSize, epilogSize DEBUGARG(codePtr)); /* Tell the emitter that we're done with this function */ diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 690f0d8b160b4a..fa72c8139b9324 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2835,7 +2835,6 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.dspInstrs = false; opts.dspLines = false; opts.varNames = false; - opts.dmpHex = false; opts.disAsmSpilled = false; opts.disAddr = false; opts.dspCode = false; @@ -2847,8 +2846,6 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.compLongAddress = false; opts.optRepeat = false; - opts.disAsmHexDumpFile = nullptr; - #ifdef LATE_DISASM opts.doLateDisasm = false; #endif // LATE_DISASM @@ -2933,12 +2930,6 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.doLateDisasm = true; #endif // LATE_DISASM - const WCHAR* disAsmHexDumpFile = JitConfig.JitDisasmHexDumpFile(); - if (disAsmHexDumpFile != nullptr) - { - opts.disAsmHexDumpFile = disAsmHexDumpFile; - } - // This one applies to both Ngen/Jit Disasm output: DOTNET_JitDasmWithAddress=1 if (JitConfig.JitDasmWithAddress() != 0) { diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ec50b1b7067e8e..bf68511f1ee268 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9705,24 +9705,22 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool disAlignment; // Display alignment boundaries in disassembly code bool disCodeBytes; // Display instruction code bytes in disassembly code #ifdef DEBUG - bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH - bool dspCode; // Display native code generated - bool dspEHTable; // Display the EH table reported to the VM - bool dspDebugInfo; // Display the Debug info reported to the VM - bool dspInstrs; // Display the IL instructions intermixed with the native code output - bool dspLines; // Display source-code lines intermixed with native code output - bool dmpHex; // Display raw bytes in hex of native code output - bool varNames; // Display variables names in native code output - bool disAsmSpilled; // Display native code when any register spilling occurs - bool disasmWithGC; // Display GC info interleaved with disassembly. - bool disAddr; // Display process address next to each instruction in disassembly code - bool disAsm2; // Display native code after it is generated using external disassembler - bool dspOrder; // Display names of each of the methods that we ngen/jit - bool dspUnwind; // Display the unwind info output - bool compLongAddress; // Force using large pseudo instructions for long address - // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) - bool dspGCtbls; // Display the GC tables - const WCHAR* disAsmHexDumpFile; // Writes the raw bytes in hex of native code to the specified file + bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH + bool dspCode; // Display native code generated + bool dspEHTable; // Display the EH table reported to the VM + bool dspDebugInfo; // Display the Debug info reported to the VM + bool dspInstrs; // Display the IL instructions intermixed with the native code output + bool dspLines; // Display source-code lines intermixed with native code output + bool varNames; // Display variables names in native code output + bool disAsmSpilled; // Display native code when any register spilling occurs + bool disasmWithGC; // Display GC info interleaved with disassembly. + bool disAddr; // Display process address next to each instruction in disassembly code + bool disAsm2; // Display native code after it is generated using external disassembler + bool dspOrder; // Display names of each of the methods that we ngen/jit + bool dspUnwind; // Display the unwind info output + bool compLongAddress; // Force using large pseudo instructions for long address + // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) + bool dspGCtbls; // Display the GC tables #endif // Default numbers used to perform loop alignment. All the numbers are chosen diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 9e1b1470362956..7c0c69e238c2f8 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -677,7 +677,8 @@ CONFIG_STRING(JitFunctionFile, W("JitFunctionFile")) #endif // DEBUG #if defined(DEBUG) -CONFIG_STRING(JitDisasmHexDumpFile, W("JitDisasmHexDumpFile")) +CONFIG_METHODSET(JitRawHexCode, W("JitRawHexCode")) +CONFIG_STRING(JitRawHexCodeFile, W("JitRawHexCodeFile")) #endif // DEBUG #if defined(DEBUG) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 099155e85f0b98..50885fb94da722 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1319,7 +1319,7 @@ int SimpleSprintf_s(_In_reads_(cbBufSize - (pWriteStart - pBufStart)) char* pWri #ifdef DEBUG -void hexDump(FILE* dmpf, const char* name, BYTE* addr, size_t size) +void hexDump(FILE* dmpf, BYTE* addr, size_t size) { if (!size) { @@ -1328,19 +1328,10 @@ void hexDump(FILE* dmpf, const char* name, BYTE* addr, size_t size) assert(addr); - fprintf(dmpf, "Hex dump of %s:\n", name); - for (unsigned i = 0; i < size; i++) { - if ((i % 16) == 0) - { - fprintf(dmpf, "\n %04X: ", i); - } - - fprintf(dmpf, "%02X ", *addr++); + fprintf(dmpf, "%02X", *addr++); } - - fprintf(dmpf, "\n\n"); } #endif // DEBUG diff --git a/src/coreclr/jit/utils.h b/src/coreclr/jit/utils.h index 747daf9d719d46..1eaa16d67ba81e 100644 --- a/src/coreclr/jit/utils.h +++ b/src/coreclr/jit/utils.h @@ -321,7 +321,7 @@ int SimpleSprintf_s(_In_reads_(cbBufSize - (pWriteStart - pBufStart)) char* pWri ...); #ifdef DEBUG -void hexDump(FILE* dmpf, const char* name, BYTE* addr, size_t size); +void hexDump(FILE* dmpf, BYTE* addr, size_t size); #endif // DEBUG /****************************************************************************** diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp index 35610f325f5344..29cfc53e86fc73 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp @@ -86,7 +86,8 @@ bool RecordVariable(const WCHAR* key) W("JitInlinePolicyDumpXml"), W("JitInlineReplayFile"), W("JitFunctionFile") - W("JitDisasmHexDumpFile") + W("JitRawHexCode"), + W("JitRawHexCodeFile") }; for (const WCHAR* ignoredVar : s_ignoredVars) From c01ff8f4daffa35120ff964c86353daed235e05e Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 17 Nov 2023 13:57:22 -0800 Subject: [PATCH 3/3] minor cleanup --- src/coreclr/jit/codegencommon.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index e0a56103f8438b..744462af3d7ab0 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2120,7 +2120,6 @@ void CodeGen::genEmitUnwindDebugGCandEH() FILE* dmpf = jitstdout(); fprintf(dmpf, "Generated native code for %s:\n", compiler->info.compFullName); - fprintf(dmpf, "\n"); hexDump(dmpf, addr, codeSize); fprintf(dmpf, "\n\n"); }