Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_
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))

add_compile_definitions($<${FEATURE_INTERPRETER}:FEATURE_INTERPRETER>)

if (CLR_CMAKE_TARGET_WIN32)
add_definitions(-DFEATURE_ISYM_READER)
endif(CLR_CMAKE_TARGET_WIN32)
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/clrfeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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 $<IF:$<CONFIG:Debug,Checked>,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)
endif(NOT DEFINED FEATURE_INTERPRETER)

if(NOT DEFINED FEATURE_STANDALONE_GC)
set(FEATURE_STANDALONE_GC 1)
endif(NOT DEFINED FEATURE_STANDALONE_GC)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions src/coreclr/vm/amd64/AsmHelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +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
Expand Down Expand Up @@ -458,4 +461,21 @@ JIT_PollGCRarePath:
TAILJMP_RAX
LEAF_END JIT_PollGC, _TEXT

ifdef FEATURE_INTERPRETER
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
endif ; FEATURE_INTERPRETER

end
19 changes: 19 additions & 0 deletions src/coreclr/vm/amd64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,22 @@ LOCAL_LABEL(JIT_PollGCRarePath):
mov rax, [rax]
jmp rax
LEAF_END JIT_PollGC, _TEXT

#ifdef FEATURE_INTERPRETER
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
#endif // FEATURE_INTERPRETER
15 changes: 15 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -817,3 +817,18 @@ LOCAL_LABEL(JIT_PollGCRarePath):
ldr x9, [x9]
br x9
LEAF_END JIT_PollGC, _TEXT

#ifdef FEATURE_INTERPRETER
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
#endif // FEATURE_INTERPRETER
17 changes: 17 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +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
Expand Down Expand Up @@ -1193,6 +1196,20 @@ JIT_PollGCRarePath
br x9
LEAF_END

#ifdef FEATURE_INTERPRETER
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
#endif // FEATURE_INTERPRETER

; Must be at very end of file
END
12 changes: 11 additions & 1 deletion src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6611,7 +6611,11 @@ 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
#ifdef FEATURE_INTERPRETER
| CORINFO_FLG_INTERPRETER
#endif // FEATURE_INTERPRETER
))
{
PrepareCodeConfig *config = GetThread()->GetCurrentPrepareCodeConfig();
if (config != nullptr)
Expand All @@ -6621,6 +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)
{
Expand Down
17 changes: 17 additions & 0 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2060,6 +2060,20 @@ class PrepareCodeConfig
m_jitSwitchedToMinOpt = true;
}

#ifdef FEATURE_INTERPRETER
void SetIsInterpreterCode()
{
LIMITED_METHOD_CONTRACT;
m_isInterpreterCode = true;
}

bool IsInterpreterCode() const
{
LIMITED_METHOD_CONTRACT;
return m_isInterpreterCode;
}
#endif // FEATURE_INTERPRETER

#ifdef FEATURE_TIERED_COMPILATION
public:
bool JitSwitchedToOptimized() const
Expand Down Expand Up @@ -2128,6 +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;
};

Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/vm/precode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr)

#ifndef DACCESS_COMPILE

#ifdef FEATURE_INTERPRETER
InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode,
LoaderAllocator * pLoaderAllocator,
AllocMemTracker * pamTracker)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
MODE_ANY;
}
CONTRACTL_END;

SIZE_T size = sizeof(InterpreterPrecode);
InterpreterPrecode* pPrecode = (InterpreterPrecode*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocAlignedMem(size, 1));
pPrecode->Init(pPrecode, byteCode);
return pPrecode;
}
#endif // FEATURE_INTERPRETER

Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD,
LoaderAllocator * pLoaderAllocator,
AllocMemTracker * pamTracker)
Expand Down Expand Up @@ -483,6 +503,18 @@ BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr)
#endif // TARGET_X86
}

#ifdef FEATURE_INTERPRETER
void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr)
{
WRAPPER_NO_CONTRACT;
InterpreterPrecodeData *pStubData = GetData();

pStubData->Target = (PCODE)InterpreterStub;
pStubData->ByteCodeAddr = byteCodeAddr;
pStubData->Type = InterpreterPrecode::Type;
}
#endif // FEATURE_INTERPRETER

#ifdef HAS_NDIRECT_IMPORT_PRECODE

void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator)
Expand Down
42 changes: 42 additions & 0 deletions src/coreclr/vm/precode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -204,6 +208,37 @@ typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode;

#endif // HAS_NDIRECT_IMPORT_PRECODE

#ifdef FEATURE_INTERPRETER
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));
}
};
#endif // FEATURE_INTERPRETER

#ifdef HAS_FIXUP_PRECODE

Expand Down Expand Up @@ -347,6 +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
Expand Down Expand Up @@ -534,6 +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
Expand Down
27 changes: 27 additions & 0 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,16 @@ 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;
InterpreterPrecode* pPrecode = Precode::AllocateInterpreterPrecode(pCode, GetLoaderAllocator(), &amt);
amt.SuppressRelease();
pCode = PINSTRToPCODE(pPrecode->GetEntryPoint());
SetNativeCodeInterlocked(pCode);
}
#endif // FEATURE_INTERPRETER
}
else
{
Expand Down Expand Up @@ -1829,6 +1839,9 @@ PrepareCodeConfig::PrepareCodeConfig(NativeCodeVersion codeVersion, BOOL needsMu
m_jitSwitchedToMinOpt(false),
#ifdef FEATURE_TIERED_COMPILATION
m_jitSwitchedToOptimized(false),
#endif
#ifdef FEATURE_INTERPRETER
m_isInterpreterCode(false),
#endif
m_nextInSameThread(nullptr)
{}
Expand Down Expand Up @@ -2683,6 +2696,20 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
return pbRetVal;
}

#ifdef FEATURE_INTERPRETER
extern "C" void STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr)
{
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
Expand Down