Remove superfluous 'const' qualifier from trivial return types (#20652)
[platform/upstream/coreclr.git] / src / vm / codeversion.h
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 // File: CodeVersion.h
6 //
7 // ===========================================================================
8
9
10 #ifndef CODE_VERSION_H
11 #define CODE_VERSION_H
12
13 class NativeCodeVersion;
14 class ILCodeVersion;
15 typedef DWORD NativeCodeVersionId;
16
17 #ifdef FEATURE_CODE_VERSIONING
18 class NativeCodeVersionNode;
19 typedef DPTR(class NativeCodeVersionNode) PTR_NativeCodeVersionNode;
20 class NativeCodeVersionCollection;
21 class NativeCodeVersionIterator;
22 class ILCodeVersionNode;
23 typedef DPTR(class ILCodeVersionNode) PTR_ILCodeVersionNode;
24 class ILCodeVersionCollection;
25 class ILCodeVersionIterator;
26 class MethodDescVersioningState;
27 typedef DPTR(class MethodDescVersioningState) PTR_MethodDescVersioningState;
28
29 class ILCodeVersioningState;
30 typedef DPTR(class ILCodeVersioningState) PTR_ILCodeVersioningState;
31 class CodeVersionManager;
32 typedef DPTR(class CodeVersionManager) PTR_CodeVersionManager;
33
34 // This HRESULT is only used as a private implementation detail. Corerror.xml has a comment in it
35 //  reserving this value for our use but it doesn't appear in the public headers.
36 #define CORPROF_E_RUNTIME_SUSPEND_REQUIRED 0x80131381
37
38 #endif
39
40
41
42
43 class NativeCodeVersion
44 {
45 #ifdef FEATURE_CODE_VERSIONING
46     friend class MethodDescVersioningState;
47     friend class ILCodeVersion;
48 #endif
49
50 public:
51     NativeCodeVersion();
52     NativeCodeVersion(const NativeCodeVersion & rhs);
53 #ifdef FEATURE_CODE_VERSIONING
54     NativeCodeVersion(PTR_NativeCodeVersionNode pVersionNode);
55 #endif
56     NativeCodeVersion(PTR_MethodDesc pMethod);
57     BOOL IsNull() const;
58     PTR_MethodDesc GetMethodDesc() const;
59     NativeCodeVersionId GetVersionId() const;
60     BOOL IsDefaultVersion() const;
61     PCODE GetNativeCode() const;
62     ILCodeVersion GetILCodeVersion() const;
63     ReJITID GetILCodeVersionId() const;
64 #ifndef DACCESS_COMPILE
65     BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected = NULL);
66 #endif
67     enum OptimizationTier
68     {
69         OptimizationTier0,
70         OptimizationTier1
71     };
72 #ifdef FEATURE_TIERED_COMPILATION
73     OptimizationTier GetOptimizationTier() const;
74 #endif // FEATURE_TIERED_COMPILATION
75     bool operator==(const NativeCodeVersion & rhs) const;
76     bool operator!=(const NativeCodeVersion & rhs) const;
77 #if defined(DACCESS_COMPILE) && defined(FEATURE_CODE_VERSIONING)
78     // The DAC is privy to the backing node abstraction
79     PTR_NativeCodeVersionNode AsNode() const;
80 #endif
81
82 private:
83
84 #ifndef FEATURE_CODE_VERSIONING
85     MethodDesc* m_pMethodDesc;
86 #else // FEATURE_CODE_VERSIONING
87
88 #ifndef DACCESS_COMPILE
89     NativeCodeVersionNode* AsNode() const;
90     NativeCodeVersionNode* AsNode();
91     void SetActiveChildFlag(BOOL isActive);
92     MethodDescVersioningState* GetMethodDescVersioningState();
93 #endif
94
95     BOOL IsActiveChildVersion() const;
96     PTR_MethodDescVersioningState GetMethodDescVersioningState() const;
97
98     enum StorageKind
99     {
100         Unknown,
101         Explicit,
102         Synthetic
103     };
104
105     StorageKind m_storageKind;
106     union
107     {
108         PTR_NativeCodeVersionNode m_pVersionNode;
109         struct SyntheticStorage
110         {
111             PTR_MethodDesc m_pMethodDesc;
112         } m_synthetic;
113     };
114 #endif // FEATURE_CODE_VERSIONING
115 };
116
117
118
119 #ifdef FEATURE_CODE_VERSIONING
120
121
122
123 class ILCodeVersion
124 {
125     friend class NativeCodeVersionIterator;
126
127 public:
128     ILCodeVersion();
129     ILCodeVersion(const ILCodeVersion & ilCodeVersion);
130     ILCodeVersion(PTR_ILCodeVersionNode pILCodeVersionNode);
131     ILCodeVersion(PTR_Module pModule, mdMethodDef methodDef);
132
133     bool operator==(const ILCodeVersion & rhs) const;
134     bool operator!=(const ILCodeVersion & rhs) const;
135     BOOL HasDefaultIL() const;
136     BOOL IsNull() const;
137     BOOL IsDefaultVersion() const;
138     PTR_Module GetModule() const;
139     mdMethodDef GetMethodDef() const;
140     ReJITID GetVersionId() const;
141     NativeCodeVersionCollection GetNativeCodeVersions(PTR_MethodDesc pClosedMethodDesc) const;
142     NativeCodeVersion GetActiveNativeCodeVersion(PTR_MethodDesc pClosedMethodDesc) const;
143     PTR_COR_ILMETHOD GetIL() const;
144     PTR_COR_ILMETHOD GetILNoThrow() const;
145     DWORD GetJitFlags() const;
146     const InstrumentedILOffsetMapping* GetInstrumentedILMap() const;
147
148 #ifndef DACCESS_COMPILE
149     void SetIL(COR_ILMETHOD* pIL);
150     void SetJitFlags(DWORD flags);
151     void SetInstrumentedILMap(SIZE_T cMap, COR_IL_MAP * rgMap);
152     HRESULT AddNativeCodeVersion(MethodDesc* pClosedMethodDesc, NativeCodeVersion::OptimizationTier optimizationTier, NativeCodeVersion* pNativeCodeVersion);
153     HRESULT GetOrCreateActiveNativeCodeVersion(MethodDesc* pClosedMethodDesc, NativeCodeVersion* pNativeCodeVersion);
154     HRESULT SetActiveNativeCodeVersion(NativeCodeVersion activeNativeCodeVersion, BOOL fEESuspended);
155 #endif //DACCESS_COMPILE
156
157     enum RejitFlags
158     {
159         // The profiler has requested a ReJit, so we've allocated stuff, but we haven't
160         // called back to the profiler to get any info or indicate that the ReJit has
161         // started. (This Info can be 'reused' for a new ReJit if the
162         // profiler calls RequestRejit again before we transition to the next state.)
163         kStateRequested = 0x00000000,
164
165         // The CLR has initiated the call to the profiler's GetReJITParameters() callback
166         // but it hasn't completed yet. At this point we have to assume the profiler has
167         // commited to a specific IL body, even if the CLR doesn't know what it is yet.
168         // If the profiler calls RequestRejit we need to allocate a new ILCodeVersion
169         // and call GetReJITParameters() again.
170         kStateGettingReJITParameters = 0x00000001,
171
172         // We have asked the profiler about this method via ICorProfilerFunctionControl,
173         // and have thus stored the IL and codegen flags the profiler specified.
174         kStateActive = 0x00000002,
175
176         kStateMask = 0x0000000F,
177     };
178
179     RejitFlags GetRejitState() const;
180 #ifndef DACCESS_COMPILE
181     void SetRejitState(RejitFlags newState);
182 #endif
183
184 #ifdef DACCESS_COMPILE
185     // The DAC is privy to the backing node abstraction
186     PTR_ILCodeVersionNode AsNode() const;
187 #endif
188
189 private:
190
191 #ifndef DACCESS_COMPILE
192     PTR_ILCodeVersionNode AsNode();
193     PTR_ILCodeVersionNode AsNode() const;
194 #endif
195
196     enum StorageKind
197     {
198         Unknown,
199         Explicit,
200         Synthetic
201     };
202
203     StorageKind m_storageKind;
204     union
205     {
206         PTR_ILCodeVersionNode m_pVersionNode;
207         struct SyntheticStorage
208         {
209             PTR_Module m_pModule;
210             mdMethodDef m_methodDef;
211         } m_synthetic;
212     };
213 };
214
215
216 class NativeCodeVersionNode
217 {
218     friend NativeCodeVersionIterator;
219     friend MethodDescVersioningState;
220     friend ILCodeVersionNode;
221 public:
222 #ifndef DACCESS_COMPILE
223     NativeCodeVersionNode(NativeCodeVersionId id, MethodDesc* pMethod, ReJITID parentId, NativeCodeVersion::OptimizationTier optimizationTier);
224 #endif
225 #ifdef DEBUG
226     BOOL LockOwnedByCurrentThread() const;
227 #endif
228     PTR_MethodDesc GetMethodDesc() const;
229     NativeCodeVersionId GetVersionId() const;
230     PCODE GetNativeCode() const;
231     ReJITID GetILVersionId() const;
232     ILCodeVersion GetILCodeVersion() const;
233     BOOL IsActiveChildVersion() const;
234 #ifndef DACCESS_COMPILE
235     BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected);
236     void SetActiveChildFlag(BOOL isActive);
237 #endif
238 #ifdef FEATURE_TIERED_COMPILATION
239     NativeCodeVersion::OptimizationTier GetOptimizationTier() const;
240 #endif
241
242 private:
243     //union - could save a little memory?
244     //{
245     PCODE m_pNativeCode;
246     PTR_MethodDesc m_pMethodDesc;
247     //};
248
249     ReJITID m_parentId;
250     PTR_NativeCodeVersionNode m_pNextMethodDescSibling;
251     NativeCodeVersionId m_id;
252 #ifdef FEATURE_TIERED_COMPILATION
253     NativeCodeVersion::OptimizationTier m_optTier;
254 #endif
255
256     enum NativeCodeVersionNodeFlags
257     {
258         IsActiveChildFlag = 1
259     };
260     DWORD m_flags;
261 };
262
263 class NativeCodeVersionCollection
264 {
265     friend class NativeCodeVersionIterator;
266 public:
267     NativeCodeVersionCollection(PTR_MethodDesc pMethodDescFilter, ILCodeVersion ilCodeFilter);
268     NativeCodeVersionIterator Begin();
269     NativeCodeVersionIterator End();
270
271 private:
272     PTR_MethodDesc m_pMethodDescFilter;
273     ILCodeVersion m_ilCodeFilter;
274 };
275
276 class NativeCodeVersionIterator : public Enumerator<const NativeCodeVersion, NativeCodeVersionIterator>
277 {
278     friend class Enumerator<const NativeCodeVersion, NativeCodeVersionIterator>;
279
280 public:
281     NativeCodeVersionIterator(NativeCodeVersionCollection* pCollection);
282     CHECK Check() const { CHECK_OK; }
283
284 protected:
285     const NativeCodeVersion & Get() const;
286     void First();
287     void Next();
288     bool Equal(const NativeCodeVersionIterator &i) const;
289
290     CHECK DoCheck() const { CHECK_OK; }
291
292 private:
293     enum IterationStage
294     {
295         Initial,
296         ImplicitCodeVersion,
297         LinkedList,
298         End
299     };
300     IterationStage m_stage;
301     NativeCodeVersionCollection* m_pCollection;
302     PTR_NativeCodeVersionNode m_pLinkedListCur;
303     NativeCodeVersion m_cur;
304 };
305
306 class ILCodeVersionNode
307 {
308 public:
309     ILCodeVersionNode();
310 #ifndef DACCESS_COMPILE
311     ILCodeVersionNode(Module* pModule, mdMethodDef methodDef, ReJITID id);
312 #endif
313 #ifdef DEBUG
314     BOOL LockOwnedByCurrentThread() const;
315 #endif //DEBUG
316     PTR_Module GetModule() const;
317     mdMethodDef GetMethodDef() const;
318     ReJITID GetVersionId() const;
319     PTR_COR_ILMETHOD GetIL() const;
320     DWORD GetJitFlags() const;
321     const InstrumentedILOffsetMapping* GetInstrumentedILMap() const;
322     ILCodeVersion::RejitFlags GetRejitState() const;
323     PTR_ILCodeVersionNode GetNextILVersionNode() const;
324 #ifndef DACCESS_COMPILE
325     void SetIL(COR_ILMETHOD* pIL);
326     void SetJitFlags(DWORD flags);
327     void SetInstrumentedILMap(SIZE_T cMap, COR_IL_MAP * rgMap);
328     void SetRejitState(ILCodeVersion::RejitFlags newState);
329     void SetNextILVersionNode(ILCodeVersionNode* pNextVersionNode);
330 #endif
331
332 private:
333     PTR_Module m_pModule;
334     mdMethodDef m_methodDef;
335     ReJITID m_rejitId;
336     PTR_ILCodeVersionNode m_pNextILVersionNode;
337     Volatile<ILCodeVersion::RejitFlags> m_rejitState;
338     VolatilePtr<COR_ILMETHOD, PTR_COR_ILMETHOD> m_pIL;
339     Volatile<DWORD> m_jitFlags;
340     InstrumentedILOffsetMapping m_instrumentedILMap;
341 };
342
343 class ILCodeVersionCollection
344 {
345     friend class ILCodeVersionIterator;
346
347 public:
348     ILCodeVersionCollection(PTR_Module pModule, mdMethodDef methodDef);
349     ILCodeVersionIterator Begin();
350     ILCodeVersionIterator End();
351
352 private:
353     PTR_Module m_pModule;
354     mdMethodDef m_methodDef;
355 };
356
357 class ILCodeVersionIterator : public Enumerator<const ILCodeVersion, ILCodeVersionIterator>
358 {
359     friend class Enumerator<const ILCodeVersion, ILCodeVersionIterator>;
360
361 public:
362     ILCodeVersionIterator();
363     ILCodeVersionIterator(const ILCodeVersionIterator & iter);
364     ILCodeVersionIterator(ILCodeVersionCollection* pCollection);
365     CHECK Check() const { CHECK_OK; }
366
367 protected:
368     const ILCodeVersion & Get() const;
369     void First();
370     void Next();
371     bool Equal(const ILCodeVersionIterator &i) const;
372
373     CHECK DoCheck() const { CHECK_OK; }
374
375 private:
376     enum IterationStage
377     {
378         Initial,
379         ImplicitCodeVersion,
380         LinkedList,
381         End
382     };
383     IterationStage m_stage;
384     ILCodeVersion m_cur;
385     PTR_ILCodeVersionNode m_pLinkedListCur;
386     ILCodeVersionCollection* m_pCollection;
387 };
388
389 class MethodDescVersioningState
390 {
391 public:
392     // The size of the code used to jump stamp the prolog
393 #ifdef FEATURE_JUMPSTAMP
394     static const size_t JumpStubSize =
395 #if defined(_X86_) || defined(_AMD64_)
396         5;
397 #else
398 #error "Need to define size of jump-stamp for this platform"
399 #endif
400 #endif // FEATURE_JUMPSTAMP
401
402     MethodDescVersioningState(PTR_MethodDesc pMethodDesc);
403     PTR_MethodDesc GetMethodDesc() const;
404     NativeCodeVersionId AllocateVersionId();
405     PTR_NativeCodeVersionNode GetFirstVersionNode() const;
406
407 #ifndef DACCESS_COMPILE
408 #ifdef FEATURE_JUMPSTAMP
409     HRESULT SyncJumpStamp(NativeCodeVersion nativeCodeVersion, BOOL fEESuspended);
410     HRESULT UpdateJumpTarget(BOOL fEESuspended, PCODE pRejittedCode);
411     HRESULT UndoJumpStampNativeCode(BOOL fEESuspended);
412     HRESULT JumpStampNativeCode(PCODE pCode = NULL);
413 #endif // FEATURE_JUMPSTAMP
414     void LinkNativeCodeVersionNode(NativeCodeVersionNode* pNativeCodeVersionNode);
415 #endif // DACCESS_COMPILE
416
417 #ifdef FEATURE_JUMPSTAMP
418     enum JumpStampFlags
419     {
420         // There is no jump stamp in place on this method (Either because
421         // there is no code at all, or there is code that hasn't been
422         // overwritten with a jump)
423         JumpStampNone = 0x0,
424
425         // The method code has the jump stamp written in, and it points to the Prestub
426         JumpStampToPrestub = 0x1,
427
428         // The method code has the jump stamp written in, and it points to the currently
429         // active code version
430         JumpStampToActiveVersion = 0x2,
431     };
432
433     JumpStampFlags GetJumpStampState();
434     void SetJumpStampState(JumpStampFlags newState);
435 #endif // FEATURE_JUMPSTAMP
436
437     //read-write data for the default native code version
438     BOOL IsDefaultVersionActiveChild() const;
439 #ifndef DACCESS_COMPILE
440     void SetDefaultVersionActiveChildFlag(BOOL isActive);
441 #endif
442
443 private:
444 #if !defined(DACCESS_COMPILE) && defined(FEATURE_JUMPSTAMP)
445     INDEBUG(BOOL CodeIsSaved();)
446     HRESULT UpdateJumpStampHelper(BYTE* pbCode, INT64 i64OldValue, INT64 i64NewValue, BOOL fContentionPossible);
447 #endif
448     PTR_MethodDesc m_pMethodDesc;
449     
450     enum MethodDescVersioningStateFlags
451     {
452         JumpStampMask = 0x3,
453         IsDefaultVersionActiveChildFlag = 0x4
454     };
455     BYTE m_flags;
456     NativeCodeVersionId m_nextId;
457     PTR_NativeCodeVersionNode m_pFirstVersionNode;
458
459
460     // The originally JITted code that was overwritten with the jmp stamp.
461 #ifdef FEATURE_JUMPSTAMP
462     BYTE m_rgSavedCode[JumpStubSize];
463 #endif
464 };
465
466 class MethodDescVersioningStateHashTraits : public NoRemoveSHashTraits<DefaultSHashTraits<PTR_MethodDescVersioningState>>
467 {
468 public:
469     typedef typename DefaultSHashTraits<PTR_MethodDescVersioningState>::element_t element_t;
470     typedef typename DefaultSHashTraits<PTR_MethodDescVersioningState>::count_t count_t;
471
472     typedef const PTR_MethodDesc key_t;
473
474     static key_t GetKey(element_t e)
475     {
476         LIMITED_METHOD_CONTRACT;
477         return e->GetMethodDesc();
478     }
479     static BOOL Equals(key_t k1, key_t k2)
480     {
481         LIMITED_METHOD_CONTRACT;
482         return k1 == k2;
483     }
484     static count_t Hash(key_t k)
485     {
486         LIMITED_METHOD_CONTRACT;
487         return (count_t)(size_t)dac_cast<TADDR>(k);
488     }
489
490     static element_t Null() { LIMITED_METHOD_CONTRACT; return dac_cast<PTR_MethodDescVersioningState>(nullptr); }
491     static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
492 };
493
494 typedef SHash<MethodDescVersioningStateHashTraits> MethodDescVersioningStateHash;
495
496 class ILCodeVersioningState
497 {
498 public:
499     ILCodeVersioningState(PTR_Module pModule, mdMethodDef methodDef);
500     ILCodeVersion GetActiveVersion() const;
501     PTR_ILCodeVersionNode GetFirstVersionNode() const;
502 #ifndef DACCESS_COMPILE
503     void SetActiveVersion(ILCodeVersion ilActiveCodeVersion);
504     void LinkILCodeVersionNode(ILCodeVersionNode* pILCodeVersionNode);
505 #endif
506
507     struct Key
508     {
509     public:
510         Key();
511         Key(PTR_Module pModule, mdMethodDef methodDef);
512         size_t Hash() const;
513         bool operator==(const Key & rhs) const;
514     private:
515         PTR_Module m_pModule;
516         mdMethodDef m_methodDef;
517     };
518
519     Key GetKey() const;
520
521 private:
522     ILCodeVersion m_activeVersion;
523     PTR_ILCodeVersionNode m_pFirstVersionNode;
524     PTR_Module m_pModule;
525     mdMethodDef m_methodDef;
526 };
527
528 class ILCodeVersioningStateHashTraits : public NoRemoveSHashTraits<DefaultSHashTraits<PTR_ILCodeVersioningState>>
529 {
530 public:
531     typedef typename DefaultSHashTraits<PTR_ILCodeVersioningState>::element_t element_t;
532     typedef typename DefaultSHashTraits<PTR_ILCodeVersioningState>::count_t count_t;
533
534     typedef const ILCodeVersioningState::Key key_t;
535
536     static key_t GetKey(element_t e)
537     {
538         LIMITED_METHOD_CONTRACT;
539         return e->GetKey();
540     }
541     static BOOL Equals(key_t k1, key_t k2)
542     {
543         LIMITED_METHOD_CONTRACT;
544         return k1 == k2;
545     }
546     static count_t Hash(key_t k)
547     {
548         LIMITED_METHOD_CONTRACT;
549         return (count_t)k.Hash();
550     }
551
552     static element_t Null() { LIMITED_METHOD_CONTRACT; return dac_cast<PTR_ILCodeVersioningState>(nullptr); }
553     static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
554 };
555
556 typedef SHash<ILCodeVersioningStateHashTraits> ILCodeVersioningStateHash;
557
558
559 class CodeVersionManager
560 {
561     friend class ILCodeVersion;
562     friend class PublishMethodHolder;
563     friend class PublishMethodTableHolder;
564
565 public:
566     CodeVersionManager();
567
568     void PreInit(BOOL fSharedDomain);
569
570     class TableLockHolder : public CrstHolder
571     {
572     public:
573         TableLockHolder(CodeVersionManager * pCodeVersionManager);
574     };
575     //Using the holder is preferable, but in some cases the holder can't be used
576 #ifndef DACCESS_COMPILE
577     void EnterLock();
578     void LeaveLock();
579 #endif
580     
581 #ifdef DEBUG
582     BOOL LockOwnedByCurrentThread() const;
583 #endif
584
585     DWORD GetNonDefaultILVersionCount();
586     ILCodeVersionCollection GetILCodeVersions(PTR_MethodDesc pMethod);
587     ILCodeVersionCollection GetILCodeVersions(PTR_Module pModule, mdMethodDef methodDef);
588     ILCodeVersion GetActiveILCodeVersion(PTR_MethodDesc pMethod);
589     ILCodeVersion GetActiveILCodeVersion(PTR_Module pModule, mdMethodDef methodDef);
590     ILCodeVersion GetILCodeVersion(PTR_MethodDesc pMethod, ReJITID rejitId);
591     NativeCodeVersionCollection GetNativeCodeVersions(PTR_MethodDesc pMethod) const;
592     NativeCodeVersion GetNativeCodeVersion(PTR_MethodDesc pMethod, PCODE codeStartAddress) const;
593     PTR_ILCodeVersioningState GetILCodeVersioningState(PTR_Module pModule, mdMethodDef methodDef) const;
594     PTR_MethodDescVersioningState GetMethodDescVersioningState(PTR_MethodDesc pMethod) const;
595
596 #ifndef DACCESS_COMPILE
597     struct CodePublishError
598     {
599         Module* pModule;
600         mdMethodDef methodDef;
601         MethodDesc* pMethodDesc;
602         HRESULT hrStatus;
603     };
604
605     HRESULT AddILCodeVersion(Module* pModule, mdMethodDef methodDef, ReJITID rejitId, ILCodeVersion* pILCodeVersion);
606     HRESULT AddNativeCodeVersion(ILCodeVersion ilCodeVersion, MethodDesc* pClosedMethodDesc, NativeCodeVersion::OptimizationTier optimizationTier, NativeCodeVersion* pNativeCodeVersion);
607     HRESULT DoJumpStampIfNecessary(MethodDesc* pMD, PCODE pCode);
608     PCODE PublishVersionableCodeIfNecessary(MethodDesc* pMethodDesc, BOOL fCanBackpatchPrestub);
609     HRESULT PublishNativeCodeVersion(MethodDesc* pMethodDesc, NativeCodeVersion nativeCodeVersion, BOOL fEESuspended);
610     HRESULT GetOrCreateMethodDescVersioningState(MethodDesc* pMethod, MethodDescVersioningState** ppMethodDescVersioningState);
611     HRESULT GetOrCreateILCodeVersioningState(Module* pModule, mdMethodDef methodDef, ILCodeVersioningState** ppILCodeVersioningState);
612     HRESULT SetActiveILCodeVersions(ILCodeVersion* pActiveVersions, DWORD cActiveVersions, BOOL fEESuspended, CDynArray<CodePublishError> * pPublishErrors);
613     static HRESULT AddCodePublishError(Module* pModule, mdMethodDef methodDef, MethodDesc* pMD, HRESULT hrStatus, CDynArray<CodePublishError> * pErrors);
614     static HRESULT AddCodePublishError(NativeCodeVersion nativeCodeVersion, HRESULT hrStatus, CDynArray<CodePublishError> * pErrors);
615     static void OnAppDomainExit(AppDomain* pAppDomain);
616 #endif
617
618 private:
619
620 #ifndef DACCESS_COMPILE
621     static HRESULT EnumerateClosedMethodDescs(MethodDesc* pMD, CDynArray<MethodDesc*> * pClosedMethodDescs, CDynArray<CodePublishError> * pUnsupportedMethodErrors);
622     static HRESULT EnumerateDomainClosedMethodDescs(
623         AppDomain * pAppDomainToSearch,
624         Module* pModuleContainingMethodDef,
625         mdMethodDef methodDef,
626         CDynArray<MethodDesc*> * pClosedMethodDescs,
627         CDynArray<CodePublishError> * pUnsupportedMethodErrors);
628     static HRESULT GetNonVersionableError(MethodDesc* pMD);
629     void ReportCodePublishError(CodePublishError* pErrorRecord);
630     void ReportCodePublishError(Module* pModule, mdMethodDef methodDef, MethodDesc* pMD, HRESULT hrStatus);
631 #endif
632
633     //Module,MethodDef -> ILCodeVersioningState
634     ILCodeVersioningStateHash m_ilCodeVersioningStateMap;
635
636     //closed MethodDesc -> MethodDescVersioningState
637     MethodDescVersioningStateHash m_methodDescVersioningStateMap;
638     
639     CrstExplicitInit m_crstTable;
640 };
641
642 #endif // FEATURE_CODE_VERSIONING
643
644 //
645 // These holders are used by runtime code that is making new code
646 // available for execution, either by publishing jitted code
647 // or restoring NGEN code. It ensures the publishing is synchronized
648 // with rejit requests
649 //
650 class PublishMethodHolder
651 {
652 public:
653 #if !defined(FEATURE_CODE_VERSIONING) || defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
654     PublishMethodHolder(MethodDesc* pMethod, PCODE pCode) { }
655 #else
656     PublishMethodHolder(MethodDesc* pMethod, PCODE pCode);
657     ~PublishMethodHolder();
658 #endif
659
660 private:
661 #if defined(FEATURE_CODE_VERSIONING)
662     MethodDesc * m_pMD;
663     HRESULT m_hr;
664 #endif
665 };
666
667 class PublishMethodTableHolder
668 {
669 public:
670 #if !defined(FEATURE_CODE_VERSIONING) || defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
671     PublishMethodTableHolder(MethodTable* pMethodTable) { }
672 #else
673     PublishMethodTableHolder(MethodTable* pMethodTable);
674     ~PublishMethodTableHolder();
675 #endif
676
677 private:
678 #if defined(FEATURE_CODE_VERSIONING) && !defined(DACCESS_COMPILE)
679     MethodTable* m_pMethodTable;
680     CDynArray<CodeVersionManager::CodePublishError> m_errors;
681 #endif
682 };
683
684 #endif // CODE_VERSION_H