JIT: Fix bug in finally cloning caused by unsound callfinally reordering
[platform/upstream/coreclr.git] / src / zap / zapreadytorun.cpp
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::Save(ZapWriter * pZapWriter)
26 {
27     ZapImage * pImage = ZapImage::GetImage(pZapWriter);
28
29     READYTORUN_HEADER readyToRunHeader;
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(&section.Section, m_Sections[i].pSection);
55         pZapWriter->Write(&section, 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 * pReadyToRunHeader = 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     LPCUTF8 pszName;
412     LPCUTF8 pszNameSpace;
413
414     // Save the TypeDefs to the hashtable
415     {
416         HENUMInternalHolder hEnum(pMDImport);
417         hEnum.EnumAllInit(mdtTypeDef);
418
419         mdToken mdTypeToken;
420         while (pMDImport->EnumNext(&hEnum, &mdTypeToken))
421         {
422             mdTypeDef mdCurrentToken = mdTypeToken;
423             DWORD dwHash = GetCompileInfo()->GetVersionResilientTypeHashCode(GetModuleHandle(), mdTypeToken);
424
425             typesHashtable.Append(dwHash, pSection->Place(new UnsignedConstant(RidFromToken(mdTypeToken) << 1)));
426         }
427     }
428
429     // Save the ExportedTypes to the hashtable
430     {
431         HENUMInternalHolder hEnum(pMDImport);
432         hEnum.EnumInit(mdtExportedType, mdTokenNil);
433
434         mdToken mdTypeToken;
435         while (pMDImport->EnumNext(&hEnum, &mdTypeToken))
436         {
437             DWORD dwHash = GetCompileInfo()->GetVersionResilientTypeHashCode(GetModuleHandle(), mdTypeToken);
438
439             typesHashtable.Append(dwHash, pSection->Place(new UnsignedConstant((RidFromToken(mdTypeToken) << 1) | 1)));
440         }
441     }
442
443     vector<byte>& blob = writer.Save();
444
445     ZapNode * pBlob = ZapBlob::NewBlob(this, &blob[0], blob.size());
446     _ASSERTE(m_pAvailableTypesSection);
447     m_pAvailableTypesSection->Place(pBlob);
448
449     GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_AVAILABLE_TYPES, pBlob);
450 }
451
452
453 //
454 // Verify that data structures and flags shared between NGen and ReadyToRun are in sync
455 //
456
457 //
458 // READYTORUN_IMPORT_SECTION
459 //
460 static_assert_no_msg(sizeof(READYTORUN_IMPORT_SECTION)          == sizeof(CORCOMPILE_IMPORT_SECTION));
461
462 static_assert_no_msg((int)READYTORUN_IMPORT_SECTION_TYPE_UNKNOWN     == (int)CORCOMPILE_IMPORT_TYPE_UNKNOWN);
463
464 static_assert_no_msg((int)READYTORUN_IMPORT_SECTION_FLAGS_EAGER      == (int)CORCOMPILE_IMPORT_FLAGS_EAGER);
465
466 //
467 // READYTORUN_METHOD_SIG
468 //
469 static_assert_no_msg((int)READYTORUN_METHOD_SIG_UnboxingStub         == (int)ENCODE_METHOD_SIG_UnboxingStub);
470 static_assert_no_msg((int)READYTORUN_METHOD_SIG_InstantiatingStub    == (int)ENCODE_METHOD_SIG_InstantiatingStub);
471 static_assert_no_msg((int)READYTORUN_METHOD_SIG_MethodInstantiation  == (int)ENCODE_METHOD_SIG_MethodInstantiation);
472 static_assert_no_msg((int)READYTORUN_METHOD_SIG_SlotInsteadOfToken   == (int)ENCODE_METHOD_SIG_SlotInsteadOfToken);
473 static_assert_no_msg((int)READYTORUN_METHOD_SIG_MemberRefToken       == (int)ENCODE_METHOD_SIG_MemberRefToken);
474 static_assert_no_msg((int)READYTORUN_METHOD_SIG_Constrained          == (int)ENCODE_METHOD_SIG_Constrained);
475 static_assert_no_msg((int)READYTORUN_METHOD_SIG_OwnerType            == (int)ENCODE_METHOD_SIG_OwnerType);
476
477 //
478 // READYTORUN_FIELD_SIG
479 //
480 static_assert_no_msg((int)READYTORUN_FIELD_SIG_IndexInsteadOfToken   == (int)ENCODE_FIELD_SIG_IndexInsteadOfToken);
481 static_assert_no_msg((int)READYTORUN_FIELD_SIG_MemberRefToken        == (int)ENCODE_FIELD_SIG_MemberRefToken);
482 static_assert_no_msg((int)READYTORUN_FIELD_SIG_OwnerType             == (int)ENCODE_FIELD_SIG_OwnerType);
483
484 //
485 // READYTORUN_FIXUP
486 //
487 static_assert_no_msg((int)READYTORUN_FIXUP_ThisObjDictionaryLookup   == (int)ENCODE_DICTIONARY_LOOKUP_THISOBJ);
488 static_assert_no_msg((int)READYTORUN_FIXUP_TypeDictionaryLookup      == (int)ENCODE_DICTIONARY_LOOKUP_TYPE);
489 static_assert_no_msg((int)READYTORUN_FIXUP_MethodDictionaryLookup    == (int)ENCODE_DICTIONARY_LOOKUP_METHOD);
490
491 static_assert_no_msg((int)READYTORUN_FIXUP_TypeHandle                == (int)ENCODE_TYPE_HANDLE);
492 static_assert_no_msg((int)READYTORUN_FIXUP_MethodHandle              == (int)ENCODE_METHOD_HANDLE);
493 static_assert_no_msg((int)READYTORUN_FIXUP_FieldHandle               == (int)ENCODE_FIELD_HANDLE);
494
495 static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry               == (int)ENCODE_METHOD_ENTRY);
496 static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry_DefToken      == (int)ENCODE_METHOD_ENTRY_DEF_TOKEN);
497 static_assert_no_msg((int)READYTORUN_FIXUP_MethodEntry_RefToken      == (int)ENCODE_METHOD_ENTRY_REF_TOKEN);
498
499 static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry              == (int)ENCODE_VIRTUAL_ENTRY);
500 static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_DefToken     == (int)ENCODE_VIRTUAL_ENTRY_DEF_TOKEN);
501 static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_RefToken     == (int)ENCODE_VIRTUAL_ENTRY_REF_TOKEN);
502 static_assert_no_msg((int)READYTORUN_FIXUP_VirtualEntry_Slot         == (int)ENCODE_VIRTUAL_ENTRY_SLOT);
503
504 static_assert_no_msg((int)READYTORUN_FIXUP_Helper                    == (int)ENCODE_READYTORUN_HELPER);
505 static_assert_no_msg((int)READYTORUN_FIXUP_StringHandle              == (int)ENCODE_STRING_HANDLE);
506
507 static_assert_no_msg((int)READYTORUN_FIXUP_NewObject                 == (int)ENCODE_NEW_HELPER);
508 static_assert_no_msg((int)READYTORUN_FIXUP_NewArray                  == (int)ENCODE_NEW_ARRAY_HELPER);
509
510 static_assert_no_msg((int)READYTORUN_FIXUP_IsInstanceOf              == (int)ENCODE_ISINSTANCEOF_HELPER);
511 static_assert_no_msg((int)READYTORUN_FIXUP_ChkCast                   == (int)ENCODE_CHKCAST_HELPER);
512
513 static_assert_no_msg((int)READYTORUN_FIXUP_FieldAddress              == (int)ENCODE_FIELD_ADDRESS);
514 static_assert_no_msg((int)READYTORUN_FIXUP_CctorTrigger              == (int)ENCODE_CCTOR_TRIGGER);
515
516 static_assert_no_msg((int)READYTORUN_FIXUP_StaticBaseNonGC           == (int)ENCODE_STATIC_BASE_NONGC_HELPER);
517 static_assert_no_msg((int)READYTORUN_FIXUP_StaticBaseGC              == (int)ENCODE_STATIC_BASE_GC_HELPER);
518 static_assert_no_msg((int)READYTORUN_FIXUP_ThreadStaticBaseNonGC     == (int)ENCODE_THREAD_STATIC_BASE_NONGC_HELPER);
519 static_assert_no_msg((int)READYTORUN_FIXUP_ThreadStaticBaseGC        == (int)ENCODE_THREAD_STATIC_BASE_GC_HELPER);
520
521 static_assert_no_msg((int)READYTORUN_FIXUP_FieldBaseOffset           == (int)ENCODE_FIELD_BASE_OFFSET);
522 static_assert_no_msg((int)READYTORUN_FIXUP_FieldOffset               == (int)ENCODE_FIELD_OFFSET);
523
524 static_assert_no_msg((int)READYTORUN_FIXUP_TypeDictionary            == (int)ENCODE_TYPE_DICTIONARY);
525 static_assert_no_msg((int)READYTORUN_FIXUP_MethodDictionary          == (int)ENCODE_METHOD_DICTIONARY);
526
527 static_assert_no_msg((int)READYTORUN_FIXUP_Check_TypeLayout          == (int)ENCODE_CHECK_TYPE_LAYOUT);
528 static_assert_no_msg((int)READYTORUN_FIXUP_Check_FieldOffset         == (int)ENCODE_CHECK_FIELD_OFFSET);
529
530 static_assert_no_msg((int)READYTORUN_FIXUP_DelegateCtor              == (int)ENCODE_DELEGATE_CTOR);
531
532 static_assert_no_msg((int)READYTORUN_FIXUP_DeclaringTypeHandle       == (int)ENCODE_DECLARINGTYPE_HANDLE);
533
534 //
535 // READYTORUN_EXCEPTION
536 //
537 static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_LOOKUP_TABLE_ENTRY) == sizeof(CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY));
538 static_assert_no_msg(sizeof(READYTORUN_EXCEPTION_CLAUSE) == sizeof(CORCOMPILE_EXCEPTION_CLAUSE));