Skip to content

触发JIT

Posted on:October 16, 2023 at 04:06 AM

一些环境变量

存在jit/jitconfigvalue.h中 COMPlus_JitDump COMPlus_JitFunctionTrace COMPlus_ReasyToRun COMPLus_LogEnable

JIT中的一些数据结构

    MethodTable (vm\methodtable.h)
			表示各个普通的独立类型, Object指向的类型信息
			泛型类型实例化一个就会生成一个新的MethodTable
	TypeDesc (vm\typedesc.h)
			表示特殊类型, 包括
				TypeVarTypeDesc: 泛型类型, 例如List<T>中的T, 不共享
				FnPtrTypeDesc: 函数指针, C#不支持, Managed c++
				ParamTypeDesc: byref或者指针类型, byref是使用ref或者out传递的类型, 指针类型Unsafe c#或者Managed c++
				ArrayTypeDesc: 数组类型
	TypeHandle (vm\typehandle.h)
			保存指向MethodTable或者TypeDesc的指针
			保存TypeDesc时指针值会|=2, 用于判断指针的类型
	CorElementType (inc\corhdr.h)
			元素类型的枚举,有ELEMENT_TYPE_BOOLEAN ELEMENT_TYPE_CHAR等
	EEClass (vm\class.h)
			EE使用的类型信息, 包含是否抽象或者是否接口等Cold Data(运行时不需要, 只在加载类型和反射和JIT时需要的数据)
			一般和MethodTable是一对一的关系,除非MethodTable是泛型的实例化
			多个泛型的实例化的MethodTable会共享一个EEClass, 而EEClass.GetMethodTable会返回Canonical MT
	MethodDesc (vm\method.hpp)
			函数信息, 由EEClass引用, 保存在MDChunks中
	FieldDesc (vm\field.hpp)
			字段信息, 由EEClass引用

第一个函数是怎么被JIT编译的

第一个函数是如何被JIT编译的
corerun.cpp
main
coreruncommon.cpp
ExecuteManagedAssembly
unixinterface.cpp
coreclr::initialize
return coreclr_initialize
dlls\mscoree\unixinterface.cpp
CorHost2::CreateAppDomainWithManager
hr = host->CreateAppDomainWithManager
vm\corhost.cpp
CorHost2::CreateAppDomain
\_gc.setupInfo=prepareDataForSetup.Call_RetOBJECTREF(args);
vm\callhelpers.h
MDCALLDEF_REFTYPE( Call, FALSE, \_RetOBJECTREF, Object\*, OBJECTREF)
vm\callhelpers.cpp
MethodDescCallSite::CallTargetWorker
CallDescrWorkerWithHandler(&callDescrData);
vm\callhelpers.cpp
CallDescrWorkerWithHandler
CallDescrWorker(pCallDescrData);
vm\amd64\calldescrworkeramd64.S
CallDescrWorkerInternal
vm\amd64\theprestubamd64.S
ThePreStub
vm\prestub.cpp
PreStubWorker
pbRetVal = pMD->DoPrestub(pDispatchingMT);
vm\prestub.cpp
MethodDesc::DoPrestub
pStub = MakeUnboxingStubWorker(this);
vm\prestub.cpp
MakeUnboxingStubWorker
pstub = CreateUnboxingILStubForSharedGenericValueTypeMethods(pUnboxedMD);
vm\prestub.cpp
CreateUnboxingILStubForSharedGenericValueTypeMethods
RETURN Stub::NewStub(JitILStub(pStubMD));
vm\dllimport.cpp
JitILStub
pCode = pStubMD->MakeJitWorker(NULL, dwFlags, 0);
vm\prestub.cpp
线程安全的通过JIT编译函数,如果多个线程同时编译会返回同一份编译后的代码
MethodDesc::MakeJitWorker
pCode = UnsafeJitFunction(this, ILHeader, flags, flags2, &sizeOfCode);
vm\jitinterface.cpp
非线程安全的通过JIT编译函数
UnsafeJitFunction
res = CallCompileMethodWithSEHWrapper(jitMgr
vm\jitinterface.cpp
CallCompileMethodWithSEHWrapper
pParam->res = invokeCompileMethod
vm\jitinterface.cpp
invokeCompileMethod
CorJitResult ret = invokeCompileMethodHelper
vm\jitinterface.cpp
invokeCompileMethodHelper
ret = jitMgr->m_jit->compileMethod(comp, ...)
jit\ee_il_dll.cpp
CILJit::compileMethod
result = jitNativeCode(methodHandle)
jit\compiler.cpp
jitNativeCode
pParam->pComp->compCompile(pParam->methodHnd, pParam->classPtr, pParam->compHnd, pParam->methodInfo,
jit\compiler.cpp
Compiler::compCompile

Main函数是怎样被编译的

   /jit/corerun.cpp
   		main
   /jit/coreruncommon.cpp
   		ExecutemanagedAssembly
   /jit/corhost.cpp
   		coreclr_execute_asssembly
   /jit/assembly.cpp
   		CorHost2:ExecuteAssembly
   /jit/assembly.cpp
   		ExecuteMainMethod
   /jit/assembly.cpp
   		RunMain

JIT Stub的调用和替换流程

jit前 call => Fixup Precode => Fixup Precode Chunk => The PreStub => PreStub Worker => ...
jit后 call => Fixup Precode => Compile Result