forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcodeversion.h
731 lines (613 loc) · 22.2 KB
/
codeversion.h
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ===========================================================================
// File: CodeVersion.h
//
// ===========================================================================
#ifndef CODE_VERSION_H
#define CODE_VERSION_H
class ILCodeVersion;
typedef DWORD NativeCodeVersionId;
#ifdef FEATURE_CODE_VERSIONING
class NativeCodeVersionNode;
typedef DPTR(class NativeCodeVersionNode) PTR_NativeCodeVersionNode;
class NativeCodeVersionCollection;
class NativeCodeVersionIterator;
class ILCodeVersionNode;
typedef DPTR(class ILCodeVersionNode) PTR_ILCodeVersionNode;
class ILCodeVersionCollection;
class ILCodeVersionIterator;
class MethodDescVersioningState;
typedef DPTR(class MethodDescVersioningState) PTR_MethodDescVersioningState;
class ILCodeVersioningState;
typedef DPTR(class ILCodeVersioningState) PTR_ILCodeVersioningState;
class CodeVersionManager;
typedef DPTR(class CodeVersionManager) PTR_CodeVersionManager;
#endif
#ifdef HAVE_GCCOVER
class GCCoverageInfo;
typedef DPTR(class GCCoverageInfo) PTR_GCCoverageInfo;
#endif
#ifdef FEATURE_ON_STACK_REPLACEMENT
struct PatchpointInfo;
typedef DPTR(struct PatchpointInfo) PTR_PatchpointInfo;
#endif
class NativeCodeVersion
{
#ifdef FEATURE_CODE_VERSIONING
friend class MethodDescVersioningState;
friend class ILCodeVersion;
#endif
public:
NativeCodeVersion();
NativeCodeVersion(const NativeCodeVersion & rhs);
#ifdef FEATURE_CODE_VERSIONING
NativeCodeVersion(PTR_NativeCodeVersionNode pVersionNode);
#endif
explicit NativeCodeVersion(PTR_MethodDesc pMethod);
BOOL IsNull() const;
PTR_MethodDesc GetMethodDesc() const;
NativeCodeVersionId GetVersionId() const;
BOOL IsDefaultVersion() const;
PCODE GetNativeCode() const;
#ifdef FEATURE_CODE_VERSIONING
ILCodeVersion GetILCodeVersion() const;
ReJITID GetILCodeVersionId() const;
#endif
#ifndef DACCESS_COMPILE
BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected = 0);
#endif
// NOTE: Don't change existing values to avoid breaking changes in event tracing
enum OptimizationTier
{
OptimizationTier0,
OptimizationTier1,
OptimizationTier1OSR,
OptimizationTierOptimized, // may do less optimizations than tier 1
OptimizationTier0Instrumented,
OptimizationTier1Instrumented,
};
#ifdef FEATURE_TIERED_COMPILATION
OptimizationTier GetOptimizationTier() const;
bool IsFinalTier() const;
#ifndef DACCESS_COMPILE
void SetOptimizationTier(OptimizationTier tier);
#endif
#endif // FEATURE_TIERED_COMPILATION
#ifdef FEATURE_ON_STACK_REPLACEMENT
PatchpointInfo * GetOSRInfo(unsigned * iloffset);
#endif // FEATURE_ON_STACK_REPLACEMENT
#ifdef HAVE_GCCOVER
PTR_GCCoverageInfo GetGCCoverageInfo() const;
void SetGCCoverageInfo(PTR_GCCoverageInfo gcCover);
#endif
bool operator==(const NativeCodeVersion & rhs) const;
bool operator!=(const NativeCodeVersion & rhs) const;
#if defined(DACCESS_COMPILE) && defined(FEATURE_CODE_VERSIONING)
// The DAC is privy to the backing node abstraction
PTR_NativeCodeVersionNode AsNode() const;
#endif
private:
#ifndef FEATURE_CODE_VERSIONING
PTR_MethodDesc m_pMethodDesc;
#else // FEATURE_CODE_VERSIONING
#ifndef DACCESS_COMPILE
NativeCodeVersionNode* AsNode() const;
NativeCodeVersionNode* AsNode();
void SetActiveChildFlag(BOOL isActive);
MethodDescVersioningState* GetMethodDescVersioningState();
#endif
BOOL IsActiveChildVersion() const;
PTR_MethodDescVersioningState GetMethodDescVersioningState() const;
enum StorageKind
{
Unknown,
Explicit,
Synthetic
};
StorageKind m_storageKind;
union
{
PTR_NativeCodeVersionNode m_pVersionNode;
struct
{
PTR_MethodDesc m_pMethodDesc;
} m_synthetic;
};
#endif // FEATURE_CODE_VERSIONING
};
#ifdef FEATURE_CODE_VERSIONING
class ILCodeVersion
{
friend class NativeCodeVersionIterator;
public:
ILCodeVersion();
ILCodeVersion(const ILCodeVersion & ilCodeVersion);
ILCodeVersion(PTR_ILCodeVersionNode pILCodeVersionNode);
ILCodeVersion(PTR_Module pModule, mdMethodDef methodDef);
bool operator==(const ILCodeVersion & rhs) const;
bool operator!=(const ILCodeVersion & rhs) const;
BOOL HasDefaultIL() const;
BOOL IsNull() const;
BOOL IsDefaultVersion() const;
PTR_Module GetModule() const;
mdMethodDef GetMethodDef() const;
ReJITID GetVersionId() const;
NativeCodeVersionCollection GetNativeCodeVersions(PTR_MethodDesc pClosedMethodDesc) const;
NativeCodeVersion GetActiveNativeCodeVersion(PTR_MethodDesc pClosedMethodDesc) const;
#if defined(FEATURE_TIERED_COMPILATION) && !defined(DACCESS_COMPILE)
bool HasAnyOptimizedNativeCodeVersion(NativeCodeVersion tier0NativeCodeVersion) const;
#endif
PTR_COR_ILMETHOD GetIL() const;
DWORD GetJitFlags() const;
const InstrumentedILOffsetMapping* GetInstrumentedILMap() const;
#ifndef DACCESS_COMPILE
void SetIL(COR_ILMETHOD* pIL);
void SetJitFlags(DWORD flags);
void SetInstrumentedILMap(SIZE_T cMap, COR_IL_MAP * rgMap);
HRESULT AddNativeCodeVersion(MethodDesc* pClosedMethodDesc, NativeCodeVersion::OptimizationTier optimizationTier,
NativeCodeVersion* pNativeCodeVersion, PatchpointInfo* patchpointInfo = NULL, unsigned ilOffset = 0);
HRESULT GetOrCreateActiveNativeCodeVersion(MethodDesc* pClosedMethodDesc, NativeCodeVersion* pNativeCodeVersion);
HRESULT SetActiveNativeCodeVersion(NativeCodeVersion activeNativeCodeVersion);
#endif //DACCESS_COMPILE
enum RejitFlags
{
// The profiler has requested a ReJit, so we've allocated stuff, but we haven't
// called back to the profiler to get any info or indicate that the ReJit has
// started. (This Info can be 'reused' for a new ReJit if the
// profiler calls RequestRejit again before we transition to the next state.)
kStateRequested = 0x00000000,
// The CLR has initiated the call to the profiler's GetReJITParameters() callback
// but it hasn't completed yet. At this point we have to assume the profiler has
// committed to a specific IL body, even if the CLR doesn't know what it is yet.
// If the profiler calls RequestRejit we need to allocate a new ILCodeVersion
// and call GetReJITParameters() again.
kStateGettingReJITParameters = 0x00000001,
// We have asked the profiler about this method via ICorProfilerFunctionControl,
// and have thus stored the IL and codegen flags the profiler specified.
kStateActive = 0x00000002,
kStateMask = 0x0000000F,
// Indicates that the method being ReJITted is an inliner of the actual
// ReJIT request and we should not issue the GetReJITParameters for this
// method.
kSuppressParams = 0x80000000
};
RejitFlags GetRejitState() const;
BOOL GetEnableReJITCallback() const;
BOOL IsDeoptimized() const;
#ifndef DACCESS_COMPILE
void SetRejitState(RejitFlags newState);
void SetEnableReJITCallback(BOOL state);
#endif
#ifdef DACCESS_COMPILE
// The DAC is privy to the backing node abstraction
PTR_ILCodeVersionNode AsNode() const;
#endif
private:
#ifndef DACCESS_COMPILE
PTR_ILCodeVersionNode AsNode();
PTR_ILCodeVersionNode AsNode() const;
#endif
enum StorageKind
{
Unknown,
Explicit,
Synthetic
};
StorageKind m_storageKind;
union
{
PTR_ILCodeVersionNode m_pVersionNode;
struct
{
PTR_Module m_pModule;
mdMethodDef m_methodDef;
} m_synthetic;
};
};
class NativeCodeVersionNode
{
friend NativeCodeVersionIterator;
friend MethodDescVersioningState;
friend ILCodeVersionNode;
public:
#ifndef DACCESS_COMPILE
NativeCodeVersionNode(NativeCodeVersionId id, MethodDesc* pMethod, ReJITID parentId, NativeCodeVersion::OptimizationTier optimizationTier,
PatchpointInfo* patchpointInfo, unsigned ilOffset);
#endif
PTR_MethodDesc GetMethodDesc() const; // Can be called without any locks
NativeCodeVersionId GetVersionId() const; // Can be called without any locks
PCODE GetNativeCode() const; // Can be called without any locks, but result may be stale if it wasn't already set
ReJITID GetILVersionId() const; // Can be called without any locks
ILCodeVersion GetILCodeVersion() const;// Can be called without any locks
BOOL IsActiveChildVersion() const;
#ifndef DACCESS_COMPILE
BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected);
void SetActiveChildFlag(BOOL isActive);
#endif
#ifdef FEATURE_TIERED_COMPILATION
NativeCodeVersion::OptimizationTier GetOptimizationTier() const;
#ifndef DACCESS_COMPILE
void SetOptimizationTier(NativeCodeVersion::OptimizationTier tier);
#endif
#endif // FEATURE_TIERED_COMPILATION
#ifdef HAVE_GCCOVER
PTR_GCCoverageInfo GetGCCoverageInfo() const;
void SetGCCoverageInfo(PTR_GCCoverageInfo gcCover);
#endif
#ifdef FEATURE_ON_STACK_REPLACEMENT
PatchpointInfo * GetOSRInfo(unsigned * ilOffset) const;
#endif
private:
//union - could save a little memory?
//{
PCODE m_pNativeCode;
DAC_IGNORE(const) PTR_MethodDesc m_pMethodDesc;
//};
DAC_IGNORE(const) ReJITID m_parentId;
PTR_NativeCodeVersionNode m_pNextMethodDescSibling; // Never modified after being added to the linked list
DAC_IGNORE(const) NativeCodeVersionId m_id;
#ifdef FEATURE_TIERED_COMPILATION
NativeCodeVersion::OptimizationTier m_optTier; // Set in constructor, but as the JIT runs it may upgrade the optimization tier
#endif
#ifdef HAVE_GCCOVER
PTR_GCCoverageInfo m_gcCover;
#endif
#ifdef FEATURE_ON_STACK_REPLACEMENT
DAC_IGNORE(const) PTR_PatchpointInfo m_patchpointInfo;
DAC_IGNORE(const) unsigned m_ilOffset;
#endif
enum NativeCodeVersionNodeFlags
{
IsActiveChildFlag = 1
};
DWORD m_flags;
};
class NativeCodeVersionCollection
{
friend class NativeCodeVersionIterator;
public:
NativeCodeVersionCollection(PTR_MethodDesc pMethodDescFilter, ILCodeVersion ilCodeFilter);
NativeCodeVersionIterator Begin();
NativeCodeVersionIterator End();
private:
PTR_MethodDesc m_pMethodDescFilter;
ILCodeVersion m_ilCodeFilter;
};
class NativeCodeVersionIterator : public Enumerator<const NativeCodeVersion, NativeCodeVersionIterator>
{
friend class Enumerator<const NativeCodeVersion, NativeCodeVersionIterator>;
public:
NativeCodeVersionIterator(NativeCodeVersionCollection* pCollection);
CHECK Check() const { CHECK_OK; }
protected:
const NativeCodeVersion & Get() const;
void First();
void Next();
bool Equal(const NativeCodeVersionIterator &i) const;
CHECK DoCheck() const { CHECK_OK; }
private:
enum IterationStage
{
Initial,
ImplicitCodeVersion,
LinkedList,
End
};
IterationStage m_stage;
NativeCodeVersionCollection* m_pCollection;
PTR_NativeCodeVersionNode m_pLinkedListCur;
NativeCodeVersion m_cur;
};
class ILCodeVersionNode
{
public:
ILCodeVersionNode();
#ifndef DACCESS_COMPILE
ILCodeVersionNode(Module* pModule, mdMethodDef methodDef, ReJITID id, BOOL isDeoptimized);
#endif
PTR_Module GetModule() const;
mdMethodDef GetMethodDef() const;
ReJITID GetVersionId() const;
PTR_COR_ILMETHOD GetIL() const;
DWORD GetJitFlags() const;
const InstrumentedILOffsetMapping* GetInstrumentedILMap() const;
ILCodeVersion::RejitFlags GetRejitState() const;
BOOL GetEnableReJITCallback() const;
PTR_ILCodeVersionNode GetNextILVersionNode() const;
BOOL IsDeoptimized() const;
#ifndef DACCESS_COMPILE
void SetIL(COR_ILMETHOD* pIL);
void SetJitFlags(DWORD flags);
void SetInstrumentedILMap(SIZE_T cMap, COR_IL_MAP * rgMap);
void SetRejitState(ILCodeVersion::RejitFlags newState);
void SetEnableReJITCallback(BOOL state);
void SetNextILVersionNode(ILCodeVersionNode* pNextVersionNode);
#endif
private:
const PTR_Module m_pModule;
const mdMethodDef m_methodDef;
const ReJITID m_rejitId;
PTR_ILCodeVersionNode m_pNextILVersionNode; // Never modified after being added to the linked list
Volatile<ILCodeVersion::RejitFlags> m_rejitState;
VolatilePtr<COR_ILMETHOD, PTR_COR_ILMETHOD> m_pIL;
Volatile<DWORD> m_jitFlags;
InstrumentedILOffsetMapping m_instrumentedILMap;
BOOL m_deoptimized;
};
class ILCodeVersionCollection
{
friend class ILCodeVersionIterator;
public:
ILCodeVersionCollection(PTR_Module pModule, mdMethodDef methodDef);
ILCodeVersionIterator Begin();
ILCodeVersionIterator End();
private:
PTR_Module m_pModule;
mdMethodDef m_methodDef;
};
class ILCodeVersionIterator : public Enumerator<const ILCodeVersion, ILCodeVersionIterator>
{
friend class Enumerator<const ILCodeVersion, ILCodeVersionIterator>;
public:
ILCodeVersionIterator();
ILCodeVersionIterator(const ILCodeVersionIterator & iter);
ILCodeVersionIterator(ILCodeVersionCollection* pCollection);
CHECK Check() const { CHECK_OK; }
protected:
const ILCodeVersion & Get() const;
void First();
void Next();
bool Equal(const ILCodeVersionIterator &i) const;
CHECK DoCheck() const { CHECK_OK; }
private:
enum IterationStage
{
Initial,
ImplicitCodeVersion,
LinkedList,
End
};
IterationStage m_stage;
ILCodeVersion m_cur;
PTR_ILCodeVersionNode m_pLinkedListCur;
ILCodeVersionCollection* m_pCollection;
};
class MethodDescVersioningState
{
public:
MethodDescVersioningState(PTR_MethodDesc pMethodDesc);
PTR_MethodDesc GetMethodDesc() const;
NativeCodeVersionId AllocateVersionId();
PTR_NativeCodeVersionNode GetFirstVersionNode() const;
#ifndef DACCESS_COMPILE
void LinkNativeCodeVersionNode(NativeCodeVersionNode* pNativeCodeVersionNode);
#endif // DACCESS_COMPILE
//read-write data for the default native code version
BOOL IsDefaultVersionActiveChild() const;
#ifndef DACCESS_COMPILE
void SetDefaultVersionActiveChildFlag(BOOL isActive);
#endif
private:
PTR_MethodDesc m_pMethodDesc;
enum MethodDescVersioningStateFlags
{
IsDefaultVersionActiveChildFlag = 0x4
};
BYTE m_flags;
NativeCodeVersionId m_nextId;
PTR_NativeCodeVersionNode m_pFirstVersionNode;
};
class ILCodeVersioningState
{
public:
ILCodeVersioningState(PTR_Module pModule, mdMethodDef methodDef);
ILCodeVersion GetActiveVersion() const;
PTR_ILCodeVersionNode GetFirstVersionNode() const;
#ifndef DACCESS_COMPILE
void SetActiveVersion(ILCodeVersion ilActiveCodeVersion);
void LinkILCodeVersionNode(ILCodeVersionNode* pILCodeVersionNode);
#endif
struct Key
{
public:
Key();
Key(PTR_Module pModule, mdMethodDef methodDef);
size_t Hash() const;
bool operator==(const Key & rhs) const;
private:
PTR_Module m_pModule;
mdMethodDef m_methodDef;
};
Key GetKey() const;
private:
ILCodeVersion m_activeVersion;
PTR_ILCodeVersionNode m_pFirstVersionNode;
PTR_Module m_pModule;
mdMethodDef m_methodDef;
};
class CodeVersionManager
{
friend class ILCodeVersion;
friend struct _DacGlobals;
SVAL_DECL(BOOL, s_HasNonDefaultILVersions);
public:
CodeVersionManager() = default;
BOOL HasNonDefaultILVersions();
ILCodeVersionCollection GetILCodeVersions(PTR_MethodDesc pMethod);
ILCodeVersionCollection GetILCodeVersions(PTR_Module pModule, mdMethodDef methodDef);
ILCodeVersion GetActiveILCodeVersion(PTR_MethodDesc pMethod);
ILCodeVersion GetActiveILCodeVersion(PTR_Module pModule, mdMethodDef methodDef);
ILCodeVersion GetILCodeVersion(PTR_MethodDesc pMethod, ReJITID rejitId);
NativeCodeVersionCollection GetNativeCodeVersions(PTR_MethodDesc pMethod) const;
NativeCodeVersion GetNativeCodeVersion(PTR_MethodDesc pMethod, PCODE codeStartAddress) const;
PTR_ILCodeVersioningState GetILCodeVersioningState(PTR_Module pModule, mdMethodDef methodDef) const;
PTR_MethodDescVersioningState GetMethodDescVersioningState(PTR_MethodDesc pMethod) const;
#ifndef DACCESS_COMPILE
struct CodePublishError
{
Module* pModule;
mdMethodDef methodDef;
MethodDesc* pMethodDesc;
HRESULT hrStatus;
};
HRESULT AddILCodeVersion(Module* pModule, mdMethodDef methodDef, ILCodeVersion* pILCodeVersion, BOOL isDeoptimized);
HRESULT AddNativeCodeVersion(ILCodeVersion ilCodeVersion, MethodDesc* pClosedMethodDesc, NativeCodeVersion::OptimizationTier optimizationTier, NativeCodeVersion* pNativeCodeVersion,
PatchpointInfo* patchpointInfo = NULL, unsigned ilOffset = 0);
PCODE PublishVersionableCodeIfNecessary(
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef);
private:
HRESULT PublishNativeCodeVersion(MethodDesc* pMethodDesc, NativeCodeVersion nativeCodeVersion);
HRESULT GetOrCreateMethodDescVersioningState(MethodDesc* pMethod, MethodDescVersioningState** ppMethodDescVersioningState);
HRESULT GetOrCreateILCodeVersioningState(Module* pModule, mdMethodDef methodDef, ILCodeVersioningState** ppILCodeVersioningState);
public:
HRESULT SetActiveILCodeVersions(ILCodeVersion* pActiveVersions, DWORD cActiveVersions, CDynArray<CodePublishError> * pPublishErrors);
static HRESULT AddCodePublishError(Module* pModule, mdMethodDef methodDef, MethodDesc* pMD, HRESULT hrStatus, CDynArray<CodePublishError> * pErrors);
static HRESULT AddCodePublishError(NativeCodeVersion nativeCodeVersion, HRESULT hrStatus, CDynArray<CodePublishError> * pErrors);
static void OnAppDomainExit(AppDomain* pAppDomain);
#endif
static bool IsMethodSupported(PTR_MethodDesc pMethodDesc);
#ifndef DACCESS_COMPILE
static bool InitialNativeCodeVersionMayNotBeTheDefaultNativeCodeVersion()
{
LIMITED_METHOD_CONTRACT;
return s_initialNativeCodeVersionMayNotBeTheDefaultNativeCodeVersion;
}
static void SetInitialNativeCodeVersionMayNotBeTheDefaultNativeCodeVersion()
{
LIMITED_METHOD_CONTRACT;
s_initialNativeCodeVersionMayNotBeTheDefaultNativeCodeVersion = true;
}
#endif
private:
#ifndef DACCESS_COMPILE
static HRESULT EnumerateClosedMethodDescs(MethodDesc* pMD, CDynArray<MethodDesc*> * pClosedMethodDescs, CDynArray<CodePublishError> * pUnsupportedMethodErrors);
static HRESULT EnumerateDomainClosedMethodDescs(
AppDomain * pAppDomainToSearch,
Module* pModuleContainingMethodDef,
mdMethodDef methodDef,
CDynArray<MethodDesc*> * pClosedMethodDescs,
CDynArray<CodePublishError> * pUnsupportedMethodErrors);
static HRESULT GetNonVersionableError(MethodDesc* pMD);
void ReportCodePublishError(CodePublishError* pErrorRecord);
void ReportCodePublishError(MethodDesc* pMD, HRESULT hrStatus);
void ReportCodePublishError(Module* pModule, mdMethodDef methodDef, MethodDesc* pMD, HRESULT hrStatus);
static bool s_initialNativeCodeVersionMayNotBeTheDefaultNativeCodeVersion;
#endif
private:
static CrstStatic s_lock;
#ifndef DACCESS_COMPILE
public:
static void StaticInitialize()
{
WRAPPER_NO_CONTRACT;
s_lock.Init(
CrstCodeVersioning,
CrstFlags(CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD | CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN));
}
#endif
#ifdef _DEBUG
public:
static bool IsLockOwnedByCurrentThread();
#endif
public:
class LockHolder : private CrstHolderWithState
{
public:
LockHolder()
#ifndef DACCESS_COMPILE
: CrstHolderWithState(&s_lock)
#else
: CrstHolderWithState(nullptr)
#endif
{
WRAPPER_NO_CONTRACT;
}
LockHolder(const LockHolder &) = delete;
LockHolder &operator =(const LockHolder &) = delete;
};
};
#endif // FEATURE_CODE_VERSIONING
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NativeCodeVersion definitions
inline NativeCodeVersion::NativeCodeVersion()
#ifdef FEATURE_CODE_VERSIONING
: m_storageKind(StorageKind::Unknown), m_pVersionNode(PTR_NULL)
#else
: m_pMethodDesc(PTR_NULL)
#endif
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
static_assert_no_msg(sizeof(m_pVersionNode) == sizeof(m_synthetic));
#endif
}
inline NativeCodeVersion::NativeCodeVersion(const NativeCodeVersion & rhs)
#ifdef FEATURE_CODE_VERSIONING
: m_storageKind(rhs.m_storageKind), m_pVersionNode(rhs.m_pVersionNode)
#else
: m_pMethodDesc(rhs.m_pMethodDesc)
#endif
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
static_assert_no_msg(sizeof(m_pVersionNode) == sizeof(m_synthetic));
#endif
}
inline BOOL NativeCodeVersion::IsNull() const
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
return m_storageKind == StorageKind::Unknown;
#else
return m_pMethodDesc == NULL;
#endif
}
inline PTR_MethodDesc NativeCodeVersion::GetMethodDesc() const
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
return m_storageKind == StorageKind::Explicit ? m_pVersionNode->GetMethodDesc() : m_synthetic.m_pMethodDesc;
#else
return m_pMethodDesc;
#endif
}
inline NativeCodeVersionId NativeCodeVersion::GetVersionId() const
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
if (m_storageKind == StorageKind::Explicit)
{
return m_pVersionNode->GetVersionId();
}
#endif
return 0;
}
inline bool NativeCodeVersion::operator==(const NativeCodeVersion & rhs) const
{
LIMITED_METHOD_DAC_CONTRACT;
#ifdef FEATURE_CODE_VERSIONING
static_assert_no_msg(sizeof(m_pVersionNode) == sizeof(m_synthetic));
return m_storageKind == rhs.m_storageKind && m_pVersionNode == rhs.m_pVersionNode;
#else
return m_pMethodDesc == rhs.m_pMethodDesc;
#endif
}
inline bool NativeCodeVersion::operator!=(const NativeCodeVersion & rhs) const
{
WRAPPER_NO_CONTRACT;
return !operator==(rhs);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NativeCodeVersionNode definitions
#ifdef FEATURE_CODE_VERSIONING
inline PTR_MethodDesc NativeCodeVersionNode::GetMethodDesc() const
{
LIMITED_METHOD_DAC_CONTRACT;
return m_pMethodDesc;
}
#endif // FEATURE_CODE_VERSIONING
#endif // CODE_VERSION_H