Skip to content

Commit 6abed7d

Browse files
committed
Stop using a mapping table between MethodDesc and InterpMethod
InterpMethod* is used to handle interpreted method execution on mono, but it is not really needed. For CoreCLR we will turn this structure in a header to the compiled IR code, and identify other methods directly by the IR code pointer. The first pointer slot in the IR code will contain a pointer to the InterpMethod containing any other relevant information needed in the method execution.
1 parent bd69a84 commit 6abed7d

File tree

8 files changed

+39
-68
lines changed

8 files changed

+39
-68
lines changed

src/coreclr/inc/corjit.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ extern "C" ICorJitCompiler* getJit();
107107
class ICorInterpreter
108108
{
109109
public:
110-
virtual void* GetInterpMethod(CORINFO_METHOD_HANDLE methodHnd) = 0;
111110
};
112111

113112
// #EEToJitInterface

src/coreclr/interpreter/compiler.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,24 @@ void InterpCompiler::EmitCode()
467467
ip = EmitCodeIns(ip, ins);
468468
}
469469
}
470+
471+
m_MethodCodeSize = (int32_t)(ip - m_pMethodCode);
470472
}
471473

472-
void InterpCompiler::PublishInterpMethod(InterpMethod* pMethod)
474+
InterpMethod* InterpCompiler::CreateInterpMethod()
473475
{
474-
pMethod->pCode = m_pMethodCode;
476+
InterpMethod *pMethod = new InterpMethod;
477+
475478
pMethod->allocaSize = m_totalVarsStackSize;
476-
pMethod->compiled = true;
479+
pMethod->methodHnd = m_methodHnd;
480+
481+
return pMethod;
482+
}
483+
484+
int32_t* InterpCompiler::GetCode(int32_t *pCodeSize)
485+
{
486+
*pCodeSize = m_MethodCodeSize;
487+
return m_pMethodCode;
477488
}
478489

479490
InterpCompiler::InterpCompiler(COMP_HANDLE compHnd,
@@ -484,7 +495,7 @@ InterpCompiler::InterpCompiler(COMP_HANDLE compHnd,
484495
m_methodInfo = methodInfo;
485496
}
486497

487-
int InterpCompiler::CompileMethod(InterpMethod *pMethod)
498+
InterpMethod* InterpCompiler::CompileMethod()
488499
{
489500
GenerateCode(m_methodInfo);
490501

@@ -494,9 +505,7 @@ int InterpCompiler::CompileMethod(InterpMethod *pMethod)
494505

495506
EmitCode();
496507

497-
PublishInterpMethod(pMethod);
498-
499-
return CORJIT_OK;
508+
return CreateInterpMethod();
500509
}
501510

502511
int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)

src/coreclr/interpreter/compiler.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,18 +206,21 @@ class InterpCompiler
206206

207207
// Passes
208208
int32_t* m_pMethodCode;
209+
int32_t m_MethodCodeSize; // in int32_t
209210

210211
void OptimizeCode();
211212
void AllocOffsets();
212213
int32_t ComputeCodeSize();
213214
void EmitCode();
214215
int32_t* EmitCodeIns(int32_t *ip, InterpInst *pIns);
215-
void PublishInterpMethod(InterpMethod *pMethod);
216+
InterpMethod* CreateInterpMethod();
216217
public:
217218

218219
InterpCompiler(COMP_HANDLE compHnd, CORINFO_METHOD_INFO* methodInfo);
219220

220-
int CompileMethod(InterpMethod *pMethod);
221+
InterpMethod* CompileMethod();
222+
223+
int32_t* GetCode(int32_t *pCodeSize);
221224
};
222225

223226
#endif //_COMPILER_H_

src/coreclr/interpreter/eeinterp.cpp

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,6 @@
1717

1818
#include <vector>
1919

20-
// FIXME We will probably end up not needing this table.
21-
// If deemed useful, use some hashtable implementation instead.
22-
std::vector<std::pair<CORINFO_METHOD_HANDLE,InterpMethod*>> g_interpCodeHash;
23-
24-
static InterpMethod* InterpGetInterpMethod(CORINFO_METHOD_HANDLE methodHnd)
25-
{
26-
// FIXME lock for multiple thread access
27-
for (size_t i = 0; i < g_interpCodeHash.size(); i++)
28-
{
29-
if (g_interpCodeHash[i].first == methodHnd)
30-
{
31-
return g_interpCodeHash[i].second;
32-
}
33-
}
34-
35-
InterpMethod* pMethod = new InterpMethod();
36-
pMethod->methodHnd = methodHnd;
37-
38-
g_interpCodeHash.push_back({methodHnd, pMethod});
39-
return pMethod;
40-
}
41-
4220
/*****************************************************************************/
4321
ICorJitHost* g_interpHost = nullptr;
4422
bool g_interpInitialized = false;
@@ -95,33 +73,36 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd,
9573
return CORJIT_SKIPPED;
9674
}
9775

98-
InterpMethod *pMethod = InterpGetInterpMethod(methodInfo->ftn);
99-
if (!pMethod->compiled)
100-
{
101-
InterpCompiler compiler(compHnd, methodInfo);
102-
compiler.CompileMethod(pMethod);
103-
}
76+
InterpCompiler compiler(compHnd, methodInfo);
77+
InterpMethod *pMethod = compiler.CompileMethod();
78+
79+
int32_t IRCodeSize;
80+
int32_t *pIRCode = compiler.GetCode(&IRCodeSize);
10481

10582
// FIXME this shouldn't be here
10683
compHnd->setMethodAttribs(methodInfo->ftn, CORINFO_FLG_INTERPRETER);
10784

85+
uint32_t sizeOfCode = sizeof(void*) + IRCodeSize * sizeof(int32_t);
86+
10887
// TODO: get rid of the need to allocate fake unwind info.
10988
compHnd->reserveUnwindInfo(false /* isFunclet */, false /* isColdCode */ , 8 /* unwindSize */);
11089
AllocMemArgs args;
111-
args.hotCodeSize = 16;
90+
args.hotCodeSize = sizeOfCode;
11291
args.coldCodeSize = 0;
11392
args.roDataSize = 0;
11493
args.xcptnsCount = 0;
11594
args.flag = CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN;
11695
compHnd->allocMem(&args);
117-
uint8_t *code = (uint8_t*)args.hotCodeBlockRW;
118-
*code++ = 1; // fake byte code
96+
97+
// We store first the InterpMethod pointer as the code header, followed by the actual code
98+
*(InterpMethod**)args.hotCodeBlockRW = pMethod;
99+
memcpy ((uint8_t*)args.hotCodeBlockRW + sizeof(InterpMethod*), pIRCode, IRCodeSize * sizeof(int32_t));
119100

120101
// TODO: get rid of the need to allocate fake unwind info
121102
compHnd->allocUnwindInfo((uint8_t*)args.hotCodeBlock, (uint8_t*)args.coldCodeBlock, 0, 1, 0, nullptr, CORJIT_FUNC_ROOT);
122103

123104
*entryAddress = (uint8_t*)args.hotCodeBlock;
124-
*nativeSizeOfCode = 1;
105+
*nativeSizeOfCode = sizeOfCode;
125106

126107
return CORJIT_OK;
127108
}
@@ -140,8 +121,3 @@ void CILInterp::getVersionIdentifier(GUID* versionIdentifier)
140121
void CILInterp::setTargetOS(CORINFO_OS os)
141122
{
142123
}
143-
144-
void* InterpManager::GetInterpMethod(CORINFO_METHOD_HANDLE methodHnd)
145-
{
146-
return InterpGetInterpMethod(methodHnd);
147-
}

src/coreclr/interpreter/interpretershared.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ typedef enum
2020
struct InterpMethod
2121
{
2222
CORINFO_METHOD_HANDLE methodHnd;
23-
int32_t *pCode;
2423
int32_t allocaSize;
25-
26-
volatile bool compiled;
27-
28-
InterpMethod()
29-
{
30-
pCode = NULL;
31-
compiled = false;
32-
}
3324
};
3425

3526
#endif

src/coreclr/vm/interpexec.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ void InterpExecMethod(InterpFrame *pFrame, InterpThreadContext *pThreadContext)
3535
const int32_t *ip;
3636
int8_t *stack;
3737

38-
pThreadContext->pStackPointer = pFrame->pStack + pFrame->pMethod->allocaSize;
39-
ip = pFrame->pMethod->pCode;
38+
InterpMethod *pMethod = *(InterpMethod**)pFrame->startIp;
39+
pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize;
40+
ip = pFrame->startIp + sizeof(InterpMethod*) / sizeof(int32_t);
4041
stack = pFrame->pStack;
4142

4243
while (true)

src/coreclr/vm/interpexec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct StackVal
2424
struct InterpFrame
2525
{
2626
InterpFrame *pParent;
27-
InterpMethod *pMethod;
27+
int32_t *startIp; // from start_ip we can obtain InterpMethod and MethodDesc
2828
int8_t *pStack;
2929
int8_t *pRetVal;
3030
int32_t *ip;

src/coreclr/vm/prestub.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,19 +2742,11 @@ extern "C" void STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlo
27422742
{
27432743
// Argument registers are in the TransitionBlock
27442744
// The stack arguments are right after the pTransitionBlock
2745-
CodeHeader* pCodeHeader = EEJitManager::GetCodeHeaderFromStartAddress(byteCodeAddr);
2746-
2747-
EEJitManager *pManager = ExecutionManager::GetEEJitManager();
2748-
MethodDesc *pMD = pCodeHeader->GetMethodDesc();
2749-
2750-
InterpMethod *pMethod = (InterpMethod*)pManager->m_interpreter->GetInterpMethod((CORINFO_METHOD_HANDLE)pMD);
2751-
assert(pMethod && pMethod->compiled);
2752-
27532745
InterpThreadContext *threadContext = InterpGetThreadContext();
27542746
int8_t *sp = threadContext->pStackPointer;
27552747

27562748
InterpFrame interpFrame = {0};
2757-
interpFrame.pMethod = pMethod;
2749+
interpFrame.startIp = (int32_t*)byteCodeAddr;
27582750
interpFrame.pStack = sp;
27592751
interpFrame.pRetVal = sp;
27602752

0 commit comments

Comments
 (0)