1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8
9 #include "dllexport.h"
10 #include "jitinterface.h"
11
12 typedef struct _GUID {
13 unsigned int Data1;
14 unsigned short Data2;
15 unsigned short Data3;
16 unsigned char Data4[8];
17 } GUID;
18
19 class CORJIT_FLAGS
20 {
21 public:
CORJIT_FLAGS(const CORJIT_FLAGS & other)22 CORJIT_FLAGS(const CORJIT_FLAGS& other)
23 {
24 corJitFlags = other.corJitFlags;
25 }
26 private:
27 unsigned __int64 corJitFlags;
28 };
29
30 static const GUID JITEEVersionIdentifier = { /* a6860f80-01cb-4f87-82c2-a8e5a744f2fa */
31 0xa6860f80,
32 0x01cb,
33 0x4f87,
34 {0x82, 0xc2, 0xa8, 0xe5, 0xa7, 0x44, 0xf2, 0xfa}
35 };
36
37 class Jit
38 {
39 public:
40 virtual int __stdcall compileMethod(
41 void* compHnd,
42 void* methodInfo,
43 unsigned flags,
44 void* entryAddress,
45 void* nativeSizeOfCode) = 0;
46
47 virtual void clearCache() = 0;
48 virtual unsigned isCacheCleanupRequired() = 0;
49 virtual void ProcessShutdownWork(void* info) = 0;
50
51 // The EE asks the JIT for a "version identifier". This represents the version of the JIT/EE interface.
52 // If the JIT doesn't implement the same JIT/EE interface expected by the EE (because the JIT doesn't
53 // return the version identifier that the EE expects), then the EE fails to load the JIT.
54 //
55 virtual void getVersionIdentifier(GUID* versionIdentifier) = 0;
56
57 // When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of
58 // SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD
59 // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation).
60 virtual unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) = 0;
61 };
62
JitCompileMethod(CorInfoException ** ppException,Jit * pJit,void * thisHandle,void ** callbacks,void * methodInfo,unsigned flags,void * entryAddress,void * nativeSizeOfCode)63 DLL_EXPORT int JitCompileMethod(
64 CorInfoException **ppException,
65 Jit * pJit,
66 void * thisHandle,
67 void ** callbacks,
68 void* methodInfo,
69 unsigned flags,
70 void* entryAddress,
71 void* nativeSizeOfCode)
72 {
73 *ppException = nullptr;
74
75 GUID versionId;
76 pJit->getVersionIdentifier(&versionId);
77 if (memcmp(&versionId, &JITEEVersionIdentifier, sizeof(GUID)) != 0)
78 {
79 // JIT and the compiler disagree on how the interface looks like.
80 // Either get a matching version of the JIT from the CoreCLR repo or update the interface
81 // on the CoreRT side. Under no circumstances should you comment this line out.
82 return 1;
83 }
84
85 try
86 {
87 JitInterfaceWrapper jitInterfaceWrapper(thisHandle, callbacks);
88 return pJit->compileMethod(&jitInterfaceWrapper, methodInfo, flags, entryAddress, nativeSizeOfCode);
89 }
90 catch (CorInfoException *pException)
91 {
92 *ppException = pException;
93 }
94
95 return 1;
96 }
97
GetMaxIntrinsicSIMDVectorLength(Jit * pJit,CORJIT_FLAGS * flags)98 DLL_EXPORT unsigned GetMaxIntrinsicSIMDVectorLength(
99 Jit * pJit,
100 CORJIT_FLAGS * flags)
101 {
102 return pJit->getMaxIntrinsicSIMDVectorLength(*flags);
103 }
104