Skip to content

Commit cee8434

Browse files
authored
Initial interpreter wire-in (#112202)
* 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. * Fix incorrect lookup for CodeHeader Found by PR feedback, instead of InterpretedCodeAddressFlag, it was using 1. * Add new precode type for interpreter * Put all interpreter related code under #ifdef Also enable the interpreter in debug / checked builds only by default * Fix OSX x64 build break
1 parent c9cc904 commit cee8434

File tree

12 files changed

+211
-2
lines changed

12 files changed

+211
-2
lines changed

src/coreclr/clrdefinitions.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_
126126
add_definitions(-DFEATURE_INTEROP_DEBUGGING)
127127
endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64))
128128

129+
add_compile_definitions($<${FEATURE_INTERPRETER}:FEATURE_INTERPRETER>)
130+
129131
if (CLR_CMAKE_TARGET_WIN32)
130132
add_definitions(-DFEATURE_ISYM_READER)
131133
endif(CLR_CMAKE_TARGET_WIN32)

src/coreclr/clrfeatures.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ if(NOT DEFINED FEATURE_DBGIPC)
1616
endif()
1717
endif(NOT DEFINED FEATURE_DBGIPC)
1818

19+
if(NOT DEFINED FEATURE_INTERPRETER)
20+
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
21+
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
22+
else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
23+
set(FEATURE_INTERPRETER 0)
24+
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
25+
endif(NOT DEFINED FEATURE_INTERPRETER)
26+
1927
if(NOT DEFINED FEATURE_STANDALONE_GC)
2028
set(FEATURE_STANDALONE_GC 1)
2129
endif(NOT DEFINED FEATURE_STANDALONE_GC)

src/coreclr/inc/corinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ enum CorInfoFlag
786786
enum CorInfoMethodRuntimeFlags
787787
{
788788
CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining
789-
// unused = 0x00000002,
789+
CORINFO_FLG_INTERPRETER = 0x00000002, // The method was compiled by the interpreter
790790
// unused = 0x00000004,
791791
CORINFO_FLG_SWITCHED_TO_MIN_OPT = 0x00000008, // The JIT decided to switch to MinOpt for this method, when it was not requested
792792
CORINFO_FLG_SWITCHED_TO_OPTIMIZED = 0x00000010, // The JIT decided to switch to tier 1 for this method, when a different tier was requested

src/coreclr/vm/amd64/AsmHelpers.asm

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ extern ProfileLeave:proc
1111
extern ProfileTailcall:proc
1212
extern OnHijackWorker:proc
1313
extern JIT_RareDisableHelperWorker:proc
14+
ifdef FEATURE_INTERPRETER
15+
extern ExecuteInterpretedMethod:proc
16+
endif
1417

1518
extern g_pPollGC:QWORD
1619
extern g_TrapReturningThreads:DWORD
@@ -477,4 +480,21 @@ JIT_PollGCRarePath:
477480
TAILJMP_RAX
478481
LEAF_END JIT_PollGC, _TEXT
479482

483+
ifdef FEATURE_INTERPRETER
484+
NESTED_ENTRY InterpreterStub, _TEXT
485+
486+
PROLOG_WITH_TRANSITION_BLOCK
487+
488+
;
489+
; call ExecuteInterpretedMethod
490+
;
491+
lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock*
492+
mov rdx, METHODDESC_REGISTER
493+
call ExecuteInterpretedMethod
494+
495+
EPILOG_WITH_TRANSITION_BLOCK_RETURN
496+
497+
NESTED_END InterpreterStub, _TEXT
498+
endif ; FEATURE_INTERPRETER
499+
480500
end

src/coreclr/vm/amd64/asmhelpers.S

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,22 @@ LOCAL_LABEL(JIT_PollGCRarePath):
333333
mov rax, [rax]
334334
jmp rax
335335
LEAF_END JIT_PollGC, _TEXT
336+
337+
#ifdef FEATURE_INTERPRETER
338+
NESTED_ENTRY InterpreterStub, _TEXT, NoHandler
339+
340+
PROLOG_WITH_TRANSITION_BLOCK 8, 0, 0, 0, 0
341+
mov [rsp], rax // Return buffer in Swift calling convention
342+
343+
#
344+
# call ExecuteInterpretedMethod
345+
#
346+
lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock*
347+
mov rsi, METHODDESC_REGISTER
348+
call C_FUNC(ExecuteInterpretedMethod)
349+
350+
mov rax, [rsp]
351+
EPILOG_WITH_TRANSITION_BLOCK_RETURN
352+
353+
NESTED_END InterpreterStub, _TEXT
354+
#endif // FEATURE_INTERPRETER

src/coreclr/vm/arm64/asmhelpers.S

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,18 @@ LOCAL_LABEL(JIT_PollGCRarePath):
835835
ldr x9, [x9]
836836
br x9
837837
LEAF_END JIT_PollGC, _TEXT
838+
839+
#ifdef FEATURE_INTERPRETER
840+
NESTED_ENTRY InterpreterStub, _TEXT, NoHandler
841+
842+
PROLOG_WITH_TRANSITION_BLOCK
843+
844+
add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock
845+
mov x1, METHODDESC_REGISTER // pMethodDesc
846+
847+
bl C_FUNC(ExecuteInterpretedMethod)
848+
849+
EPILOG_WITH_TRANSITION_BLOCK_RETURN
850+
851+
NESTED_END InterpreterStub, _TEXT
852+
#endif // FEATURE_INTERPRETER

src/coreclr/vm/arm64/asmhelpers.asm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#endif
2222
IMPORT HijackHandler
2323
IMPORT ThrowControlForThread
24+
#ifdef FEATURE_INTERPRETER
25+
IMPORT ExecuteInterpretedMethod
26+
#endif
2427

2528
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
2629
IMPORT g_sw_ww_table
@@ -1211,6 +1214,20 @@ JIT_PollGCRarePath
12111214
br x9
12121215
LEAF_END
12131216

1217+
#ifdef FEATURE_INTERPRETER
1218+
NESTED_ENTRY InterpreterStub
1219+
1220+
PROLOG_WITH_TRANSITION_BLOCK
1221+
1222+
add x0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
1223+
mov x1, METHODDESC_REGISTER ; pMethodDesc
1224+
1225+
bl ExecuteInterpretedMethod
1226+
1227+
EPILOG_WITH_TRANSITION_BLOCK_RETURN
1228+
1229+
NESTED_END
1230+
#endif // FEATURE_INTERPRETER
12141231

12151232
; Must be at very end of file
12161233
END

src/coreclr/vm/jitinterface.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6611,7 +6611,11 @@ void CEEInfo::setMethodAttribs (
66116611
ftn->SetNotInline(true);
66126612
}
66136613

6614-
if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT))
6614+
if (attribs & (CORINFO_FLG_SWITCHED_TO_OPTIMIZED | CORINFO_FLG_SWITCHED_TO_MIN_OPT
6615+
#ifdef FEATURE_INTERPRETER
6616+
| CORINFO_FLG_INTERPRETER
6617+
#endif // FEATURE_INTERPRETER
6618+
))
66156619
{
66166620
PrepareCodeConfig *config = GetThread()->GetCurrentPrepareCodeConfig();
66176621
if (config != nullptr)
@@ -6621,6 +6625,12 @@ void CEEInfo::setMethodAttribs (
66216625
_ASSERTE(!ftn->IsJitOptimizationDisabled());
66226626
config->SetJitSwitchedToMinOpt();
66236627
}
6628+
#ifdef FEATURE_INTERPRETER
6629+
else if (attribs & CORINFO_FLG_INTERPRETER)
6630+
{
6631+
config->SetIsInterpreterCode();
6632+
}
6633+
#endif // FEATURE_INTERPRETER
66246634
#ifdef FEATURE_TIERED_COMPILATION
66256635
else if (attribs & CORINFO_FLG_SWITCHED_TO_OPTIMIZED)
66266636
{

src/coreclr/vm/method.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,20 @@ class PrepareCodeConfig
20602060
m_jitSwitchedToMinOpt = true;
20612061
}
20622062

2063+
#ifdef FEATURE_INTERPRETER
2064+
void SetIsInterpreterCode()
2065+
{
2066+
LIMITED_METHOD_CONTRACT;
2067+
m_isInterpreterCode = true;
2068+
}
2069+
2070+
bool IsInterpreterCode() const
2071+
{
2072+
LIMITED_METHOD_CONTRACT;
2073+
return m_isInterpreterCode;
2074+
}
2075+
#endif // FEATURE_INTERPRETER
2076+
20632077
#ifdef FEATURE_TIERED_COMPILATION
20642078
public:
20652079
bool JitSwitchedToOptimized() const
@@ -2128,6 +2142,9 @@ class PrepareCodeConfig
21282142
#ifdef FEATURE_TIERED_COMPILATION
21292143
bool m_jitSwitchedToOptimized; // when a different tier was requested
21302144
#endif
2145+
#ifdef FEATURE_INTERPRETER
2146+
bool m_isInterpreterCode; // The generated code is interpreter IR
2147+
#endif // FEATURE_INTERPRETER
21312148
PrepareCodeConfig *m_nextInSameThread;
21322149
};
21332150

src/coreclr/vm/precode.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,26 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr)
184184

185185
#ifndef DACCESS_COMPILE
186186

187+
#ifdef FEATURE_INTERPRETER
188+
InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode,
189+
LoaderAllocator * pLoaderAllocator,
190+
AllocMemTracker * pamTracker)
191+
{
192+
CONTRACTL
193+
{
194+
THROWS;
195+
GC_NOTRIGGER;
196+
MODE_ANY;
197+
}
198+
CONTRACTL_END;
199+
200+
SIZE_T size = sizeof(InterpreterPrecode);
201+
InterpreterPrecode* pPrecode = (InterpreterPrecode*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocAlignedMem(size, 1));
202+
pPrecode->Init(pPrecode, byteCode);
203+
return pPrecode;
204+
}
205+
#endif // FEATURE_INTERPRETER
206+
187207
Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD,
188208
LoaderAllocator * pLoaderAllocator,
189209
AllocMemTracker * pamTracker)
@@ -483,6 +503,18 @@ BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr)
483503
#endif // TARGET_X86
484504
}
485505

506+
#ifdef FEATURE_INTERPRETER
507+
void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr)
508+
{
509+
WRAPPER_NO_CONTRACT;
510+
InterpreterPrecodeData *pStubData = GetData();
511+
512+
pStubData->Target = (PCODE)InterpreterStub;
513+
pStubData->ByteCodeAddr = byteCodeAddr;
514+
pStubData->Type = InterpreterPrecode::Type;
515+
}
516+
#endif // FEATURE_INTERPRETER
517+
486518
#ifdef HAS_NDIRECT_IMPORT_PRECODE
487519

488520
void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator)

0 commit comments

Comments
 (0)