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