Skip to content

Commit eefdc0b

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 ddf3593 commit eefdc0b

13 files changed

+40
-114
lines changed

src/coreclr/inc/corjit.h

-6
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,6 @@ class ICorJitInfo;
104104

105105
extern "C" ICorJitCompiler* getJit();
106106

107-
class ICorInterpreter
108-
{
109-
public:
110-
virtual void* GetInterpMethod(CORINFO_METHOD_HANDLE methodHnd) = 0;
111-
};
112-
113107
// #EEToJitInterface
114108
// ICorJitCompiler is the interface that the EE uses to get IL bytecode converted to native code. Note that
115109
// to accomplish this the JIT has to call back to the EE to get symbolic information. The code:ICorJitInfo

src/coreclr/interpreter/clrinterpreter.exports

-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
; The .NET Foundation licenses this file to you under the MIT license.
33
EXPORTS
44
getJit
5-
getInterpreter
65
jitStartup
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
getJit
2-
getInterpreter
32
jitStartup

src/coreclr/interpreter/compiler.cpp

+14-8
Original file line numberDiff line numberDiff line change
@@ -474,13 +474,21 @@ void InterpCompiler::EmitCode()
474474
ip = EmitCodeIns(ip, ins);
475475
}
476476
}
477+
478+
m_MethodCodeSize = (int32_t)(ip - m_pMethodCode);
477479
}
478480

479-
void InterpCompiler::PublishInterpMethod(InterpMethod* pMethod)
481+
InterpMethod* InterpCompiler::CreateInterpMethod()
480482
{
481-
pMethod->pCode = m_pMethodCode;
482-
pMethod->allocaSize = m_totalVarsStackSize;
483-
pMethod->compiled = true;
483+
InterpMethod *pMethod = new InterpMethod(m_methodHnd, m_totalVarsStackSize);
484+
485+
return pMethod;
486+
}
487+
488+
int32_t* InterpCompiler::GetCode(int32_t *pCodeSize)
489+
{
490+
*pCodeSize = m_MethodCodeSize;
491+
return m_pMethodCode;
484492
}
485493

486494
InterpCompiler::InterpCompiler(COMP_HANDLE compHnd,
@@ -491,7 +499,7 @@ InterpCompiler::InterpCompiler(COMP_HANDLE compHnd,
491499
m_methodInfo = methodInfo;
492500
}
493501

494-
int InterpCompiler::CompileMethod(InterpMethod *pMethod)
502+
InterpMethod* InterpCompiler::CompileMethod()
495503
{
496504
GenerateCode(m_methodInfo);
497505

@@ -501,9 +509,7 @@ int InterpCompiler::CompileMethod(InterpMethod *pMethod)
501509

502510
EmitCode();
503511

504-
PublishInterpMethod(pMethod);
505-
506-
return CORJIT_OK;
512+
return CreateInterpMethod();
507513
}
508514

509515
int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)

src/coreclr/interpreter/compiler.h

+5-2
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

+13-49
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,6 @@
1515
#define INTERP_API __attribute__ ((visibility ("default")))
1616
#endif // _MSC_VER
1717

18-
#include <vector>
19-
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-
4218
/*****************************************************************************/
4319
ICorJitHost* g_interpHost = nullptr;
4420
bool g_interpInitialized = false;
@@ -64,16 +40,6 @@ extern "C" INTERP_API ICorJitCompiler* getJit()
6440
return &g_CILInterp;
6541
}
6642

67-
static InterpManager g_Manager;
68-
extern "C" INTERP_API ICorInterpreter* getInterpreter()
69-
{
70-
if (!g_interpInitialized)
71-
{
72-
return nullptr;
73-
}
74-
return &g_Manager;
75-
}
76-
7743
//****************************************************************************
7844
CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd,
7945
CORINFO_METHOD_INFO* methodInfo,
@@ -95,33 +61,36 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd,
9561
return CORJIT_SKIPPED;
9662
}
9763

98-
InterpMethod *pMethod = InterpGetInterpMethod(methodInfo->ftn);
99-
if (!pMethod->compiled)
100-
{
101-
InterpCompiler compiler(compHnd, methodInfo);
102-
compiler.CompileMethod(pMethod);
103-
}
64+
InterpCompiler compiler(compHnd, methodInfo);
65+
InterpMethod *pMethod = compiler.CompileMethod();
66+
67+
int32_t IRCodeSize;
68+
int32_t *pIRCode = compiler.GetCode(&IRCodeSize);
10469

10570
// FIXME this shouldn't be here
10671
compHnd->setMethodAttribs(methodInfo->ftn, CORINFO_FLG_INTERPRETER);
10772

73+
uint32_t sizeOfCode = sizeof(InterpMethod*) + IRCodeSize * sizeof(int32_t);
74+
10875
// TODO: get rid of the need to allocate fake unwind info.
10976
compHnd->reserveUnwindInfo(false /* isFunclet */, false /* isColdCode */ , 8 /* unwindSize */);
11077
AllocMemArgs args;
111-
args.hotCodeSize = 16;
78+
args.hotCodeSize = sizeOfCode;
11279
args.coldCodeSize = 0;
11380
args.roDataSize = 0;
11481
args.xcptnsCount = 0;
11582
args.flag = CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN;
11683
compHnd->allocMem(&args);
117-
uint8_t *code = (uint8_t*)args.hotCodeBlockRW;
118-
*code++ = 1; // fake byte code
84+
85+
// We store first the InterpMethod pointer as the code header, followed by the actual code
86+
*(InterpMethod**)args.hotCodeBlockRW = pMethod;
87+
memcpy ((uint8_t*)args.hotCodeBlockRW + sizeof(InterpMethod*), pIRCode, IRCodeSize * sizeof(int32_t));
11988

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

12392
*entryAddress = (uint8_t*)args.hotCodeBlock;
124-
*nativeSizeOfCode = 1;
93+
*nativeSizeOfCode = sizeOfCode;
12594

12695
return CORJIT_OK;
12796
}
@@ -140,8 +109,3 @@ void CILInterp::getVersionIdentifier(GUID* versionIdentifier)
140109
void CILInterp::setTargetOS(CORINFO_OS os)
141110
{
142111
}
143-
144-
void* InterpManager::GetInterpMethod(CORINFO_METHOD_HANDLE methodHnd)
145-
{
146-
return InterpGetInterpMethod(methodHnd);
147-
}

src/coreclr/interpreter/eeinterp.h

-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,3 @@ class CILInterp : public ICorJitCompiler
1515
void getVersionIdentifier(GUID* versionIdentifier /* OUT */ );
1616
void setTargetOS(CORINFO_OS os);
1717
};
18-
19-
class InterpManager : public ICorInterpreter
20-
{
21-
void* GetInterpMethod(CORINFO_METHOD_HANDLE methodHnd);
22-
};

src/coreclr/interpreter/interpretershared.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,12 @@ typedef enum
2020
struct InterpMethod
2121
{
2222
CORINFO_METHOD_HANDLE methodHnd;
23-
int32_t *pCode;
2423
int32_t allocaSize;
2524

26-
volatile bool compiled;
27-
28-
InterpMethod()
25+
InterpMethod(CORINFO_METHOD_HANDLE methodHnd, int32_t allocaSize)
2926
{
30-
pCode = NULL;
31-
compiled = false;
27+
this->methodHnd = methodHnd;
28+
this->allocaSize = allocaSize;
3229
}
3330
};
3431

src/coreclr/vm/codeman.cpp

-21
Original file line numberDiff line numberDiff line change
@@ -1838,18 +1838,6 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName DEBUGARG(LPCWSTR pwzJitPath)
18381838
}
18391839
}
18401840

1841-
#ifdef FEATURE_INTERPRETER
1842-
void InitializeInterpreter(IN HINSTANCE phJit, OUT ICorInterpreter **pNewInterpreter)
1843-
{
1844-
typedef ICorInterpreter* (* pGetInterpreterFn)();
1845-
pGetInterpreterFn getInterpreterFn = (pGetInterpreterFn) GetProcAddress(phJit, "getInterpreter");
1846-
if (getInterpreterFn != NULL)
1847-
{
1848-
*pNewInterpreter = (*getInterpreterFn)();
1849-
}
1850-
}
1851-
#endif
1852-
18531841
#ifdef FEATURE_MERGE_JIT_AND_ENGINE
18541842
EXTERN_C void jitStartup(ICorJitHost* host);
18551843
EXTERN_C ICorJitCompiler* getJit();
@@ -1911,9 +1899,6 @@ BOOL EEJitManager::LoadJIT()
19111899
// This allows us to display load error messages for loading altjit.
19121900

19131901
ICorJitCompiler* newAltJitCompiler = NULL;
1914-
#ifdef FEATURE_INTERPRETER
1915-
ICorInterpreter* newInterpreter = NULL;
1916-
#endif
19171902

19181903
LPWSTR altJitConfig;
19191904
IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AltJit, &altJitConfig));
@@ -1985,9 +1970,6 @@ BOOL EEJitManager::LoadJIT()
19851970
}
19861971
g_JitLoadData.jld_id = JIT_LOAD_ALTJIT;
19871972
LoadAndInitializeJIT(altJitName DEBUGARG(altJitPath), &m_AltJITCompiler, &newAltJitCompiler, &g_JitLoadData, targetOs);
1988-
#ifdef FEATURE_INTERPRETER
1989-
InitializeInterpreter(m_AltJITCompiler, &newInterpreter);
1990-
#endif
19911973
}
19921974

19931975
#endif // ALLOW_SXS_JIT
@@ -1997,9 +1979,6 @@ BOOL EEJitManager::LoadJIT()
19971979
#ifdef ALLOW_SXS_JIT
19981980
m_AltJITRequired = (altJitConfig != NULL);
19991981
m_alternateJit = newAltJitCompiler;
2000-
#ifdef FEATURE_INTERPRETER
2001-
m_interpreter = newInterpreter;
2002-
#endif
20031982
#endif // ALLOW_SXS_JIT
20041983

20051984
m_jit = newJitCompiler;

src/coreclr/vm/codeman.h

-3
Original file line numberDiff line numberDiff line change
@@ -1988,9 +1988,6 @@ private :
19881988
#ifdef ALLOW_SXS_JIT
19891989
//put these at the end so that we don't mess up the offsets in the DAC.
19901990
ICorJitCompiler * m_alternateJit;
1991-
#ifdef FEATURE_INTERPRETER
1992-
ICorInterpreter * m_interpreter;
1993-
#endif
19941991
HINSTANCE m_AltJITCompiler;
19951992
bool m_AltJITRequired;
19961993
#endif //ALLOW_SXS_JIT

src/coreclr/vm/interpexec.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ void InterpExecMethod(InterpMethodContextFrame *pFrame, InterpThreadContext *pTh
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct StackVal
2424
struct InterpMethodContextFrame
2525
{
2626
InterpMethodContextFrame *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

+1-9
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
InterpMethodContextFrame 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)