Skip to content

Commit

Permalink
Add new precode type for interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
janvorli committed Feb 6, 2025
1 parent d7c56e7 commit bd9f36b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 97 deletions.
3 changes: 0 additions & 3 deletions src/coreclr/inc/utilcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
5 changes: 0 additions & 5 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13143,11 +13143,6 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config,
ret |= THUMB_CODE;
#endif

if (config->IsInterpreterCode())
{
ret |= InterpretedCodeAddressFlag;
}

// We are done
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3044,7 +3044,7 @@ void MethodDesc::TrySetInitialCodeEntryPointForVersionableMethod(
else
{
_ASSERTE(IsVersionableWithPrecode());
GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */, (entryPoint & InterpretedCodeAddressFlag) /* fInterpreter */);
GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */);
}
}

Expand Down
78 changes: 28 additions & 50 deletions src/coreclr/vm/precode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TADDR>(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<PCODE>(methodDesc);
}

TADDR FixupPrecode::GetMethodDesc()
{
LIMITED_METHOD_CONTRACT;
return GetMethodDescFromPrecodeData(dac_cast<TADDR>(GetData()->MethodDesc));
}

PCODE FixupPrecode::GetTarget()
{
LIMITED_METHOD_DAC_CONTRACT;
return GetTargetFromPrecodeData(dac_cast<TADDR>(GetData()->MethodDesc), GetData()->Target);
}

TADDR StubPrecode::GetMethodDesc()
{
LIMITED_METHOD_CONTRACT;
return GetMethodDescFromPrecodeData(dac_cast<TADDR>(GetData()->MethodDesc));
}

PCODE StubPrecode::GetTarget()
{
LIMITED_METHOD_DAC_CONTRACT;
return GetTargetFromPrecodeData(dac_cast<TADDR>(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,
Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand All @@ -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);

Expand Down
76 changes: 40 additions & 36 deletions src/coreclr/vm/precode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -133,26 +133,18 @@ struct StubPrecode
}

TADDR GetMethodDesc()
#ifdef FEATURE_INTERPRETER
;
#else
{
LIMITED_METHOD_DAC_CONTRACT;

return dac_cast<TADDR>(GetData()->MethodDesc);
}
#endif

PCODE GetTarget()
#ifdef FEATURE_INTERPRETER
;
#else
{
LIMITED_METHOD_DAC_CONTRACT;

return GetData()->Target;
}
#endif

BYTE GetType()
{
Expand All @@ -175,7 +167,7 @@ struct StubPrecode
InterlockedExchangeT<PCODE>(&pData->Target, GetPreStubEntryPoint());
}

BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter)
BOOL SetTargetInterlocked(TADDR target, TADDR expected)
{
CONTRACTL
{
Expand All @@ -184,12 +176,6 @@ struct StubPrecode
}
CONTRACTL_END;

#ifdef FEATURE_INTERPRETER
if (fInterpreter)
{
target = (PCODE)InterpreterStub;
}
#endif
StubPrecodeData *pData = GetData();
return InterlockedCompareExchangeT<PCODE>(&pData->Target, (PCODE)target, (PCODE)expected) == expected;
}
Expand Down Expand Up @@ -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<PTR_InterpreterPrecodeData>(dac_cast<TADDR>(this) + GetStubCodePageSize());
}

PCODE GetEntryPoint()
{
LIMITED_METHOD_CONTRACT;
return PINSTRToPCODE(dac_cast<TADDR>(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;
};

Expand Down Expand Up @@ -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()
{
Expand All @@ -331,7 +339,7 @@ struct FixupPrecode
InterlockedExchangeT<PCODE>(&GetData()->Target, target);
}

BOOL SetTargetInterlocked(TADDR target, TADDR expected, BOOL fInterpreter)
BOOL SetTargetInterlocked(TADDR target, TADDR expected)
{
CONTRACTL
{
Expand All @@ -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<PCODE>(&GetData()->PrecodeFixupThunk, (PCODE)InterpreterStub, (PCODE)oldTarget) == (PCODE)oldTarget;
}
#endif
PCODE oldTarget = (PCODE)GetData()->Target;
if (oldTarget != ((PCODE)this + FixupCodeOffset))
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 6 additions & 2 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit bd9f36b

Please sign in to comment.