From d2760d6c98be2ed362a766843781abb54436f120 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 22 Jan 2025 00:00:07 +0100 Subject: [PATCH 1/5] Initial interpreter wire-in This change adds initial support for a new interpreter to coreclr. The interpreter will have a compilation phase that generates an IR byte code and will behave as a JIT. This change allows the runtime to understand that the generated code is an interpreter IR and when runtime attempts to execute such a method, it calls into the ExecuteInterpretedMethod. This will call into the interpreter execution code once the actual interpreter is merged in. The change uses the StubPrecode and FixupPrecode as a mean to call the InterpreterStub with a special register loaded with a pointer to the IR byte code of the methods and TransitionFrame to get the arguments from. So instead of MethodDesc, the stub data holds the IR address and instead of the usual generated code target, it holds the InterpreterStub. There is a small twist for FixupPrecode. This precode has two parts ensuring that we load the MethodDesc into the special register only at the first call when we need to know what method we are going to compile. In follow up calls, it invokes the target directly without loading that register. For interpreter, it is always kept in the state of going through the register loading path so that the interpreter execution knows what to run. The plan is to use AltJit mechanism to load the interpreter during its development. That allows us to interpret only a subset of the methods and fall back to JIT for the ones we cannot interpret yet. --- src/coreclr/clrdefinitions.cmake | 3 ++ src/coreclr/clrfeatures.cmake | 8 ++++ src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/utilcode.h | 3 ++ src/coreclr/vm/amd64/AsmHelpers.asm | 16 ++++++++ src/coreclr/vm/amd64/asmhelpers.S | 17 ++++++++ src/coreclr/vm/arm64/asmhelpers.S | 13 +++++++ src/coreclr/vm/arm64/asmhelpers.asm | 13 +++++++ src/coreclr/vm/jitinterface.cpp | 11 +++++- src/coreclr/vm/method.cpp | 2 +- src/coreclr/vm/method.hpp | 14 +++++++ src/coreclr/vm/precode.cpp | 60 ++++++++++++++++++++++++++--- src/coreclr/vm/precode.h | 46 +++++++++++++++++++--- src/coreclr/vm/prestub.cpp | 20 ++++++++++ 14 files changed, 214 insertions(+), 14 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index e08ffe9dd267dc..78efad1f4d7c7f 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -125,6 +125,9 @@ endif(NOT CLR_CMAKE_TARGET_NETBSD) if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_definitions(-DFEATURE_INTEROP_DEBUGGING) endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) +if(FEATURE_INTERPRETER) + add_compile_definitions(FEATURE_INTERPRETER) +endif(FEATURE_INTERPRETER) if (CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_ISYM_READER) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 2bf7216af1b4db..27f416cc711090 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -16,6 +16,14 @@ if(NOT DEFINED FEATURE_DBGIPC) endif() endif(NOT DEFINED FEATURE_DBGIPC) +if(NOT DEFINED FEATURE_INTERPRETER) + if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) + set(FEATURE_INTERPRETER 1) + else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) + set(FEATURE_INTERPRETER 0) + endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) +endif(NOT DEFINED FEATURE_INTERPRETER) + if(NOT DEFINED FEATURE_STANDALONE_GC) set(FEATURE_STANDALONE_GC 1) endif(NOT DEFINED FEATURE_STANDALONE_GC) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 9d01304c6639d8..2128b8cabe7c32 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -786,7 +786,7 @@ enum CorInfoFlag enum CorInfoMethodRuntimeFlags { CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining - // unused = 0x00000002, + CORINFO_FLG_INTERPRETER = 0x00000002, // The method was compiled by the interpreter // unused = 0x00000004, CORINFO_FLG_SWITCHED_TO_MIN_OPT = 0x00000008, // The JIT decided to switch to MinOpt for this method, when it was not requested CORINFO_FLG_SWITCHED_TO_OPTIMIZED = 0x00000010, // The JIT decided to switch to tier 1 for this method, when a different tier was requested diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index 4f801143879631..cc729d5fb0ca11 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -3969,4 +3969,7 @@ struct SpinConstants extern SpinConstants g_SpinConstants; +// This value is or-ed to the code address as a marker to indicate it is an address of the interpreter IR bytecode +static const size_t InterpretedCodeAddressFlag = 2; + #endif // __UtilCode_h__ diff --git a/src/coreclr/vm/amd64/AsmHelpers.asm b/src/coreclr/vm/amd64/AsmHelpers.asm index 95714fd0757321..e303edd4d6b9b2 100644 --- a/src/coreclr/vm/amd64/AsmHelpers.asm +++ b/src/coreclr/vm/amd64/AsmHelpers.asm @@ -11,6 +11,7 @@ extern ProfileLeave:proc extern ProfileTailcall:proc extern OnHijackWorker:proc extern JIT_RareDisableHelperWorker:proc +extern ExecuteInterpretedMethod:proc extern g_pPollGC:QWORD extern g_TrapReturningThreads:DWORD @@ -458,4 +459,19 @@ JIT_PollGCRarePath: TAILJMP_RAX LEAF_END JIT_PollGC, _TEXT +NESTED_ENTRY InterpreterStub, _TEXT + + PROLOG_WITH_TRANSITION_BLOCK + + ; + ; call ExecuteInterpretedMethod + ; + lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock* + mov rdx, METHODDESC_REGISTER + call ExecuteInterpretedMethod + + EPILOG_WITH_TRANSITION_BLOCK_RETURN + +NESTED_END InterpreterStub, _TEXT + end \ No newline at end of file diff --git a/src/coreclr/vm/amd64/asmhelpers.S b/src/coreclr/vm/amd64/asmhelpers.S index 6bce2d2f2d3436..4e71db6dfc6904 100644 --- a/src/coreclr/vm/amd64/asmhelpers.S +++ b/src/coreclr/vm/amd64/asmhelpers.S @@ -330,3 +330,20 @@ LOCAL_LABEL(JIT_PollGCRarePath): mov rax, [rax] jmp rax LEAF_END JIT_PollGC, _TEXT + +NESTED_ENTRY InterpreterStub, _TEXT, NoHandler + + PROLOG_WITH_TRANSITION_BLOCK 8, 0, 0, 0, 0 + mov [rsp], rax // Return buffer in Swift calling convention + + ; + ; call ExecuteInterpretedMethod + ; + lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock* + mov rsi, METHODDESC_REGISTER + call C_FUNC(ExecuteInterpretedMethod) + + mov rax, [rsp] + EPILOG_WITH_TRANSITION_BLOCK_RETURN + +NESTED_END InterpreterStub, _TEXT diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index d40d210dfb03ad..7a00f7a1d35960 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -817,3 +817,16 @@ LOCAL_LABEL(JIT_PollGCRarePath): ldr x9, [x9] br x9 LEAF_END JIT_PollGC, _TEXT + +NESTED_ENTRY InterpreterStub, _TEXT, NoHandler + + PROLOG_WITH_TRANSITION_BLOCK + + add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock + mov x1, METHODDESC_REGISTER // pMethodDesc + + bl C_FUNC(ExecuteInterpretedMethod) + + EPILOG_WITH_TRANSITION_BLOCK_RETURN + +NESTED_END InterpreterStub, _TEXT diff --git a/src/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index e240919a7395f0..ccb45b374dd2d8 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -21,6 +21,7 @@ #endif IMPORT HijackHandler IMPORT ThrowControlForThread + IMPORT ExecuteInterpretedMethod #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP IMPORT g_sw_ww_table @@ -1193,6 +1194,18 @@ JIT_PollGCRarePath br x9 LEAF_END + NESTED_ENTRY InterpreterStub + + PROLOG_WITH_TRANSITION_BLOCK + + add x0, sp, #__PWTB_TransitionBlock ; pTransitionBlock + mov x1, METHODDESC_REGISTER ; pMethodDesc + + bl ExecuteInterpretedMethod + + EPILOG_WITH_TRANSITION_BLOCK_RETURN + + NESTED_END ; Must be at very end of file END diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 3354a7ec0f2ab4..f7e4ee0b9c0ed3 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6611,7 +6611,7 @@ void CEEInfo::setMethodAttribs ( ftn->SetNotInline(true); } - if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT)) + if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT | CORINFO_FLG_INTERPRETER)) { PrepareCodeConfig *config = GetThread()->GetCurrentPrepareCodeConfig(); if (config != nullptr) @@ -6621,6 +6621,10 @@ void CEEInfo::setMethodAttribs ( _ASSERTE(!ftn->IsJitOptimizationDisabled()); config->SetJitSwitchedToMinOpt(); } + else if (attribs & CORINFO_FLG_INTERPRETER) + { + config->SetIsInterpreterCode(); + } #ifdef FEATURE_TIERED_COMPILATION else if (attribs & CORINFO_FLG_SWITCHED_TO_OPTIMIZED) { @@ -13139,6 +13143,11 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, ret |= THUMB_CODE; #endif + if (config->IsInterpreterCode()) + { + ret |= InterpretedCodeAddressFlag; + } + // We are done break; } diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index cd684755299a48..0b9b730de07058 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -3044,7 +3044,7 @@ void MethodDesc::TrySetInitialCodeEntryPointForVersionableMethod( else { _ASSERTE(IsVersionableWithPrecode()); - GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */); + GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */, (entryPoint & InterpretedCodeAddressFlag) /* fInterpreter */); } } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 5d541b84fbb493..f77b3f3b118120 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -2060,6 +2060,18 @@ class PrepareCodeConfig m_jitSwitchedToMinOpt = true; } + void SetIsInterpreterCode() + { + LIMITED_METHOD_CONTRACT; + m_isInterpreterCode = true; + } + + bool IsInterpreterCode() const + { + LIMITED_METHOD_CONTRACT; + return m_isInterpreterCode; + } + #ifdef FEATURE_TIERED_COMPILATION public: bool JitSwitchedToOptimized() const @@ -2128,6 +2140,8 @@ class PrepareCodeConfig #ifdef FEATURE_TIERED_COMPILATION bool m_jitSwitchedToOptimized; // when a different tier was requested #endif + bool m_isInterpreterCode; // The generated code is interpreter IR + PrepareCodeConfig *m_nextInSameThread; }; diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index e793425d2bec50..7fd83de38a656b 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -182,6 +182,55 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr) return 0; } +#ifdef FEATURE_INTERPRETER +static TADDR GetMethodDescFromPrecodeData(TADDR methodDesc) +{ + LIMITED_METHOD_CONTRACT; + if ((methodDesc & InterpretedCodeAddressFlag) == 0) + { + return methodDesc; + } + + PTR_CodeHeader pCodeHeader = PTR_CodeHeader((methodDesc & ~(TADDR)1) - sizeof(CodeHeader)); + return dac_cast(pCodeHeader->GetMethodDesc()); +} + +static PCODE GetTargetFromPrecodeData(TADDR methodDesc, PCODE target) +{ + LIMITED_METHOD_CONTRACT; + if ((methodDesc & InterpretedCodeAddressFlag) == 0) + { + return target; + } + + return dac_cast(methodDesc); +} + +TADDR FixupPrecode::GetMethodDesc() +{ + LIMITED_METHOD_CONTRACT; + return GetMethodDescFromPrecodeData(dac_cast(GetData()->MethodDesc)); +} + +PCODE FixupPrecode::GetTarget() +{ + LIMITED_METHOD_DAC_CONTRACT; + return GetTargetFromPrecodeData(dac_cast(GetData()->MethodDesc), GetData()->Target); +} + +TADDR StubPrecode::GetMethodDesc() +{ + LIMITED_METHOD_CONTRACT; + return GetMethodDescFromPrecodeData(dac_cast(GetData()->MethodDesc)); +} + +PCODE StubPrecode::GetTarget() +{ + LIMITED_METHOD_DAC_CONTRACT; + return GetTargetFromPrecodeData(dac_cast(GetData()->MethodDesc), GetData()->Target); +} +#endif // FEATURE_INTERPRETER + #ifndef DACCESS_COMPILE Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, @@ -278,7 +327,7 @@ void Precode::ResetTargetInterlocked() // interlocked operation above (see ClrFlushInstructionCache()) } -BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) +BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub, BOOL fInterpreter) { WRAPPER_NO_CONTRACT; _ASSERTE(!IsPointingToPrestub(target)); @@ -293,17 +342,18 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) switch (precodeType) { case PRECODE_STUB: - ret = AsStubPrecode()->SetTargetInterlocked(target, expected); + ret = AsStubPrecode()->SetTargetInterlocked(target, expected, fInterpreter); break; #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: - ret = AsFixupPrecode()->SetTargetInterlocked(target, expected); + ret = AsFixupPrecode()->SetTargetInterlocked(target, expected, fInterpreter); break; #endif // HAS_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: + _ASSERTE(!fInterpreter); ret = AsThisPtrRetBufPrecode()->SetTargetInterlocked(target, expected); ClrFlushInstructionCache(this, sizeof(ThisPtrRetBufPrecode), /* hasCodeExecutedBefore */ true); break; @@ -384,7 +434,7 @@ void StubPrecode::Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator pStubData->Target = target; } - pStubData->MethodDesc = pMD; + pStubData->MethodDesc = (TADDR)pMD; pStubData->Type = type; } @@ -501,7 +551,7 @@ void FixupPrecode::Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocat _ASSERTE(pPrecodeRX == this); FixupPrecodeData *pData = GetData(); - pData->MethodDesc = pMD; + pData->MethodDesc = (TADDR)pMD; _ASSERTE(GetMethodDesc() == (TADDR)pMD); diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index 894a708e195f6b..f266cd6f4d1138 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -76,7 +76,7 @@ struct InvalidPrecode struct StubPrecodeData { - PTR_MethodDesc MethodDesc; + TADDR MethodDesc; // MethodDesc pointer or interpreted code address or-ed with the InterpretedCodeAddressFlag PCODE Target; BYTE Type; }; @@ -88,6 +88,10 @@ extern "C" void StubPrecodeCode(); extern "C" void StubPrecodeCode_End(); #endif +#ifdef FEATURE_INTERPRETER +extern "C" void InterpreterStub(); +#endif + // Regular precode struct StubPrecode { @@ -129,18 +133,26 @@ struct StubPrecode } TADDR GetMethodDesc() +#ifdef FEATURE_INTERPRETER + ; +#else { LIMITED_METHOD_DAC_CONTRACT; return dac_cast(GetData()->MethodDesc); } +#endif PCODE GetTarget() +#ifdef FEATURE_INTERPRETER + ; +#else { LIMITED_METHOD_DAC_CONTRACT; return GetData()->Target; } +#endif BYTE GetType() { @@ -163,7 +175,7 @@ struct StubPrecode InterlockedExchangeT(&pData->Target, GetPreStubEntryPoint()); } - BOOL SetTargetInterlocked(TADDR target, TADDR expected) + BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter) { CONTRACTL { @@ -172,6 +184,12 @@ struct StubPrecode } CONTRACTL_END; +#ifdef FEATURE_INTERPRETER + if (fInterpreter) + { + target = (PCODE)InterpreterStub; + } +#endif StubPrecodeData *pData = GetData(); return InterlockedCompareExchangeT(&pData->Target, (PCODE)target, (PCODE)expected) == expected; } @@ -210,7 +228,7 @@ typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; struct FixupPrecodeData { PCODE Target; - class MethodDesc *MethodDesc; + TADDR MethodDesc; // MethodDesc pointer or interpreted code address or-ed with the InterpretedCodeAddressFlag PCODE PrecodeFixupThunk; }; @@ -271,16 +289,23 @@ struct FixupPrecode } TADDR GetMethodDesc() +#ifdef FEATURE_INTERPRETER + ; +#else { - LIMITED_METHOD_CONTRACT; return (TADDR)GetData()->MethodDesc; } +#endif PCODE GetTarget() +#ifdef FEATURE_INTERPRETER + ; +#else { LIMITED_METHOD_DAC_CONTRACT; return GetData()->Target; } +#endif PCODE *GetTargetSlot() { @@ -306,7 +331,7 @@ struct FixupPrecode InterlockedExchangeT(&GetData()->Target, target); } - BOOL SetTargetInterlocked(TADDR target, TADDR expected) + BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter) { CONTRACTL { @@ -315,6 +340,15 @@ struct FixupPrecode } CONTRACTL_END; +#ifdef FEATURE_INTERPRETER + if (fInterpreter) + { + _ASSERTE(IS_ALIGNED(&GetData()->PrecodeFixupThunk, sizeof(SIZE_T))); + _ASSERTE((PCODE)GetData()->Target == ((PCODE)this + FixupCodeOffset)); + PCODE oldTarget = (PCODE)GetData()->PrecodeFixupThunk; + return InterlockedCompareExchangeT(&GetData()->PrecodeFixupThunk, (PCODE)InterpreterStub, (PCODE)oldTarget) == (PCODE)oldTarget; + } +#endif PCODE oldTarget = (PCODE)GetData()->Target; if (oldTarget != ((PCODE)this + FixupCodeOffset)) { @@ -538,7 +572,7 @@ class Precode { #ifndef DACCESS_COMPILE void ResetTargetInterlocked(); - BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE); + BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE, BOOL fInterpreter = FALSE); // Reset precode to point to prestub void Reset(); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index b78092f7156336..eaaa074d0a26b3 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -426,6 +426,10 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) LOG((LF_CLASSLOADER, LL_INFO1000000, " In PrepareILBasedCode, calling JitCompileCode\n")); pCode = JitCompileCode(pConfig); + if (pConfig->IsInterpreterCode()) + { + pCode |= InterpretedCodeAddressFlag; + } } else { @@ -1830,6 +1834,7 @@ PrepareCodeConfig::PrepareCodeConfig(NativeCodeVersion codeVersion, BOOL needsMu #ifdef FEATURE_TIERED_COMPILATION m_jitSwitchedToOptimized(false), #endif + m_isInterpreterCode(false), m_nextInSameThread(nullptr) {} @@ -2683,6 +2688,21 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method return pbRetVal; } +#ifdef FEATURE_INTERPRETER +extern "C" void STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr) +{ + byteCodeAddr &= ~InterpretedCodeAddressFlag; + CodeHeader* pCodeHeader = EEJitManager::GetCodeHeaderFromStartAddress(byteCodeAddr); + + EEJitManager *pManager = ExecutionManager::GetEEJitManager(); + MethodDesc *pMD = pCodeHeader->GetMethodDesc(); + + // TODO-Interp: call the interpreter method execution entry point + // Argument registers are in the TransitionBlock + // The stack arguments are right after the pTransitionBlock +} +#endif // FEATURE_INTERPRETER + #ifdef _DEBUG // // These are two functions for testing purposes only, in debug builds only. They can be used by setting From d7c56e7d3a48d179fc14c7f63c6d2e4c7fae0f3e Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 5 Feb 2025 22:01:33 +0100 Subject: [PATCH 2/5] Fix incorrect lookup for CodeHeader Found by PR feedback, instead of InterpretedCodeAddressFlag, it was using 1. --- src/coreclr/vm/precode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 7fd83de38a656b..602b01597a4e71 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -191,7 +191,7 @@ static TADDR GetMethodDescFromPrecodeData(TADDR methodDesc) return methodDesc; } - PTR_CodeHeader pCodeHeader = PTR_CodeHeader((methodDesc & ~(TADDR)1) - sizeof(CodeHeader)); + PTR_CodeHeader pCodeHeader = PTR_CodeHeader(EEJitManager::GetCodeHeaderFromStartAddress(methodDesc & ~InterpretedCodeAddressFlag)); return dac_cast(pCodeHeader->GetMethodDesc()); } From bd9f36b176ad159ffee192306991641b1a7519f4 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 6 Feb 2025 15:04:46 +0100 Subject: [PATCH 3/5] Add new precode type for interpreter --- src/coreclr/inc/utilcode.h | 3 -- src/coreclr/vm/jitinterface.cpp | 5 --- src/coreclr/vm/method.cpp | 2 +- src/coreclr/vm/precode.cpp | 78 ++++++++++++--------------------- src/coreclr/vm/precode.h | 76 +++++++++++++++++--------------- src/coreclr/vm/prestub.cpp | 8 +++- 6 files changed, 75 insertions(+), 97 deletions(-) diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index cc729d5fb0ca11..4f801143879631 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -3969,7 +3969,4 @@ struct SpinConstants extern SpinConstants g_SpinConstants; -// This value is or-ed to the code address as a marker to indicate it is an address of the interpreter IR bytecode -static const size_t InterpretedCodeAddressFlag = 2; - #endif // __UtilCode_h__ diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f7e4ee0b9c0ed3..b4f0c28072a4e7 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -13143,11 +13143,6 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, ret |= THUMB_CODE; #endif - if (config->IsInterpreterCode()) - { - ret |= InterpretedCodeAddressFlag; - } - // We are done break; } diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 0b9b730de07058..cd684755299a48 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -3044,7 +3044,7 @@ void MethodDesc::TrySetInitialCodeEntryPointForVersionableMethod( else { _ASSERTE(IsVersionableWithPrecode()); - GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */, (entryPoint & InterpretedCodeAddressFlag) /* fInterpreter */); + GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */); } } diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 602b01597a4e71..8b5c52de3b078a 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -182,56 +182,25 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr) return 0; } -#ifdef FEATURE_INTERPRETER -static TADDR GetMethodDescFromPrecodeData(TADDR methodDesc) -{ - LIMITED_METHOD_CONTRACT; - if ((methodDesc & InterpretedCodeAddressFlag) == 0) - { - return methodDesc; - } - - PTR_CodeHeader pCodeHeader = PTR_CodeHeader(EEJitManager::GetCodeHeaderFromStartAddress(methodDesc & ~InterpretedCodeAddressFlag)); - return dac_cast(pCodeHeader->GetMethodDesc()); -} +#ifndef DACCESS_COMPILE -static PCODE GetTargetFromPrecodeData(TADDR methodDesc, PCODE target) +InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, + LoaderAllocator * pLoaderAllocator, + AllocMemTracker * pamTracker) { - LIMITED_METHOD_CONTRACT; - if ((methodDesc & InterpretedCodeAddressFlag) == 0) + CONTRACTL { - return target; + THROWS; + GC_NOTRIGGER; + MODE_ANY; } + CONTRACTL_END; - return dac_cast(methodDesc); -} - -TADDR FixupPrecode::GetMethodDesc() -{ - LIMITED_METHOD_CONTRACT; - return GetMethodDescFromPrecodeData(dac_cast(GetData()->MethodDesc)); -} - -PCODE FixupPrecode::GetTarget() -{ - LIMITED_METHOD_DAC_CONTRACT; - return GetTargetFromPrecodeData(dac_cast(GetData()->MethodDesc), GetData()->Target); -} - -TADDR StubPrecode::GetMethodDesc() -{ - LIMITED_METHOD_CONTRACT; - return GetMethodDescFromPrecodeData(dac_cast(GetData()->MethodDesc)); -} - -PCODE StubPrecode::GetTarget() -{ - LIMITED_METHOD_DAC_CONTRACT; - return GetTargetFromPrecodeData(dac_cast(GetData()->MethodDesc), GetData()->Target); + SIZE_T size = sizeof(InterpreterPrecode); + InterpreterPrecode* pPrecode = (InterpreterPrecode*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocAlignedMem(size, 1)); + pPrecode->Init(pPrecode, byteCode); + return pPrecode; } -#endif // FEATURE_INTERPRETER - -#ifndef DACCESS_COMPILE Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator * pLoaderAllocator, @@ -327,7 +296,7 @@ void Precode::ResetTargetInterlocked() // interlocked operation above (see ClrFlushInstructionCache()) } -BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub, BOOL fInterpreter) +BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) { WRAPPER_NO_CONTRACT; _ASSERTE(!IsPointingToPrestub(target)); @@ -342,18 +311,17 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub, switch (precodeType) { case PRECODE_STUB: - ret = AsStubPrecode()->SetTargetInterlocked(target, expected, fInterpreter); + ret = AsStubPrecode()->SetTargetInterlocked(target, expected); break; #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: - ret = AsFixupPrecode()->SetTargetInterlocked(target, expected, fInterpreter); + ret = AsFixupPrecode()->SetTargetInterlocked(target, expected); break; #endif // HAS_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: - _ASSERTE(!fInterpreter); ret = AsThisPtrRetBufPrecode()->SetTargetInterlocked(target, expected); ClrFlushInstructionCache(this, sizeof(ThisPtrRetBufPrecode), /* hasCodeExecutedBefore */ true); break; @@ -434,7 +402,7 @@ void StubPrecode::Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator pStubData->Target = target; } - pStubData->MethodDesc = (TADDR)pMD; + pStubData->MethodDesc = pMD; pStubData->Type = type; } @@ -533,6 +501,16 @@ BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr) #endif // TARGET_X86 } +void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr) +{ + WRAPPER_NO_CONTRACT; + InterpreterPrecodeData *pStubData = GetData(); + + pStubData->Target = (PCODE)InterpreterStub; + pStubData->ByteCodeAddr = byteCodeAddr; + pStubData->Type = InterpreterPrecode::Type; +} + #ifdef HAS_NDIRECT_IMPORT_PRECODE void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) @@ -551,7 +529,7 @@ void FixupPrecode::Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocat _ASSERTE(pPrecodeRX == this); FixupPrecodeData *pData = GetData(); - pData->MethodDesc = (TADDR)pMD; + pData->MethodDesc = pMD; _ASSERTE(GetMethodDesc() == (TADDR)pMD); diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index f266cd6f4d1138..e2772cf5d664df 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -76,7 +76,7 @@ struct InvalidPrecode struct StubPrecodeData { - TADDR MethodDesc; // MethodDesc pointer or interpreted code address or-ed with the InterpretedCodeAddressFlag + PTR_MethodDesc MethodDesc; PCODE Target; BYTE Type; }; @@ -133,26 +133,18 @@ struct StubPrecode } TADDR GetMethodDesc() -#ifdef FEATURE_INTERPRETER - ; -#else { LIMITED_METHOD_DAC_CONTRACT; return dac_cast(GetData()->MethodDesc); } -#endif PCODE GetTarget() -#ifdef FEATURE_INTERPRETER - ; -#else { LIMITED_METHOD_DAC_CONTRACT; return GetData()->Target; } -#endif BYTE GetType() { @@ -175,7 +167,7 @@ struct StubPrecode InterlockedExchangeT(&pData->Target, GetPreStubEntryPoint()); } - BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter) + BOOL SetTargetInterlocked(TADDR target, TADDR expected) { CONTRACTL { @@ -184,12 +176,6 @@ struct StubPrecode } CONTRACTL_END; -#ifdef FEATURE_INTERPRETER - if (fInterpreter) - { - target = (PCODE)InterpreterStub; - } -#endif StubPrecodeData *pData = GetData(); return InterlockedCompareExchangeT(&pData->Target, (PCODE)target, (PCODE)expected) == expected; } @@ -222,13 +208,42 @@ typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; #endif // HAS_NDIRECT_IMPORT_PRECODE +struct InterpreterPrecodeData +{ + TADDR ByteCodeAddr; + PCODE Target; + BYTE Type; +}; + +typedef DPTR(InterpreterPrecodeData) PTR_InterpreterPrecodeData; + +struct InterpreterPrecode +{ + static const int Type = 0x06; + + BYTE m_code[StubPrecode::CodeSize]; + + void Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr); + + PTR_InterpreterPrecodeData GetData() const + { + LIMITED_METHOD_CONTRACT; + return dac_cast(dac_cast(this) + GetStubCodePageSize()); + } + + PCODE GetEntryPoint() + { + LIMITED_METHOD_CONTRACT; + return PINSTRToPCODE(dac_cast(this)); + } +}; #ifdef HAS_FIXUP_PRECODE struct FixupPrecodeData { PCODE Target; - TADDR MethodDesc; // MethodDesc pointer or interpreted code address or-ed with the InterpretedCodeAddressFlag + class MethodDesc *MethodDesc; PCODE PrecodeFixupThunk; }; @@ -289,23 +304,16 @@ struct FixupPrecode } TADDR GetMethodDesc() -#ifdef FEATURE_INTERPRETER - ; -#else { + LIMITED_METHOD_CONTRACT; return (TADDR)GetData()->MethodDesc; } -#endif PCODE GetTarget() -#ifdef FEATURE_INTERPRETER - ; -#else { LIMITED_METHOD_DAC_CONTRACT; return GetData()->Target; } -#endif PCODE *GetTargetSlot() { @@ -331,7 +339,7 @@ struct FixupPrecode InterlockedExchangeT(&GetData()->Target, target); } - BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter) + BOOL SetTargetInterlocked(TADDR target, TADDR expected) { CONTRACTL { @@ -340,15 +348,6 @@ struct FixupPrecode } CONTRACTL_END; -#ifdef FEATURE_INTERPRETER - if (fInterpreter) - { - _ASSERTE(IS_ALIGNED(&GetData()->PrecodeFixupThunk, sizeof(SIZE_T))); - _ASSERTE((PCODE)GetData()->Target == ((PCODE)this + FixupCodeOffset)); - PCODE oldTarget = (PCODE)GetData()->PrecodeFixupThunk; - return InterlockedCompareExchangeT(&GetData()->PrecodeFixupThunk, (PCODE)InterpreterStub, (PCODE)oldTarget) == (PCODE)oldTarget; - } -#endif PCODE oldTarget = (PCODE)GetData()->Target; if (oldTarget != ((PCODE)this + FixupCodeOffset)) { @@ -381,6 +380,7 @@ typedef DPTR(class Precode) PTR_Precode; enum PrecodeType { PRECODE_INVALID = InvalidPrecode::Type, PRECODE_STUB = StubPrecode::Type, + PRECODE_INTERPRETER = InterpreterPrecode::Type, #ifdef HAS_NDIRECT_IMPORT_PRECODE PRECODE_NDIRECT_IMPORT = NDirectImportPrecode::Type, #endif // HAS_NDIRECT_IMPORT_PRECODE @@ -568,11 +568,15 @@ class Precode { static Precode* Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker); + + static InterpreterPrecode* AllocateInterpreterPrecode(PCODE byteCode, + LoaderAllocator * pLoaderAllocator, AllocMemTracker * pamTracker); + void Init(Precode* pPrecodeRX, PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); #ifndef DACCESS_COMPILE void ResetTargetInterlocked(); - BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE, BOOL fInterpreter = FALSE); + BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE); // Reset precode to point to prestub void Reset(); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index eaaa074d0a26b3..3f724bc94cd01e 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -426,9 +426,14 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) LOG((LF_CLASSLOADER, LL_INFO1000000, " In PrepareILBasedCode, calling JitCompileCode\n")); pCode = JitCompileCode(pConfig); + if (pConfig->IsInterpreterCode()) { - pCode |= InterpretedCodeAddressFlag; + AllocMemTracker amt; + InterpreterPrecode* pPrecode = Precode::AllocateInterpreterPrecode(pCode, GetLoaderAllocator(), &amt); + amt.SuppressRelease(); + pCode = PINSTRToPCODE(pPrecode->GetEntryPoint()); + SetNativeCodeInterlocked(pCode); } } else @@ -2691,7 +2696,6 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method #ifdef FEATURE_INTERPRETER extern "C" void STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr) { - byteCodeAddr &= ~InterpretedCodeAddressFlag; CodeHeader* pCodeHeader = EEJitManager::GetCodeHeaderFromStartAddress(byteCodeAddr); EEJitManager *pManager = ExecutionManager::GetEEJitManager(); From fa14cfaa62e2e650ffc07e132ada9fd0e5f3ca33 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 6 Feb 2025 16:34:30 +0100 Subject: [PATCH 4/5] Put all interpreter related code under #ifdef Also enable the interpreter in debug / checked builds only by default --- src/coreclr/clrdefinitions.cmake | 5 ++--- src/coreclr/clrfeatures.cmake | 2 +- src/coreclr/vm/amd64/AsmHelpers.asm | 4 ++++ src/coreclr/vm/amd64/asmhelpers.S | 2 ++ src/coreclr/vm/arm64/asmhelpers.S | 2 ++ src/coreclr/vm/arm64/asmhelpers.asm | 4 ++++ src/coreclr/vm/jitinterface.cpp | 8 +++++++- src/coreclr/vm/method.hpp | 5 ++++- src/coreclr/vm/precode.cpp | 4 ++++ src/coreclr/vm/precode.h | 8 ++++++-- src/coreclr/vm/prestub.cpp | 5 ++++- 11 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 78efad1f4d7c7f..d5b2d29d2e5d5a 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -125,9 +125,8 @@ endif(NOT CLR_CMAKE_TARGET_NETBSD) if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_definitions(-DFEATURE_INTEROP_DEBUGGING) endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) -if(FEATURE_INTERPRETER) - add_compile_definitions(FEATURE_INTERPRETER) -endif(FEATURE_INTERPRETER) + +add_compile_definitions($<${FEATURE_INTERPRETER}:FEATURE_INTERPRETER>) if (CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_ISYM_READER) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 27f416cc711090..90b40131b533d3 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -18,7 +18,7 @@ endif(NOT DEFINED FEATURE_DBGIPC) if(NOT DEFINED FEATURE_INTERPRETER) if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) - set(FEATURE_INTERPRETER 1) + set(FEATURE_INTERPRETER $,1,0>) else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) set(FEATURE_INTERPRETER 0) endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) diff --git a/src/coreclr/vm/amd64/AsmHelpers.asm b/src/coreclr/vm/amd64/AsmHelpers.asm index e303edd4d6b9b2..6c03f7c91b6992 100644 --- a/src/coreclr/vm/amd64/AsmHelpers.asm +++ b/src/coreclr/vm/amd64/AsmHelpers.asm @@ -11,7 +11,9 @@ extern ProfileLeave:proc extern ProfileTailcall:proc extern OnHijackWorker:proc extern JIT_RareDisableHelperWorker:proc +ifdef FEATURE_INTERPRETER extern ExecuteInterpretedMethod:proc +endif extern g_pPollGC:QWORD extern g_TrapReturningThreads:DWORD @@ -459,6 +461,7 @@ JIT_PollGCRarePath: TAILJMP_RAX LEAF_END JIT_PollGC, _TEXT +ifdef FEATURE_INTERPRETER NESTED_ENTRY InterpreterStub, _TEXT PROLOG_WITH_TRANSITION_BLOCK @@ -473,5 +476,6 @@ NESTED_ENTRY InterpreterStub, _TEXT EPILOG_WITH_TRANSITION_BLOCK_RETURN NESTED_END InterpreterStub, _TEXT +endif ; FEATURE_INTERPRETER end \ No newline at end of file diff --git a/src/coreclr/vm/amd64/asmhelpers.S b/src/coreclr/vm/amd64/asmhelpers.S index 4e71db6dfc6904..32301272eb3903 100644 --- a/src/coreclr/vm/amd64/asmhelpers.S +++ b/src/coreclr/vm/amd64/asmhelpers.S @@ -331,6 +331,7 @@ LOCAL_LABEL(JIT_PollGCRarePath): jmp rax LEAF_END JIT_PollGC, _TEXT +#ifdef FEATURE_INTERPRETER NESTED_ENTRY InterpreterStub, _TEXT, NoHandler PROLOG_WITH_TRANSITION_BLOCK 8, 0, 0, 0, 0 @@ -347,3 +348,4 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler EPILOG_WITH_TRANSITION_BLOCK_RETURN NESTED_END InterpreterStub, _TEXT +#endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index 7a00f7a1d35960..2fa596af772ffc 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -818,6 +818,7 @@ LOCAL_LABEL(JIT_PollGCRarePath): br x9 LEAF_END JIT_PollGC, _TEXT +#ifdef FEATURE_INTERPRETER NESTED_ENTRY InterpreterStub, _TEXT, NoHandler PROLOG_WITH_TRANSITION_BLOCK @@ -830,3 +831,4 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler EPILOG_WITH_TRANSITION_BLOCK_RETURN NESTED_END InterpreterStub, _TEXT +#endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index ccb45b374dd2d8..a08bb3f8caf22f 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -21,7 +21,9 @@ #endif IMPORT HijackHandler IMPORT ThrowControlForThread +#ifdef FEATURE_INTERPRETER IMPORT ExecuteInterpretedMethod +#endif #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP IMPORT g_sw_ww_table @@ -1194,6 +1196,7 @@ JIT_PollGCRarePath br x9 LEAF_END +#ifdef FEATURE_INTERPRETER NESTED_ENTRY InterpreterStub PROLOG_WITH_TRANSITION_BLOCK @@ -1206,6 +1209,7 @@ JIT_PollGCRarePath EPILOG_WITH_TRANSITION_BLOCK_RETURN NESTED_END +#endif // FEATURE_INTERPRETER ; Must be at very end of file END diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b4f0c28072a4e7..d136b2465157b4 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6611,7 +6611,11 @@ void CEEInfo::setMethodAttribs ( ftn->SetNotInline(true); } - if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT | CORINFO_FLG_INTERPRETER)) + if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT +#ifdef FEATURE_INTERPRETER + | CORINFO_FLG_INTERPRETER +#endif // FEATURE_INTERPRETER + )) { PrepareCodeConfig *config = GetThread()->GetCurrentPrepareCodeConfig(); if (config != nullptr) @@ -6621,10 +6625,12 @@ void CEEInfo::setMethodAttribs ( _ASSERTE(!ftn->IsJitOptimizationDisabled()); config->SetJitSwitchedToMinOpt(); } +#ifdef FEATURE_INTERPRETER else if (attribs & CORINFO_FLG_INTERPRETER) { config->SetIsInterpreterCode(); } +#endif // FEATURE_INTERPRETER #ifdef FEATURE_TIERED_COMPILATION else if (attribs & CORINFO_FLG_SWITCHED_TO_OPTIMIZED) { diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index f77b3f3b118120..eab8ae8f3232e1 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -2060,6 +2060,7 @@ class PrepareCodeConfig m_jitSwitchedToMinOpt = true; } +#ifdef FEATURE_INTERPRETER void SetIsInterpreterCode() { LIMITED_METHOD_CONTRACT; @@ -2071,6 +2072,7 @@ class PrepareCodeConfig LIMITED_METHOD_CONTRACT; return m_isInterpreterCode; } +#endif // FEATURE_INTERPRETER #ifdef FEATURE_TIERED_COMPILATION public: @@ -2140,8 +2142,9 @@ class PrepareCodeConfig #ifdef FEATURE_TIERED_COMPILATION bool m_jitSwitchedToOptimized; // when a different tier was requested #endif +#ifdef FEATURE_INTERPRETER bool m_isInterpreterCode; // The generated code is interpreter IR - +#endif // FEATURE_INTERPRETER PrepareCodeConfig *m_nextInSameThread; }; diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 8b5c52de3b078a..08d4c164585e46 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -184,6 +184,7 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr) #ifndef DACCESS_COMPILE +#ifdef FEATURE_INTERPRETER InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, LoaderAllocator * pLoaderAllocator, AllocMemTracker * pamTracker) @@ -201,6 +202,7 @@ InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, pPrecode->Init(pPrecode, byteCode); return pPrecode; } +#endif // FEATURE_INTERPRETER Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator * pLoaderAllocator, @@ -501,6 +503,7 @@ BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr) #endif // TARGET_X86 } +#ifdef FEATURE_INTERPRETER void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr) { WRAPPER_NO_CONTRACT; @@ -510,6 +513,7 @@ void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr pStubData->ByteCodeAddr = byteCodeAddr; pStubData->Type = InterpreterPrecode::Type; } +#endif // FEATURE_INTERPRETER #ifdef HAS_NDIRECT_IMPORT_PRECODE diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index e2772cf5d664df..ebe53d16463d60 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -208,6 +208,7 @@ typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; #endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef FEATURE_INTERPRETER struct InterpreterPrecodeData { TADDR ByteCodeAddr; @@ -237,6 +238,7 @@ struct InterpreterPrecode return PINSTRToPCODE(dac_cast(this)); } }; +#endif // FEATURE_INTERPRETER #ifdef HAS_FIXUP_PRECODE @@ -380,7 +382,9 @@ typedef DPTR(class Precode) PTR_Precode; enum PrecodeType { PRECODE_INVALID = InvalidPrecode::Type, PRECODE_STUB = StubPrecode::Type, +#ifdef FEATURE_INTERPRETER PRECODE_INTERPRETER = InterpreterPrecode::Type, +#endif // FEATURE_INTERPRETER #ifdef HAS_NDIRECT_IMPORT_PRECODE PRECODE_NDIRECT_IMPORT = NDirectImportPrecode::Type, #endif // HAS_NDIRECT_IMPORT_PRECODE @@ -568,10 +572,10 @@ class Precode { static Precode* Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker); - +#ifdef FEATURE_INTERPRETER static InterpreterPrecode* AllocateInterpreterPrecode(PCODE byteCode, LoaderAllocator * pLoaderAllocator, AllocMemTracker * pamTracker); - +#endif // FEATURE_INTERPRETER void Init(Precode* pPrecodeRX, PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index 3f724bc94cd01e..9e2c581413ed2a 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -426,7 +426,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) LOG((LF_CLASSLOADER, LL_INFO1000000, " In PrepareILBasedCode, calling JitCompileCode\n")); pCode = JitCompileCode(pConfig); - +#ifdef FEATURE_INTERPRETER if (pConfig->IsInterpreterCode()) { AllocMemTracker amt; @@ -435,6 +435,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) pCode = PINSTRToPCODE(pPrecode->GetEntryPoint()); SetNativeCodeInterlocked(pCode); } +#endif // FEATURE_INTERPRETER } else { @@ -1839,7 +1840,9 @@ PrepareCodeConfig::PrepareCodeConfig(NativeCodeVersion codeVersion, BOOL needsMu #ifdef FEATURE_TIERED_COMPILATION m_jitSwitchedToOptimized(false), #endif +#ifdef FEATURE_INTERPRETER m_isInterpreterCode(false), +#endif m_nextInSameThread(nullptr) {} From ae22343ea1dffb5c9d1bb17a8894d81fd3b2215d Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 6 Feb 2025 23:10:06 +0100 Subject: [PATCH 5/5] Fix OSX x64 build break --- src/coreclr/vm/amd64/asmhelpers.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/amd64/asmhelpers.S b/src/coreclr/vm/amd64/asmhelpers.S index 32301272eb3903..c4391a00b23c32 100644 --- a/src/coreclr/vm/amd64/asmhelpers.S +++ b/src/coreclr/vm/amd64/asmhelpers.S @@ -337,9 +337,9 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler PROLOG_WITH_TRANSITION_BLOCK 8, 0, 0, 0, 0 mov [rsp], rax // Return buffer in Swift calling convention - ; - ; call ExecuteInterpretedMethod - ; + # + # call ExecuteInterpretedMethod + # lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock* mov rsi, METHODDESC_REGISTER call C_FUNC(ExecuteInterpretedMethod)