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 | // ZapReadyToRun.cpp |
6 | // |
7 | |
8 | // |
9 | // Zapping of ready-to-run specific structures |
10 | // |
11 | // ====================================================================================== |
12 | |
13 | #include "common.h" |
14 | |
15 | #include "zapreadytorun.h" |
16 | |
17 | #include "zapimport.h" |
18 | |
19 | #include "nativeformatwriter.h" |
20 | |
21 | #include "nibblestream.h" |
22 | |
23 | using namespace NativeFormat; |
24 | |
25 | void ZapReadyToRunHeader::(ZapWriter * pZapWriter) |
26 | { |
27 | ZapImage * pImage = ZapImage::GetImage(pZapWriter); |
28 | |
29 | READYTORUN_HEADER ; |
30 | |
31 | ZeroMemory(&readyToRunHeader, sizeof(readyToRunHeader)); |
32 | |
33 | readyToRunHeader.Signature = READYTORUN_SIGNATURE; |
34 | readyToRunHeader.MajorVersion = READYTORUN_MAJOR_VERSION; |
35 | readyToRunHeader.MinorVersion = READYTORUN_MINOR_VERSION; |
36 | |
37 | if (pImage->m_ModuleDecoder.IsPlatformNeutral()) |
38 | readyToRunHeader.Flags |= READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE; |
39 | |
40 | // If all types loaded succesfully, set a flag to skip type loading sanity checks at runtime |
41 | if (pImage->GetCompileInfo()->AreAllClassesFullyLoaded(pImage->GetModuleHandle())) |
42 | readyToRunHeader.Flags |= READYTORUN_FLAG_SKIP_TYPE_VALIDATION; |
43 | |
44 | readyToRunHeader.NumberOfSections = m_Sections.GetCount(); |
45 | |
46 | pZapWriter->Write(&readyToRunHeader, sizeof(readyToRunHeader)); |
47 | |
48 | qsort(&m_Sections[0], m_Sections.GetCount(), sizeof(Section), SectionCmp); |
49 | |
50 | for(COUNT_T i = 0; i < m_Sections.GetCount(); i++) |
51 | { |
52 | READYTORUN_SECTION section; |
53 | section.Type = m_Sections[i].type; |
54 | ZapWriter::SetDirectoryData(§ion.Section, m_Sections[i].pSection); |
55 | pZapWriter->Write(§ion, sizeof(section)); |
56 | } |
57 | } |
58 | |
59 | class BlobVertex : public NativeFormat::Vertex |
60 | { |
61 | int m_cbSize; |
62 | |
63 | public: |
64 | BlobVertex(int cbSize) |
65 | : m_cbSize(cbSize) |
66 | { |
67 | } |
68 | |
69 | void * GetData() |
70 | { |
71 | return this + 1; |
72 | } |
73 | |
74 | int GetSize() |
75 | { |
76 | return m_cbSize; |
77 | } |
78 | |
79 | virtual void Save(NativeWriter * pWriter) |
80 | { |
81 | byte * pData = (byte *)GetData(); |
82 | for (int i = 0; i < m_cbSize; i++) |
83 | pWriter->WriteByte(pData[i]); |
84 | } |
85 | }; |
86 | |
87 | class BlobVertexKey |
88 | { |
89 | PVOID _pData; |
90 | int _cbSize; |
91 | |
92 | public: |
93 | BlobVertexKey(PVOID pData, int cbSize) |
94 | : _pData(pData), _cbSize(cbSize) |
95 | { |
96 | } |
97 | |
98 | void * GetData() |
99 | { |
100 | return _pData; |
101 | } |
102 | |
103 | int GetSize() |
104 | { |
105 | return _cbSize; |
106 | } |
107 | }; |
108 | |
109 | class BlobVertexSHashTraits : public DefaultSHashTraits<BlobVertex *> |
110 | { |
111 | public: |
112 | typedef BlobVertexKey key_t; |
113 | |
114 | static key_t GetKey(element_t e) |
115 | { |
116 | LIMITED_METHOD_CONTRACT; |
117 | return key_t(e->GetData(), e->GetSize()); |
118 | } |
119 | static BOOL Equals(key_t k1, key_t k2) |
120 | { |
121 | LIMITED_METHOD_CONTRACT; |
122 | if (k1.GetSize() != k2.GetSize()) |
123 | return FALSE; |
124 | return memcmp(k1.GetData(), k2.GetData(), k1.GetSize()) == 0; |
125 | } |
126 | static count_t Hash(key_t k) |
127 | { |
128 | LIMITED_METHOD_CONTRACT; |
129 | count_t hash = 5381 + (count_t)(k.GetSize() << 7); |
130 | |
131 | PBYTE pbData = (PBYTE)k.GetData(); |
132 | PBYTE pbDataEnd = pbData + k.GetSize(); |
133 | |
134 | for (/**/ ; pbData < pbDataEnd; pbData++) |
135 | { |
136 | hash = ((hash << 5) + hash) ^ *pbData; |
137 | } |
138 | return hash; |
139 | } |
140 | }; |
141 | |
142 | |
143 | class EntryPointVertex : public NativeFormat::Vertex |
144 | { |
145 | DWORD m_methodIndex; |
146 | BlobVertex * m_pFixups; |
147 | |
148 | public: |
149 | EntryPointVertex(DWORD methodIndex, BlobVertex * pFixups) |
150 | : m_methodIndex(methodIndex), m_pFixups(pFixups) |
151 | { |
152 | } |
153 | |
154 | virtual void Save(NativeWriter * pWriter) |
155 | { |
156 | if (m_pFixups != NULL) |
157 | { |
158 | int existingOffset = pWriter->GetCurrentOffset(m_pFixups); |
159 | if (existingOffset != -1) |
160 | { |
161 | pWriter->WriteUnsigned((m_methodIndex << 2) | 3); |
162 | pWriter->WriteUnsigned(pWriter->GetCurrentOffset() - existingOffset); |
163 | } |
164 | else |
165 | { |
166 | pWriter->WriteUnsigned((m_methodIndex << 2) | 1); |
167 | pWriter->SetCurrentOffset(m_pFixups); |
168 | m_pFixups->Save(pWriter); |
169 | } |
170 | } |
171 | else |
172 | { |
173 | pWriter->WriteUnsigned(m_methodIndex << 1); |
174 | } |
175 | } |
176 | }; |
177 | |
178 | class EntryPointWithBlobVertex : public EntryPointVertex |
179 | { |
180 | BlobVertex * m_pBlob; |
181 | |
182 | public: |
183 | EntryPointWithBlobVertex(DWORD methodIndex, BlobVertex * pFixups, BlobVertex * pBlob) |
184 | : EntryPointVertex(methodIndex, pFixups), m_pBlob(pBlob) |
185 | { |
186 | } |
187 | |
188 | virtual void Save(NativeWriter * pWriter) |
189 | { |
190 | m_pBlob->Save(pWriter); |
191 | EntryPointVertex::Save(pWriter); |
192 | } |
193 | }; |
194 | |
195 | void ZapImage::OutputEntrypointsTableForReadyToRun() |
196 | { |
197 | BeginRegion(CORINFO_REGION_COLD); |
198 | |
199 | NativeWriter arrayWriter; |
200 | NativeWriter hashtableWriter; |
201 | |
202 | NativeSection * pArraySection = arrayWriter.NewSection(); |
203 | NativeSection * pHashtableSection = hashtableWriter.NewSection(); |
204 | |
205 | VertexArray vertexArray(pArraySection); |
206 | pArraySection->Place(&vertexArray); |
207 | VertexHashtable vertexHashtable; |
208 | pHashtableSection->Place(&vertexHashtable); |
209 | |
210 | bool fEmpty = true; |
211 | |
212 | SHash< NoRemoveSHashTraits < BlobVertexSHashTraits > > fixupBlobs; |
213 | |
214 | COUNT_T nCount = m_MethodCompilationOrder.GetCount(); |
215 | for (COUNT_T i = 0; i < nCount; i++) |
216 | { |
217 | ZapMethodHeader * pMethod = m_MethodCompilationOrder[i]; |
218 | |
219 | mdMethodDef token = GetJitInfo()->getMethodDefFromMethod(pMethod->GetHandle()); |
220 | CORINFO_SIG_INFO sig; |
221 | GetJitInfo()->getMethodSig(pMethod->GetHandle(), &sig); |
222 | |
223 | int rid = RidFromToken(token); |
224 | _ASSERTE(rid != 0); |
225 | |
226 | BlobVertex * pFixupBlob = NULL; |
227 | |
228 | if (pMethod->m_pFixupList != NULL) |
229 | { |
230 | NibbleWriter writer; |
231 | m_pImportTable->PlaceFixups(pMethod->m_pFixupList, writer); |
232 | |
233 | DWORD cbBlob; |
234 | PVOID pBlob = writer.GetBlob(&cbBlob); |
235 | |
236 | pFixupBlob = fixupBlobs.Lookup(BlobVertexKey(pBlob, cbBlob)); |
237 | if (pFixupBlob == NULL) |
238 | { |
239 | void * pMemory = new (GetHeap()) BYTE[sizeof(BlobVertex) + cbBlob]; |
240 | pFixupBlob = new (pMemory) BlobVertex(cbBlob); |
241 | memcpy(pFixupBlob->GetData(), pBlob, cbBlob); |
242 | |
243 | fixupBlobs.Add(pFixupBlob); |
244 | } |
245 | } |
246 | |
247 | if (sig.sigInst.classInstCount > 0 || sig.sigInst.methInstCount > 0) |
248 | { |
249 | CORINFO_MODULE_HANDLE module = GetJitInfo()->getClassModule(pMethod->GetClassHandle()); |
250 | _ASSERTE(GetCompileInfo()->IsInCurrentVersionBubble(module)); |
251 | SigBuilder sigBuilder; |
252 | CORINFO_RESOLVED_TOKEN resolvedToken = {}; |
253 | resolvedToken.tokenScope = module; |
254 | resolvedToken.token = token; |
255 | resolvedToken.hClass = pMethod->GetClassHandle(); |
256 | resolvedToken.hMethod = pMethod->GetHandle(); |
257 | GetCompileInfo()->EncodeMethod(module, pMethod->GetHandle(), &sigBuilder, NULL, NULL, &resolvedToken); |
258 | |
259 | DWORD cbBlob; |
260 | PVOID pBlob = sigBuilder.GetSignature(&cbBlob); |
261 | void * pMemory = new (GetHeap()) BYTE[sizeof(BlobVertex) + cbBlob]; |
262 | BlobVertex * pSigBlob = new (pMemory) BlobVertex(cbBlob); |
263 | memcpy(pSigBlob->GetData(), pBlob, cbBlob); |
264 | |
265 | int dwHash = GetCompileInfo()->GetVersionResilientMethodHashCode(pMethod->GetHandle()); |
266 | vertexHashtable.Append(dwHash, pHashtableSection->Place(new (GetHeap()) EntryPointWithBlobVertex(pMethod->GetMethodIndex(), pFixupBlob, pSigBlob))); |
267 | } |
268 | else |
269 | { |
270 | vertexArray.Set(rid - 1, new (GetHeap()) EntryPointVertex(pMethod->GetMethodIndex(), pFixupBlob)); |
271 | } |
272 | |
273 | fEmpty = false; |
274 | } |
275 | |
276 | if (fEmpty) |
277 | return; |
278 | |
279 | vertexArray.ExpandLayout(); |
280 | |
281 | vector<byte>& arrayBlob = arrayWriter.Save(); |
282 | ZapNode * pArrayBlob = ZapBlob::NewBlob(this, &arrayBlob[0], arrayBlob.size()); |
283 | m_pCodeMethodDescsSection->Place(pArrayBlob); |
284 | |
285 | vector<byte>& hashtableBlob = hashtableWriter.Save(); |
286 | ZapNode * pHashtableBlob = ZapBlob::NewBlob(this, &hashtableBlob[0], hashtableBlob.size()); |
287 | m_pCodeMethodDescsSection->Place(pHashtableBlob); |
288 | |
289 | ZapReadyToRunHeader * = GetReadyToRunHeader(); |
290 | pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_METHODDEF_ENTRYPOINTS, pArrayBlob); |
291 | pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS, pHashtableBlob); |
292 | pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_RUNTIME_FUNCTIONS, m_pRuntimeFunctionSection); |
293 | |
294 | if (m_pLazyMethodCallHelperSection->GetNodeCount() != 0) |
295 | pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_DELAYLOAD_METHODCALL_THUNKS, m_pLazyMethodCallHelperSection); |
296 | |
297 | if (m_pExceptionInfoLookupTable->GetSize() != 0) |
298 | pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_EXCEPTION_INFO, m_pExceptionInfoLookupTable); |
299 | |
300 | EndRegion(CORINFO_REGION_COLD); |
301 | } |
302 | |
303 | class DebugInfoVertex : public NativeFormat::Vertex |
304 | { |
305 | BlobVertex * m_pDebugInfo; |
306 | |
307 | public: |
308 | DebugInfoVertex(BlobVertex * pDebugInfo) |
309 | : m_pDebugInfo(pDebugInfo) |
310 | { |
311 | } |
312 | |
313 | virtual void Save(NativeWriter * pWriter) |
314 | { |
315 | int existingOffset = pWriter->GetCurrentOffset(m_pDebugInfo); |
316 | if (existingOffset != -1) |
317 | { |
318 | _ASSERTE(pWriter->GetCurrentOffset() > existingOffset); |
319 | pWriter->WriteUnsigned(pWriter->GetCurrentOffset() - existingOffset); |
320 | } |
321 | else |
322 | { |
323 | pWriter->WriteUnsigned(0); |
324 | pWriter->SetCurrentOffset(m_pDebugInfo); |
325 | m_pDebugInfo->Save(pWriter); |
326 | } |
327 | } |
328 | }; |
329 | |
330 | void ZapImage::OutputDebugInfoForReadyToRun() |
331 | { |
332 | NativeWriter writer; |
333 | |
334 | NativeSection * pSection = writer.NewSection(); |
335 | |
336 | VertexArray vertexArray(pSection); |
337 | pSection->Place(&vertexArray); |
338 | |
339 | bool fEmpty = true; |
340 | |
341 | SHash< NoRemoveSHashTraits < BlobVertexSHashTraits > > debugInfoBlobs; |
342 | |
343 | COUNT_T nCount = m_MethodCompilationOrder.GetCount(); |
344 | for (COUNT_T i = 0; i < nCount; i++) |
345 | { |
346 | ZapMethodHeader * pMethod = m_MethodCompilationOrder[i]; |
347 | |
348 | ZapBlob * pDebugInfo = pMethod->GetDebugInfo(); |
349 | if (pDebugInfo == NULL) |
350 | continue; |
351 | |
352 | DWORD cbBlob = pDebugInfo->GetBlobSize(); |
353 | PVOID pBlob = pDebugInfo->GetData(); |
354 | |
355 | BlobVertex * pDebugInfoBlob = debugInfoBlobs.Lookup(BlobVertexKey(pBlob, cbBlob)); |
356 | if (pDebugInfoBlob == NULL) |
357 | { |
358 | void * pMemory = new (GetHeap()) BYTE[sizeof(BlobVertex) + cbBlob]; |
359 | pDebugInfoBlob = new (pMemory) BlobVertex(cbBlob); |
360 | memcpy(pDebugInfoBlob->GetData(), pBlob, cbBlob); |
361 | |
362 | debugInfoBlobs.Add(pDebugInfoBlob); |
363 | } |
364 | |
365 | vertexArray.Set(pMethod->GetMethodIndex(), new (GetHeap()) DebugInfoVertex(pDebugInfoBlob)); |
366 | |
367 | fEmpty = false; |
368 | } |
369 | |
370 | if (fEmpty) |
371 | return; |
372 | |
373 | vertexArray.ExpandLayout(); |
374 | |
375 | vector<byte>& blob = writer.Save(); |
376 | |
377 | ZapNode * pBlob = ZapBlob::NewBlob(this, &blob[0], blob.size()); |
378 | m_pDebugSection->Place(pBlob); |
379 | |
380 | GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_DEBUG_INFO, pBlob); |
381 | } |
382 | |
383 | void ZapImage::OutputInliningTableForReadyToRun() |
384 | { |
385 | SBuffer serializedInlineTrackingBuffer; |
386 | m_pPreloader->GetSerializedInlineTrackingMap(&serializedInlineTrackingBuffer); |
387 | ZapNode * pBlob = ZapBlob::NewAlignedBlob(this, (PVOID)(const BYTE*) serializedInlineTrackingBuffer, serializedInlineTrackingBuffer.GetSize(), 4); |
388 | m_pDebugSection->Place(pBlob); |
389 | GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_INLINING_INFO, pBlob); |
390 | } |
391 | |
392 | void ZapImage::OutputProfileDataForReadyToRun() |
393 | { |
394 | if (m_pInstrumentSection != nullptr) |
395 | { |
396 | GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_PROFILEDATA_INFO, m_pInstrumentSection); |
397 | } |
398 | } |
399 | |
400 | void ZapImage::OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport) |
401 | { |
402 | NativeWriter writer; |
403 | VertexHashtable typesHashtable; |
404 | |
405 | NativeSection * pSection = writer.NewSection(); |
406 | pSection->Place(&typesHashtable); |
407 | |
408 | // Note on duplicate types with same name: there is not need to perform that check when building |
409 | // the hashtable. If such types were encountered, the R2R compilation would fail before reaching here. |
410 | |
411 | // Save the TypeDefs to the hashtable |
412 | { |
413 | HENUMInternalHolder hEnum(pMDImport); |
414 | hEnum.EnumAllInit(mdtTypeDef); |
415 | |
416 | mdToken mdTypeToken; |
417 | while (pMDImport->EnumNext(&hEnum, &mdTypeToken)) |
418 | { |
419 | mdTypeDef mdCurrentToken = mdTypeToken; |
420 | DWORD dwHash = GetCompileInfo()->GetVersionResilientTypeHashCode(GetModuleHandle(), mdTypeToken); |
421 | |
422 | typesHashtable.Append(dwHash, pSection->Place(new UnsignedConstant(RidFromToken(mdTypeToken) << 1))); |
423 | } |
424 | } |
425 | |
426 | // Save the ExportedTypes to the hashtable |
427 | { |
428 | HENUMInternalHolder hEnum(pMDImport); |
429 | hEnum.EnumInit(mdtExportedType, mdTokenNil); |
430 | |
431 | mdToken mdTypeToken; |
432 | while (pMDImport->EnumNext(&hEnum, &mdTypeToken)) |
433 | { |
434 | DWORD dwHash = GetCompileInfo()->GetVersionResilientTypeHashCode(GetModuleHandle(), mdTypeToken); |
435 | |
436 | typesHashtable.Append(dwHash, pSection->Place(new UnsignedConstant((RidFromToken(mdTypeToken) << 1) | 1))); |
437 | } |
438 | } |
439 | |
440 | vector<byte>& blob = writer.Save(); |
441 | |
442 | ZapNode * pBlob = ZapBlob::NewBlob(this, &blob[0], blob.size()); |
443 | _ASSERTE(m_pAvailableTypesSection); |
444 | m_pAvailableTypesSection->Place(pBlob); |
445 | |
446 | GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_AVAILABLE_TYPES, pBlob); |
447 | } |
448 | |
449 | |
450 | // |
451 | // Verify that data structures and flags shared between NGen and ReadyToRun are in sync |
452 | // |
453 | |
454 | // |
455 | // READYTORUN_IMPORT_SECTION |
456 | // |
457 | static_assert_no_msg(sizeof(READYTORUN_IMPORT_SECTION) == sizeof(CORCOMPILE_IMPORT_SECTION)); |
458 | |
459 | static_assert_no_msg((int)READYTORUN_IMPORT_SECTION_TYPE_UNKNOWN == (int)CORCOMPILE_IMPORT_TYPE_UNKNOWN); |
460 | |
461 | static_assert_no_msg((int)READYTORUN_IMPORT_SECTION_FLAGS_EAGER == (int)CORCOMPILE_IMPORT_FLAGS_EAGER); |
462 | |
463 | // |
464 | // READYTORUN_METHOD_SIG |
465 | // |
466 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_UnboxingStub == (int)ENCODE_METHOD_SIG_UnboxingStub); |
467 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_InstantiatingStub == (int)ENCODE_METHOD_SIG_InstantiatingStub); |
468 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_MethodInstantiation == (int)ENCODE_METHOD_SIG_MethodInstantiation); |
469 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_SlotInsteadOfToken == (int)ENCODE_METHOD_SIG_SlotInsteadOfToken); |
470 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_MemberRefToken == (int)ENCODE_METHOD_SIG_MemberRefToken); |
471 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_Constrained == (int)ENCODE_METHOD_SIG_Constrained); |
472 | static_assert_no_msg((int)READYTORUN_METHOD_SIG_OwnerType == (int)ENCODE_METHOD_SIG_OwnerType); |
473 | |
474 | // |
475 | // READYTORUN_FIELD_SIG |
476 | // |
477 | static_assert_no_msg((int)READYTORUN_FIELD_SIG_IndexInsteadOfToken == (int)ENCODE_FIELD_SIG_IndexInsteadOfToken); |
478 | static_assert_no_msg((int)READYTORUN_FIELD_SIG_MemberRefToken == (int)ENCODE_FIELD_SIG_MemberRefToken); |
479 | static_assert_no_msg((int)READYTORUN_FIELD_SIG_OwnerType == (int)ENCODE_FIELD_SIG_OwnerType); |
480 | |
481 | // |
482 | // READYTORUN_FIXUP |
483 | // |
484 | static_assert_no_msg((int)READYTORUN_FIXUP_ThisObjDictionaryLookup == (int)ENCODE_DICTIONARY_LOOKUP_THISOBJ); |
485 | static_assert_no_msg((int)READYTORUN_FIXUP_TypeDictionaryLookup == (int)ENCODE_DICTIONARY_LOOKUP_TYPE); |
486 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodDictionaryLookup == (int)ENCODE_DICTIONARY_LOOKUP_METHOD); |
487 | |
488 | static_assert_no_msg((int)READYTORUN_FIXUP_TypeHandle == (int)ENCODE_TYPE_HANDLE); |
489 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodHandle == (int)ENCODE_METHOD_HANDLE); |
490 | static_assert_no_msg((int)READYTORUN_FIXUP_FieldHandle == (int)ENCODE_FIELD_HANDLE); |
491 | |
492 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry == (int)ENCODE_METHOD_ENTRY); |
493 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry_DefToken == (int)ENCODE_METHOD_ENTRY_DEF_TOKEN); |
494 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry_RefToken == (int)ENCODE_METHOD_ENTRY_REF_TOKEN); |
495 | |
496 | static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry == (int)ENCODE_VIRTUAL_ENTRY); |
497 | static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_DefToken == (int)ENCODE_VIRTUAL_ENTRY_DEF_TOKEN); |
498 | static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_RefToken == (int)ENCODE_VIRTUAL_ENTRY_REF_TOKEN); |
499 | static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_Slot == (int)ENCODE_VIRTUAL_ENTRY_SLOT); |
500 | |
501 | static_assert_no_msg((int)READYTORUN_FIXUP_Helper == (int)ENCODE_READYTORUN_HELPER); |
502 | static_assert_no_msg((int)READYTORUN_FIXUP_StringHandle == (int)ENCODE_STRING_HANDLE); |
503 | |
504 | static_assert_no_msg((int)READYTORUN_FIXUP_NewObject == (int)ENCODE_NEW_HELPER); |
505 | static_assert_no_msg((int)READYTORUN_FIXUP_NewArray == (int)ENCODE_NEW_ARRAY_HELPER); |
506 | |
507 | static_assert_no_msg((int)READYTORUN_FIXUP_IsInstanceOf == (int)ENCODE_ISINSTANCEOF_HELPER); |
508 | static_assert_no_msg((int)READYTORUN_FIXUP_ChkCast == (int)ENCODE_CHKCAST_HELPER); |
509 | |
510 | static_assert_no_msg((int)READYTORUN_FIXUP_FieldAddress == (int)ENCODE_FIELD_ADDRESS); |
511 | static_assert_no_msg((int)READYTORUN_FIXUP_CctorTrigger == (int)ENCODE_CCTOR_TRIGGER); |
512 | |
513 | static_assert_no_msg((int)READYTORUN_FIXUP_StaticBaseNonGC == (int)ENCODE_STATIC_BASE_NONGC_HELPER); |
514 | static_assert_no_msg((int)READYTORUN_FIXUP_StaticBaseGC == (int)ENCODE_STATIC_BASE_GC_HELPER); |
515 | static_assert_no_msg((int)READYTORUN_FIXUP_ThreadStaticBaseNonGC == (int)ENCODE_THREAD_STATIC_BASE_NONGC_HELPER); |
516 | static_assert_no_msg((int)READYTORUN_FIXUP_ThreadStaticBaseGC == (int)ENCODE_THREAD_STATIC_BASE_GC_HELPER); |
517 | |
518 | static_assert_no_msg((int)READYTORUN_FIXUP_FieldBaseOffset == (int)ENCODE_FIELD_BASE_OFFSET); |
519 | static_assert_no_msg((int)READYTORUN_FIXUP_FieldOffset == (int)ENCODE_FIELD_OFFSET); |
520 | |
521 | static_assert_no_msg((int)READYTORUN_FIXUP_TypeDictionary == (int)ENCODE_TYPE_DICTIONARY); |
522 | static_assert_no_msg((int)READYTORUN_FIXUP_MethodDictionary == (int)ENCODE_METHOD_DICTIONARY); |
523 | |
524 | static_assert_no_msg((int)READYTORUN_FIXUP_Check_TypeLayout == (int)ENCODE_CHECK_TYPE_LAYOUT); |
525 | static_assert_no_msg((int)READYTORUN_FIXUP_Check_FieldOffset == (int)ENCODE_CHECK_FIELD_OFFSET); |
526 | |
527 | static_assert_no_msg((int)READYTORUN_FIXUP_DelegateCtor == (int)ENCODE_DELEGATE_CTOR); |
528 | |
529 | static_assert_no_msg((int)READYTORUN_FIXUP_DeclaringTypeHandle == (int)ENCODE_DECLARINGTYPE_HANDLE); |
530 | |
531 | // |
532 | // READYTORUN_EXCEPTION |
533 | // |
534 | static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_LOOKUP_TABLE_ENTRY) == sizeof(CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY)); |
535 | static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_CLAUSE) == sizeof(CORCOMPILE_EXCEPTION_CLAUSE)); |
536 | |