diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 2e90db063fc08d..4ea0cafce0b89d 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -900,7 +900,7 @@ int32_t InterpCompiler::GetLiveEndOffset(int32_t var) } } -uint32_t InterpCompiler::ConvertOffset(int32_t offset) +static uint32_t ConvertOffset(int32_t offset) { // FIXME Once the VM moved the InterpMethod* to code header, we don't need to add a pointer size to the offset return offset * sizeof(int32_t) + sizeof(void*); @@ -1430,8 +1430,8 @@ class InterpGcSlotAllocator assert(slot != ((GcSlotId)-1)); assert(pVar->liveStart); assert(pVar->liveEnd); - uint32_t startOffset = m_compiler->ConvertOffset(m_compiler->GetLiveStartOffset(varIndex)), - endOffset = m_compiler->ConvertOffset(m_compiler->GetLiveEndOffset(varIndex)); + uint32_t startOffset = ConvertOffset(m_compiler->GetLiveStartOffset(varIndex)), + endOffset = ConvertOffset(m_compiler->GetLiveEndOffset(varIndex)); INTERP_DUMP( "Slot %u (%s var #%d offset %u) live [IR_%04x - IR_%04x] [%u - %u]\n", slot, pVar->global ? "global" : "local", @@ -1450,7 +1450,7 @@ class InterpGcSlotAllocator void ReportConservativeRangesToGCEncoder() { - uint32_t maxEndOffset = m_compiler->ConvertOffset(m_compiler->m_methodCodeSize); + uint32_t maxEndOffset = ConvertOffset(m_compiler->m_methodCodeSize); for (uint32_t iSlot = 0; iSlot < m_slotTableSize; iSlot++) { ConservativeRanges* ranges = m_conservativeRanges.Get(iSlot); @@ -1956,8 +1956,9 @@ InterpMethod* InterpCompiler::FinalizeMethodData(void* baseAddressRW, void* base // Construct InterpMethod in the final allocation InterpMethod* pMethodRW = (InterpMethod*)(rwBase + interpMethodOffset); InterpMethod* pMethodRX = (InterpMethod*)(rxBase + interpMethodOffset); - new (pMethodRW) InterpMethod(m_methodHnd, m_ILLocalsOffset, m_totalVarsStackSize, pDataItems, - m_initLocals, m_unmanagedCallersOnly, m_publishSecretStubParam); + new (pMethodRW) InterpMethod(m_methodHnd, m_ILLocalsOffset, m_totalVarsStackSize, pDataItems, + m_initLocals, m_unmanagedCallersOnly, m_publishSecretStubParam, + m_methodCodeSize); // Copy async suspend data and fix up pointers uint32_t currentAsyncOffset = asyncSuspendDataOffset; @@ -11203,21 +11204,27 @@ bool InterpreterRetryData::GetOverrideILMergePointStackType(int32_t ilOffset, ui } } -void InterpCompiler::PrintClassName(CORINFO_CLASS_HANDLE cls) +#ifdef DEBUG +static void DumpClassName(CORINFO_CLASS_HANDLE cls, COMP_HANDLE compHnd) { char className[100]; - m_compHnd->printClassName(cls, className, 100); + compHnd->printClassName(cls, className, 100); printf("%s", className); } -void InterpCompiler::PrintMethodName(CORINFO_METHOD_HANDLE method) +void InterpCompiler::PrintClassName(CORINFO_CLASS_HANDLE cls) +{ + DumpClassName(cls, m_compHnd); +} + +static void DumpMethodName(CORINFO_METHOD_HANDLE method, COMP_HANDLE compHnd) { - CORINFO_CLASS_HANDLE cls = m_compHnd->getMethodClass(method); + CORINFO_CLASS_HANDLE cls = compHnd->getMethodClass(method); CORINFO_SIG_INFO sig; - m_compHnd->getMethodSig(method, &sig, cls); + compHnd->getMethodSig(method, &sig, cls); - TArray methodName = ::PrintMethodName(m_compHnd, cls, method, &sig, + TArray methodName = ::PrintMethodName(compHnd, cls, method, &sig, /* includeAssembly */ false, /* includeClass */ true, /* includeClassInstantiation */ true, @@ -11226,10 +11233,14 @@ void InterpCompiler::PrintMethodName(CORINFO_METHOD_HANDLE method) /* includeReturnType */ false, /* includeThis */ false); - printf(".%s", methodName.GetUnderlyingArray()); } +void InterpCompiler::PrintMethodName(CORINFO_METHOD_HANDLE method) +{ + DumpMethodName(method, m_compHnd); +} + void InterpCompiler::PrintCode() { for (InterpBasicBlock *pBB = m_pEntryBB; pBB != NULL; pBB = pBB->pNextBB) @@ -11352,23 +11363,28 @@ void PrintInterpGenericLookup(InterpGenericLookup* lookup) } } -#ifdef DEBUG -void InterpCompiler::PrintNameInPointerMap(void* ptr) +static void DumpNameInPointerMap(void* ptr, dn_simdhash_ptr_ptr_t* pPointerMap, COMP_HANDLE compHnd) { const char *name; - if (dn_simdhash_ptr_ptr_try_get_value(m_pointerToNameMap.GetValue(), ptr, (void**)&name)) + if (dn_simdhash_ptr_ptr_try_get_value(pPointerMap, ptr, (void**)&name)) { if (name == PointerIsMethodHandle) { - printf("("); - PrintMethodName((CORINFO_METHOD_HANDLE)((size_t)ptr)); - printf(")"); + if (compHnd) + { + printf("("); + DumpMethodName((CORINFO_METHOD_HANDLE)((size_t)ptr), compHnd); + printf(")"); + } } else if (name == PointerIsClassHandle) { - printf("("); - PrintClassName((CORINFO_CLASS_HANDLE)((size_t)ptr)); - printf(")"); + if (compHnd) + { + printf("("); + DumpClassName((CORINFO_CLASS_HANDLE)((size_t)ptr), compHnd); + printf(")"); + } } else if (name == PointerIsStringLiteral) { @@ -11411,25 +11427,26 @@ void InterpCompiler::PrintNameInPointerMap(void* ptr) printf("(%s)", name); } } - return; } -#endif -void InterpCompiler::PrintPointer(void* pointer) +static void DumpPointer(void* pointer, + dn_simdhash_ptr_ptr_t* pPointerMap = nullptr, COMP_HANDLE compHnd = nullptr) { printf("%p ", pointer); -#ifdef DEBUG - PrintNameInPointerMap(pointer); -#endif + if (pPointerMap != nullptr) + { + DumpNameInPointerMap(pointer, pPointerMap, compHnd); + } } -void InterpCompiler::PrintHelperFtn(int32_t _data) +static void DumpHelperFtn(int32_t _data, void** pDataItems, + dn_simdhash_ptr_ptr_t* pPointerMap = nullptr, COMP_HANDLE compHnd = nullptr) { InterpHelperData data{}; memcpy(&data, &_data, sizeof(_data)); - void *helperAddr = GetDataItemAtIndex(data.addressDataItemIndex); - PrintPointer(helperAddr); + void *helperAddr = pDataItems[data.addressDataItemIndex]; + DumpPointer(helperAddr, pPointerMap, compHnd); switch (data.accessType) { case IAT_PVALUE: @@ -11458,7 +11475,7 @@ void PrintLocalIntervals(InterpIntervalMapEntry* pIntervals) printf("]"); } -void InterpCompiler::PrintInterpAsyncSuspendData(InterpAsyncSuspendData* pSuspendInfo) +static void DumpInterpAsyncSuspendData(InterpAsyncSuspendData* pSuspendInfo) { printf(" AsyncSuspendData["); printf("continuationTypeHnd=%p", pSuspendInfo->continuationTypeHnd); @@ -11472,7 +11489,8 @@ void InterpCompiler::PrintInterpAsyncSuspendData(InterpAsyncSuspendData* pSuspen printf("]"); } -void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int32_t *pData, int32_t opcode) +static void DumpInsData(InterpInst *ins, int32_t insOffset, const int32_t *pData, int32_t opcode, void** pDataItems, + dn_simdhash_ptr_ptr_t* pPointerMap = nullptr, COMP_HANDLE compHnd = nullptr) { switch (g_interpOpArgType[opcode]) { case InterpOpNoArgs: @@ -11511,19 +11529,19 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 break; case InterpOpLdPtr: { - PrintPointer((void*)GetDataItemAtIndex(pData[0])); + DumpPointer(pDataItems[pData[0]], pPointerMap, compHnd); break; } case InterpOpGenericHelperFtn: { - PrintHelperFtn(pData[0]); - InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)GetAddrOfDataItemAtIndex(pData[1]); + DumpHelperFtn(pData[0], pDataItems, pPointerMap, compHnd); + InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)&pDataItems[pData[1]]; PrintInterpGenericLookup(pGenericLookup); break; } case InterpOpGenericLookup: { - InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)GetAddrOfDataItemAtIndex(pData[0]); + InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)&pDataItems[pData[0]]; PrintInterpGenericLookup(pGenericLookup); } break; @@ -11546,62 +11564,68 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } case InterpOpMethodHandle: { - CORINFO_METHOD_HANDLE mh = (CORINFO_METHOD_HANDLE)((size_t)m_dataItems.Get(*pData)); + CORINFO_METHOD_HANDLE mh = (CORINFO_METHOD_HANDLE)((size_t)pDataItems[*pData]); printf(" "); - PrintMethodName(mh); + if (compHnd) + DumpMethodName(mh, compHnd); + else + DumpPointer(pDataItems[*pData]); break; } case InterpOpClassHandle: { - CORINFO_CLASS_HANDLE ch = (CORINFO_CLASS_HANDLE)((size_t)m_dataItems.Get(*pData)); + CORINFO_CLASS_HANDLE ch = (CORINFO_CLASS_HANDLE)((size_t)pDataItems[*pData]); printf(" "); - PrintClassName(ch); + if (compHnd) + DumpClassName(ch, compHnd); + else + DumpPointer(pDataItems[*pData]); break; } case InterpOpHelperFtnNoArgs: { - PrintHelperFtn(pData[0]); + DumpHelperFtn(pData[0], pDataItems, pPointerMap, compHnd); break; } case InterpOpHelperFtn: { - PrintHelperFtn(pData[0]); + DumpHelperFtn(pData[0], pDataItems, pPointerMap, compHnd); if (GetDataLen(opcode) > 1) { printf(", "); - PrintPointer((void*)GetDataItemAtIndex(pData[1])); + DumpPointer(pDataItems[pData[1]], pPointerMap, compHnd); } break; } case InterpOpPointerHelperFtn: { - PrintPointer((void*)GetDataItemAtIndex(pData[0])); + DumpPointer(pDataItems[pData[0]], pPointerMap, compHnd); printf(", "); - PrintHelperFtn(pData[1]); + DumpHelperFtn(pData[1], pDataItems, pPointerMap, compHnd); break; } case InterpOpPointerInt: { - PrintPointer((void*)GetDataItemAtIndex(pData[0])); + DumpPointer(pDataItems[pData[0]], pPointerMap, compHnd); printf(", %d", pData[1]); break; } case InterpOpGenericLookupInt: { - InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)GetAddrOfDataItemAtIndex(pData[0]); + InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)&pDataItems[pData[0]]; PrintInterpGenericLookup(pGenericLookup); printf(", %d", pData[1]); break; } case InterpOpHandleContinuation: { - PrintInterpAsyncSuspendData((InterpAsyncSuspendData*)GetDataItemAtIndex(pData[0])); + DumpInterpAsyncSuspendData((InterpAsyncSuspendData*)pDataItems[pData[0]]); printf(", "); - PrintHelperFtn(pData[1]); + DumpHelperFtn(pData[1], pDataItems, pPointerMap, compHnd); break; } case InterpOpHandleContinuationPt2: { - PrintInterpAsyncSuspendData((InterpAsyncSuspendData*)GetDataItemAtIndex(pData[0])); + DumpInterpAsyncSuspendData((InterpAsyncSuspendData*)pDataItems[pData[0]]); break; } default: @@ -11610,21 +11634,14 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } } -void InterpCompiler::PrintCompiledCode() +void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int32_t *pData, int32_t opcode) { - const int32_t *ip = m_pMethodCode; - const int32_t *end = m_pMethodCode + m_methodCodeSize; - - while (ip < end) - { - PrintCompiledIns(ip, m_pMethodCode); - ip = InterpNextOp(ip); - } - - printf("End of method: %04x: IR_%04x\n", (int32_t)ConvertOffset((int32_t)(ip - m_pMethodCode)), (int32_t)(ip - m_pMethodCode)); + DumpInsData(ins, insOffset, pData, opcode, m_dataItems.GetUnderlyingArray(), + m_pointerToNameMap.GetValue(), m_compHnd); } -void InterpCompiler::PrintCompiledIns(const int32_t *ip, const int32_t *start) +static void DumpCompiledIns(const int32_t *ip, const int32_t *start, void** pDataItems, + dn_simdhash_ptr_ptr_t* pPointerMap = nullptr, COMP_HANDLE compHnd = nullptr) { int32_t opcode = *ip; int32_t insOffset = (int32_t)(ip - start); @@ -11648,10 +11665,41 @@ void InterpCompiler::PrintCompiledIns(const int32_t *ip, const int32_t *start) printf(" nil],"); } - PrintInsData(NULL, insOffset, ip, opcode); + DumpInsData(NULL, insOffset, ip, opcode, pDataItems, pPointerMap, compHnd); printf("\n"); } +static void DumpCompiledCode(const int32_t *code, int32_t codeSizeInSlots, void** pDataItems, + dn_simdhash_ptr_ptr_t* pPointerMap = nullptr, COMP_HANDLE compHnd = nullptr) +{ + const int32_t *ip = code; + const int32_t *end = code + codeSizeInSlots; + + while (ip < end) + { + DumpCompiledIns(ip, code, pDataItems, pPointerMap, compHnd); + ip = InterpNextOp(ip); + } + + printf("End of method: %04x: IR_%04x\n", (int32_t)ConvertOffset((int32_t)(ip - code)), (int32_t)(ip - code)); +} + +void InterpCompiler::PrintCompiledCode() +{ + DumpCompiledCode(m_pMethodCode, m_methodCodeSize, m_dataItems.GetUnderlyingArray(), + m_pointerToNameMap.GetValue(), m_compHnd); +} + +extern "C" void InterpDumpIR(const InterpByteCodeStart *startIp) +{ + InterpMethod *pMethod = startIp->Method; + const int32_t *code = startIp->GetByteCodes(); + + printf("Dumping interpreter IR at %p (method %p)\n", startIp, pMethod->methodHnd); + DumpCompiledCode(code, pMethod->codeSize, pMethod->pDataItems); +} +#endif + extern "C" void assertAbort(const char* why, const char* file, unsigned line) { if (t_InterpJitInfoTls) { diff --git a/src/coreclr/interpreter/compiler.h b/src/coreclr/interpreter/compiler.h index 33ef656ffe5f5a..485c55503ea977 100644 --- a/src/coreclr/interpreter/compiler.h +++ b/src/coreclr/interpreter/compiler.h @@ -211,6 +211,12 @@ class InterpDumpScope #define INTERP_DUMP(...) #endif // DEBUG +#ifdef DEBUG +static const char* const PointerIsClassHandle = (const char*)0x1; +static const char* const PointerIsMethodHandle = (const char*)0x2; +static const char* const PointerIsStringLiteral = (const char*)0x3; +#endif // DEBUG + struct InterpInst; struct InterpBasicBlock; @@ -1038,7 +1044,6 @@ class InterpCompiler void AllocOffsets(); int32_t ComputeCodeSize(); - uint32_t ConvertOffset(int32_t offset); void EmitCode(); int32_t* EmitBBCode(int32_t *ip, InterpBasicBlock *bb, TArray *relocs); int32_t* EmitCodeIns(int32_t *ip, InterpInst *pIns, TArray *relocs); @@ -1054,26 +1059,17 @@ class InterpCompiler uint8_t* getILCode(CORINFO_METHOD_INFO* methodInfo); unsigned int getILCodeSize(CORINFO_METHOD_INFO* methodInfo); - // Debug +#ifdef DEBUG void PrintClassName(CORINFO_CLASS_HANDLE cls); void PrintMethodName(CORINFO_METHOD_HANDLE method); void PrintCode(); void PrintBBCode(InterpBasicBlock *pBB); void PrintIns(InterpInst *ins); - void PrintPointer(void* pointer); - void PrintHelperFtn(int32_t _data); void PrintInsData(InterpInst *ins, int32_t offset, const int32_t *pData, int32_t opcode); void PrintCompiledCode(); - void PrintCompiledIns(const int32_t *ip, const int32_t *start); - void PrintInterpAsyncSuspendData(InterpAsyncSuspendData* pSuspendInfo); -#ifdef DEBUG InterpDumpScope m_dumpScope; TArray m_methodName; - const char* PointerIsClassHandle = (const char*)0x1; - const char* PointerIsMethodHandle = (const char*)0x2; - const char* PointerIsStringLiteral = (const char*)0x3; - dn_simdhash_ptr_ptr_holder m_pointerToNameMap; bool PointerInNameMap(void* ptr) { @@ -1083,7 +1079,6 @@ class InterpCompiler { checkNoError(dn_simdhash_ptr_ptr_try_add(m_pointerToNameMap.GetValue(), ptr, (void*)name)); } - void PrintNameInPointerMap(void* ptr); #endif // DEBUG public: diff --git a/src/coreclr/interpreter/inc/interpretershared.h b/src/coreclr/interpreter/inc/interpretershared.h index 35b7c23f8ac9df..c696140b97b073 100644 --- a/src/coreclr/interpreter/inc/interpretershared.h +++ b/src/coreclr/interpreter/inc/interpretershared.h @@ -46,11 +46,13 @@ struct InterpMethod bool initLocals; bool unmanagedCallersOnly; bool publishSecretStubParam; + int32_t codeSize; // size in int32_t slots #ifdef INTERPRETER_COMPILER_INTERNAL InterpMethod( CORINFO_METHOD_HANDLE methodHnd, int32_t argsSize, int32_t allocaSize, - void** pDataItems, bool initLocals, bool unmanagedCallersOnly, bool publishSecretStubParam + void** pDataItems, bool initLocals, bool unmanagedCallersOnly, + bool publishSecretStubParam, int32_t codeSize ) { #if DEBUG @@ -63,6 +65,7 @@ struct InterpMethod this->initLocals = initLocals; this->unmanagedCallersOnly = unmanagedCallersOnly; this->publishSecretStubParam = publishSecretStubParam; + this->codeSize = codeSize; pCallStub = NULL; } #endif