| 1 | // |
| 2 | // Copyright (c) Microsoft. All rights reserved. |
| 3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| 4 | // |
| 5 | |
| 6 | #include "standardpch.h" |
| 7 | #include "spmiutil.h" |
| 8 | #include "icorjitcompiler.h" |
| 9 | #include "icorjitinfo.h" |
| 10 | #include "jithost.h" |
| 11 | #include "superpmi-shim-collector.h" |
| 12 | |
| 13 | #define fatMC // this is nice to have on so ildump works... |
| 14 | interceptor_IEEMM* current_IEEMM = nullptr; // we want this to live beyond the scope of a single compileMethodCall |
| 15 | |
| 16 | CorJitResult __stdcall interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ |
| 17 | struct CORINFO_METHOD_INFO* info, /* IN */ |
| 18 | unsigned /* code:CorJitFlag */ flags, /* IN */ |
| 19 | BYTE** nativeEntry, /* OUT */ |
| 20 | ULONG* nativeSizeOfCode /* OUT */ |
| 21 | ) |
| 22 | { |
| 23 | interceptor_ICJI our_ICorJitInfo; |
| 24 | our_ICorJitInfo.original_ICorJitInfo = comp; |
| 25 | |
| 26 | if (current_IEEMM == nullptr) |
| 27 | current_IEEMM = new interceptor_IEEMM(); |
| 28 | |
| 29 | auto* mc = new MethodContext(); |
| 30 | if (g_ourJitHost != nullptr) |
| 31 | { |
| 32 | g_ourJitHost->setMethodContext(mc); |
| 33 | } |
| 34 | |
| 35 | our_ICorJitInfo.mc = mc; |
| 36 | our_ICorJitInfo.mc->cr->recProcessName(GetCommandLineA()); |
| 37 | |
| 38 | our_ICorJitInfo.mc->recCompileMethod(info, flags); |
| 39 | |
| 40 | // force some extra data into our tables.. |
| 41 | // data probably not needed with RyuJIT, but needed in 4.5 and 4.5.1 to help with catching cached values |
| 42 | our_ICorJitInfo.getBuiltinClass(CLASSID_SYSTEM_OBJECT); |
| 43 | our_ICorJitInfo.getBuiltinClass(CLASSID_TYPED_BYREF); |
| 44 | our_ICorJitInfo.getBuiltinClass(CLASSID_TYPE_HANDLE); |
| 45 | our_ICorJitInfo.getBuiltinClass(CLASSID_FIELD_HANDLE); |
| 46 | our_ICorJitInfo.getBuiltinClass(CLASSID_METHOD_HANDLE); |
| 47 | our_ICorJitInfo.getBuiltinClass(CLASSID_STRING); |
| 48 | our_ICorJitInfo.getBuiltinClass(CLASSID_ARGUMENT_HANDLE); |
| 49 | our_ICorJitInfo.getBuiltinClass(CLASSID_RUNTIME_TYPE); |
| 50 | |
| 51 | #ifdef fatMC |
| 52 | // to build up a fat mc |
| 53 | CORINFO_CLASS_HANDLE ourClass = our_ICorJitInfo.getMethodClass(info->ftn); |
| 54 | our_ICorJitInfo.getClassAttribs(ourClass); |
| 55 | our_ICorJitInfo.getClassName(ourClass); |
| 56 | our_ICorJitInfo.isValueClass(ourClass); |
| 57 | our_ICorJitInfo.asCorInfoType(ourClass); |
| 58 | #endif |
| 59 | |
| 60 | // Record data from the global context, if any |
| 61 | if (g_globalContext != nullptr) |
| 62 | { |
| 63 | our_ICorJitInfo.mc->recGlobalContext(*g_globalContext); |
| 64 | } |
| 65 | |
| 66 | CorJitResult temp = |
| 67 | original_ICorJitCompiler->compileMethod(&our_ICorJitInfo, info, flags, nativeEntry, nativeSizeOfCode); |
| 68 | |
| 69 | if (temp == CORJIT_OK) |
| 70 | { |
| 71 | // capture the results of compilation |
| 72 | our_ICorJitInfo.mc->cr->recCompileMethod(nativeEntry, nativeSizeOfCode, temp); |
| 73 | |
| 74 | our_ICorJitInfo.mc->cr->recAllocMemCapture(); |
| 75 | our_ICorJitInfo.mc->cr->recAllocGCInfoCapture(); |
| 76 | our_ICorJitInfo.mc->saveToFile(hFile); |
| 77 | } |
| 78 | |
| 79 | delete mc; |
| 80 | |
| 81 | if (g_ourJitHost != nullptr) |
| 82 | { |
| 83 | g_ourJitHost->setMethodContext(g_globalContext); |
| 84 | } |
| 85 | |
| 86 | return temp; |
| 87 | } |
| 88 | |
| 89 | void interceptor_ICJC::clearCache() |
| 90 | { |
| 91 | original_ICorJitCompiler->clearCache(); |
| 92 | } |
| 93 | |
| 94 | BOOL interceptor_ICJC::isCacheCleanupRequired() |
| 95 | { |
| 96 | return original_ICorJitCompiler->isCacheCleanupRequired(); |
| 97 | } |
| 98 | |
| 99 | void interceptor_ICJC::ProcessShutdownWork(ICorStaticInfo* info) |
| 100 | { |
| 101 | original_ICorJitCompiler->ProcessShutdownWork(info); |
| 102 | } |
| 103 | |
| 104 | void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */) |
| 105 | { |
| 106 | original_ICorJitCompiler->getVersionIdentifier(versionIdentifier); |
| 107 | } |
| 108 | |
| 109 | unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) |
| 110 | { |
| 111 | return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); |
| 112 | } |
| 113 | |
| 114 | void interceptor_ICJC::setRealJit(ICorJitCompiler* realJitCompiler) |
| 115 | { |
| 116 | original_ICorJitCompiler->setRealJit(realJitCompiler); |
| 117 | } |
| 118 | |