Remove undefined and unused getPersonalityValue function from CEECompileInfo (#15482)
[platform/upstream/coreclr.git] / src / vm / compile.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: compile.h
6 //
7 // Interfaces and support for zap compiler and zap files
8 // 
9
10 // ===========================================================================
11
12
13 /*
14
15 The preloader is used to serialize internal EE data structures in the
16 zapped image.  The object model looks like the following:
17
18                     +--------------------+
19                     |                    |
20                     |    ZapperModule    |
21                     |                    |
22                     +--------------------+
23                               |
24                               *    
25                      ICorCompileDataStore           Zapper
26                     
27            =====================================================      
28                     
29                      ICorCompilePreloader           EE
30                               * 
31                               | 
32                     +--------------------+
33                     |                    |
34                     |    CEEPreloader    |
35                     |                    |
36                     +--------------------+                    
37                               |
38                               *    
39                      DataImage::IDataStore                    
40                     
41                                                  
42                     +--------------------+
43                     |                    |
44                     |     DataImage      |
45                     |                    |
46                     +--------------------+
47                     
48 ZapperModule - Created by the zapper for each module.  It implements the
49                ICorCompileDataStore interface that the preloader uses to
50                allocate space for the EE data structures.  Currently it
51                allocates space in a single PE section (though the DataImage
52                has logic to further subdivide the space into subsections).
53   
54 CEEPreloader - Created by ZapperModule in order to serialize EE
55                data structures.  It implements two interfaces.  
56                ICorCompilePreloader is used by ZapperModule to inquire
57                about the offsets of various EE data structures inside
58                the preloader section.  DataImage::IDataStore is used
59                by DataImage to manage the PE section memory, and the
60                implementation in the CEEPreloader mostly forwards the calls
61                to the zapper (ICorCompileDataStore).
62
63 DataImage    - Created by CEEPreloader to keep track of memory used by
64                EE data structures.  Even though it uses only one PE
65                section, it allows the EE to allocate memory in multiple
66                subsections.  This is accomplished by splitting the work into
67                three phases (there are comments in dataimage.h that explain
68                this in detail).
69                
70
71 The CEEPreloader is created when ZapperModule::Preload calls
72 m_zapper->m_pEECompileInfo->PreloadModule.  PreloadModule creates
73 the CEEPreloader and then calls its Preload method, which explicitely
74 loads all the EE objects into memory (Module::ExpandAll), and then
75 allocates space for them in the preloader section (Module::Save).
76
77 Each EE data structure that needs to be serialized implements a Save
78 method.  A Save method is required to:
79 1) Store all of its data (including strings and other buffers that it
80    uses) in the preloader section.  This is accomplished by calling on
81    one of the DataImage storage methods (such as DataImage::StoreStructure).
82 2) Call the Save method on the objects that it owns.  The interesting
83    part of the hierarchy looks like:
84    
85    Module::Save
86      MethodTable::Save (in profile order)
87        EEClass::Save
88          MethodDescChunk::Save (method desc chunks can be split into hot 
89                                 and cold based on profile info)
90            MethodDesc::Save
91            
92 Note that while the architecture requires the data structures in the
93 preloader sections to look like their EE counterparts, it is possible
94 to work around that limitation by constructing multiple submappings of
95 these data structures.  Sometimes the submappings require a change to the actual
96 data (i.e. each method desc has information that tells you how far it is
97 from the MethodDescChunk, and that needs to change when reordering method
98 descs).  In such cases you create new copies of that memory and construct
99 a regular copying map for each of the new updated copies (DataImage::StoreStructure),
100 and a pointer update map for each of the original EE data structures 
101 (DataImage::StoreStructureUsingSurrogate).  See MethodDescChunk::Save for
102 an example on how to do this.
103
104 Fixups:  once everything has been layout out in memory, the ZapperModule
105 calls CEEPreloader::Link to generate fixups for the data.  CEEPreloader::Link
106 calls Module::Fixup, which results in a data structure walk very similar to
107 that of Module::Save.  Each data structure calls one of the FixupPointerField
108 methods on the DataImage, which in turn forwards the call to
109 CEEPreloader::AddFixup, which forwards it to the zapper 
110 (ZapperModule::AddFixup).
111    
112 */
113
114 #ifndef COMPILE_H_
115 #define COMPILE_H_
116
117 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
118
119 struct ZapperLoaderModuleTableKey {
120     ZapperLoaderModuleTableKey(Module *pDefinitionModule, 
121         mdToken token, 
122         Instantiation classInst,
123         Instantiation methodInst)
124         : m_inst(classInst, methodInst)
125     { WRAPPER_NO_CONTRACT;
126       this->m_pDefinitionModule = pDefinitionModule;
127       this->m_token = token;  }
128     
129     Module *m_pDefinitionModule;
130     mdToken m_token;
131     SigTypeContext m_inst;
132 } ;
133
134 struct ZapperLoaderModuleTableEntry {
135     ZapperLoaderModuleTableEntry(): key(0,0,Instantiation(),Instantiation()) { WRAPPER_NO_CONTRACT; this->result = 0; }
136     ZapperLoaderModuleTableEntry(const ZapperLoaderModuleTableKey &_key,Module *_result) 
137         : key(_key)
138     { this->result = _result; }
139     
140     ZapperLoaderModuleTableKey key;
141     Module *result;
142 } ;
143
144 class ZapperLoaderModuleTableTraits : public NoRemoveSHashTraits<DefaultSHashTraits<ZapperLoaderModuleTableEntry> >
145 {
146     
147 public:
148     typedef const ZapperLoaderModuleTableKey *key_t;
149     static const ZapperLoaderModuleTableKey * GetKey(const ZapperLoaderModuleTableEntry &e) { return &e.key; }
150     static count_t Hash(const ZapperLoaderModuleTableKey * k) 
151     { 
152         LIMITED_METHOD_CONTRACT;
153         
154         DWORD dwHash = 5381;
155         
156         dwHash = ((dwHash << 5) + dwHash) ^ (unsigned int)(SIZE_T)k->m_pDefinitionModule;
157         dwHash = ((dwHash << 5) + dwHash) ^ (unsigned int)(SIZE_T)k->m_token;
158         dwHash = ((dwHash << 5) + dwHash) ^ EEInstantiationHashTableHelper:: Hash(&k->m_inst);
159         return dwHash;
160     }
161     
162     static BOOL Equals(const ZapperLoaderModuleTableKey *e1, const ZapperLoaderModuleTableKey *e2)
163     {
164         WRAPPER_NO_CONTRACT;
165         return e1->m_pDefinitionModule == e2->m_pDefinitionModule && 
166             e1->m_token == e2->m_token && 
167             SigTypeContext::Equal(&e1->m_inst, &e2->m_inst);
168     }
169     static const ZapperLoaderModuleTableEntry Null() 
170     { return ZapperLoaderModuleTableEntry(); }
171     
172     static bool IsNull(const ZapperLoaderModuleTableEntry &e) 
173     { LIMITED_METHOD_CONTRACT; return e.key.m_pDefinitionModule == 0 && e.key.m_token == 0 && e.key.m_inst.IsEmpty(); }
174     
175 };
176
177
178 typedef  SHash<ZapperLoaderModuleTableTraits> ZapperLoaderModuleTable;
179
180 class CEECompileInfo : public ICorCompileInfo
181 {
182   public:
183     virtual ~CEECompileInfo()
184     {
185         WRAPPER_NO_CONTRACT;
186     }
187     
188     HRESULT Startup(     BOOL                     fForceDebug, 
189                          BOOL                     fForceProfiling,
190                          BOOL                     fForceInstrument);
191
192     HRESULT CreateDomain(ICorCompilationDomain **ppDomain,
193                          IMetaDataAssemblyEmit    *pEmitter,
194                          BOOL                     fForceDebug,
195                          BOOL                     fForceProfiling,
196                          BOOL                     fForceInstrument,
197                          BOOL                     fForceFulltrustDomain);
198
199     HRESULT MakeCrossDomainCallback(
200                                     ICorCompilationDomain*  pDomain,
201                                     CROSS_DOMAIN_CALLBACK   pfnCallback,
202                                     LPVOID                  pArgs);
203    
204     HRESULT DestroyDomain(ICorCompilationDomain   *pDomain);
205
206     HRESULT LoadAssemblyByPath(LPCWSTR                  wzPath,
207                                BOOL                     fExplicitBindToNativeImage,
208                                CORINFO_ASSEMBLY_HANDLE *pHandle);
209
210
211 #ifdef FEATURE_COMINTEROP
212     HRESULT LoadTypeRefWinRT(IMDInternalImport       *pAssemblyImport,
213                                      mdTypeRef               ref,
214                                      CORINFO_ASSEMBLY_HANDLE *pHandle);
215 #endif
216
217     BOOL IsInCurrentVersionBubble(CORINFO_MODULE_HANDLE hModule);
218
219     HRESULT LoadAssemblyModule(CORINFO_ASSEMBLY_HANDLE assembly,
220                                mdFile                  file,
221                                CORINFO_MODULE_HANDLE   *pHandle);
222
223
224     BOOL CheckAssemblyZap(
225         CORINFO_ASSEMBLY_HANDLE assembly, 
226       __out_ecount_opt(*cAssemblyManifestModulePath) 
227         LPWSTR                  assemblyManifestModulePath, 
228         LPDWORD                 cAssemblyManifestModulePath);
229
230     HRESULT SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE     assembly,
231                                  CORINFO_MODULE_HANDLE       module);
232
233     IMDInternalImport * GetAssemblyMetaDataImport(CORINFO_ASSEMBLY_HANDLE scope);
234
235     IMDInternalImport * GetModuleMetaDataImport(CORINFO_MODULE_HANDLE scope);
236
237     CORINFO_MODULE_HANDLE GetAssemblyModule(CORINFO_ASSEMBLY_HANDLE module);
238
239     CORINFO_ASSEMBLY_HANDLE GetModuleAssembly(CORINFO_MODULE_HANDLE module);
240
241     PEDecoder * GetModuleDecoder(CORINFO_MODULE_HANDLE scope);
242
243     void GetModuleFileName(CORINFO_MODULE_HANDLE module,
244                            SString               &result);
245
246     void EncodeModuleAsIndexes( CORINFO_MODULE_HANDLE   fromHandle,
247                                 CORINFO_MODULE_HANDLE   handle,
248                                 DWORD                   *pAssemblyIndex,
249                                 DWORD                   *pModuleIndex,
250                                 IMetaDataAssemblyEmit   *pAssemblyEmit); 
251
252     void EncodeClass(  CORINFO_MODULE_HANDLE   referencingModule,
253                        CORINFO_CLASS_HANDLE    classHandle,
254                        SigBuilder              *pSigBuilder,
255                        LPVOID                  encodeContext,
256                        ENCODEMODULE_CALLBACK   pfnEncodeModule);
257
258     void EncodeMethod( CORINFO_MODULE_HANDLE   referencingModule,
259                        CORINFO_METHOD_HANDLE   methHnd,
260                        SigBuilder              *pSigBuilder,
261                        LPVOID                  encodeContext,
262                        ENCODEMODULE_CALLBACK   pfnEncodeModule,
263                        CORINFO_RESOLVED_TOKEN  *pResolvedToken,
264                        CORINFO_RESOLVED_TOKEN  *pConstrainedResolvedToken,
265                        BOOL                    fEncodeUsingResolvedTokenSpecStreams);
266
267     virtual mdToken TryEncodeMethodAsToken(CORINFO_METHOD_HANDLE handle, 
268                                            CORINFO_RESOLVED_TOKEN * pResolvedToken,
269                                            CORINFO_MODULE_HANDLE * referencingModule);
270
271     virtual DWORD TryEncodeMethodSlot(CORINFO_METHOD_HANDLE handle);
272
273     void EncodeField(  CORINFO_MODULE_HANDLE   referencingModule,
274                        CORINFO_FIELD_HANDLE    handle,
275                        SigBuilder              *pSigBuilder,
276                        LPVOID                  encodeContext,
277                        ENCODEMODULE_CALLBACK   pfnEncodeModule,
278                        CORINFO_RESOLVED_TOKEN  *pResolvedToken,
279                        BOOL                    fEncodeUsingResolvedTokenSpecStreams);
280
281     // Encode generic dictionary signature
282     virtual void EncodeGenericSignature(
283             LPVOID signature,
284             BOOL fMethod,
285             SigBuilder * pSigBuilder,
286             LPVOID encodeContext,
287             ENCODEMODULE_CALLBACK pfnEncodeModule);
288
289
290     BOOL IsEmptyString(mdString token,
291                        CORINFO_MODULE_HANDLE module);
292
293     BOOL IsNativeCallableMethod(CORINFO_METHOD_HANDLE handle);
294
295     BOOL IsCachingOfInliningHintsEnabled()
296     {
297         return m_fCachingOfInliningHintsEnabled;
298     }
299
300     void DisableCachingOfInliningHints()
301     {
302         m_fCachingOfInliningHintsEnabled = FALSE;
303     }
304
305     HRESULT GetTypeDef(   CORINFO_CLASS_HANDLE    classHandle,
306                           mdTypeDef               *token);
307     HRESULT GetMethodDef( CORINFO_METHOD_HANDLE   methodHandle,
308                           mdMethodDef             *token);
309     HRESULT GetFieldDef(  CORINFO_FIELD_HANDLE    fieldHandle,
310                           mdFieldDef              *token);
311
312     void SetAssemblyHardBindList(__in_ecount( cHardBindList )
313                                  LPWSTR *pHardBindList,
314                                  DWORD cHardBindList);
315
316     CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib();
317     CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableType(CORINFO_CLASS_HANDLE classHandle);
318     CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableMethod(CORINFO_METHOD_HANDLE methodHandle);
319     CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableField(CORINFO_FIELD_HANDLE fieldHandle);
320
321     ICorCompilePreloader * PreloadModule(CORINFO_MODULE_HANDLE   moduleHandle,
322                                     ICorCompileDataStore    *pData,
323                                     CorProfileData          *profileData);
324
325     
326     HRESULT GetLoadHint(CORINFO_ASSEMBLY_HANDLE   hAssembly,
327                         CORINFO_ASSEMBLY_HANDLE hAssemblyDependency,
328                         LoadHintEnum           *loadHint,
329                         LoadHintEnum           *defaultLoadHint);
330
331     HRESULT GetAssemblyVersionInfo(CORINFO_ASSEMBLY_HANDLE Handle, 
332                                     CORCOMPILE_VERSION_INFO *pInfo);
333
334     void GetAssemblyCodeBase(CORINFO_ASSEMBLY_HANDLE hAssembly,
335                              SString                &result);
336
337     void GetCallRefMap(CORINFO_METHOD_HANDLE hMethod, 
338                        GCRefMapBuilder * pBuilder);
339
340     void CompressDebugInfo(
341                                     IN ICorDebugInfo::OffsetMapping * pOffsetMapping,
342                                     IN ULONG            iOffsetMapping,
343                                     IN ICorDebugInfo::NativeVarInfo * pNativeVarInfo,
344                                     IN ULONG            iNativeVarInfo,
345                                     IN OUT SBuffer    * pDebugInfoBuffer);
346
347     HRESULT SetVerboseLevel(
348                                     IN  VerboseLevel        level);
349
350     HRESULT GetBaseJitFlags(
351             IN  CORINFO_METHOD_HANDLE    hMethod,
352             OUT CORJIT_FLAGS            *pFlags);
353
354     void* GetStubSize(void *pStubAddress, DWORD *pSizeToCopy);
355
356     HRESULT GetStubClone(void *pStub, BYTE *pBuffer, DWORD dwBufferSize);
357
358     BOOL GetIsGeneratingNgenPDB();
359     void SetIsGeneratingNgenPDB(BOOL fGeneratingNgenPDB);
360
361 #ifdef FEATURE_READYTORUN_COMPILER
362     CORCOMPILE_FIXUP_BLOB_KIND GetFieldBaseOffset(
363             CORINFO_CLASS_HANDLE classHnd, 
364             DWORD * pBaseOffset);
365
366     BOOL NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd);
367     void EncodeTypeLayout(CORINFO_CLASS_HANDLE classHandle, SigBuilder * pSigBuilder);
368
369     BOOL AreAllClassesFullyLoaded(CORINFO_MODULE_HANDLE moduleHandle);
370
371     int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
372
373     int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
374 #endif
375
376     BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
377
378     //--------------------------------------------------------------------
379     // ZapperLoaderModules and the ZapperLoaderModuleTable
380     //
381     // When NGEN'ing we want to adjust the
382     // places where some items (i.e. generic instantiations) are placed, in order to get some of them
383     // placed into the module we are compiling.  However, the
384     // results of ComputeLoaderModule must be stable for the duration
385     // of an entire instance of the VM, i.e. for the duration of a compilation 
386     // process.  Thus each time we place an item into a non-standard LoaderModule we record 
387     // that fact.
388
389     Module *LookupZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey)
390     {
391         WRAPPER_NO_CONTRACT;
392         const ZapperLoaderModuleTableEntry *pEntry = m_ZapperLoaderModuleTable.LookupPtr(pKey);
393         if (pEntry)
394             return pEntry->result;
395         return NULL;
396     }
397
398     void RecordZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey,
399                                   Module *pZapperLoaderModuleTable)
400     {
401         CONTRACTL
402         {
403             THROWS;
404             GC_NOTRIGGER;
405             SO_TOLERANT;
406             MODE_ANY;
407         }
408         CONTRACTL_END;
409         ZapperLoaderModuleTableEntry entry(*pKey, pZapperLoaderModuleTable);
410         m_ZapperLoaderModuleTable.Add(entry);
411     }
412
413     ZapperLoaderModuleTable m_ZapperLoaderModuleTable;
414     
415 private:
416     BOOL m_fCachingOfInliningHintsEnabled;
417     BOOL m_fGeneratingNgenPDB;
418 };
419
420 extern CEECompileInfo *g_pCEECompileInfo;
421
422 BOOL IsNgenPDBCompilationProcess();
423
424 //
425 // See comment at top of file for an explanation on the preloader
426 // architecture.
427 //
428
429 class CEEPreloader : public ICorCompilePreloader
430 {
431   private:
432     DataImage              *m_image;
433     ICorCompileDataStore   *m_pData;
434
435     class MethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodDesc *> >
436     {
437     public:
438         typedef MethodDesc *key_t;
439         static MethodDesc * GetKey(MethodDesc *md) { return md; }
440         static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
441         static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
442         {
443             return md1 == md2;
444         }
445     };
446
447     class TypeSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<TypeHandle> >
448     {
449     public:
450         typedef TypeHandle key_t;
451         static const TypeHandle Null() { return TypeHandle(); }
452         static bool IsNull(const TypeHandle &th) { return !!th.IsNull(); }
453         static TypeHandle GetKey(TypeHandle th) { return th; }
454         static count_t Hash(TypeHandle th) { return (count_t) th.AsTAddr(); }
455         static BOOL Equals(TypeHandle th1, TypeHandle th2) { return th1 == th2; }
456     };
457
458     // Cached results of instantiations triage
459     SHash<TypeSetTraits>    m_acceptedTypes;
460     SHash<MethodSetTraits>  m_acceptedMethods;
461     SHash<TypeSetTraits>    m_rejectedTypes;
462     SHash<MethodSetTraits>  m_rejectedMethods;
463
464 #ifdef FEATURE_FULL_NGEN
465     // Tentatively accepted instantiations
466     InlineSArray<TypeHandle, 20>    m_speculativeTypes;
467     BOOL                            m_fSpeculativeTriage;
468     BOOL                            m_fDictionariesPopulated;
469 #endif
470
471     struct CompileMethodEntry
472     {
473         MethodDesc * pMD;
474 #ifndef FEATURE_FULL_NGEN // Unreferenced methods
475         bool fReferenced; // true when this method was referenced by other code
476         bool fScheduled;  // true when this method was scheduled for compilation
477 #endif
478     };
479
480     class CompileMethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<CompileMethodEntry> >
481     {
482     public:
483         typedef MethodDesc *key_t;
484         static MethodDesc * GetKey(CompileMethodEntry e) { return e.pMD; }
485         static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
486         static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
487         {
488             return md1 == md2;
489         }
490         static const CompileMethodEntry Null() { CompileMethodEntry e; e.pMD = NULL; return e; }
491         static bool IsNull(const CompileMethodEntry &e) { return e.pMD == NULL; }
492     };
493
494     SHash<CompileMethodSetTraits> m_compileMethodsHash;
495
496     // Array of methods that we need to compile.
497     SArray<MethodDesc*> m_uncompiledMethods;
498
499     int m_methodCompileLimit;
500
501     void AppendUncompiledMethod(MethodDesc *pMD)
502     {
503         STANDARD_VM_CONTRACT;
504         if (m_methodCompileLimit > 0)
505         {
506             m_uncompiledMethods.Append(pMD);
507             m_methodCompileLimit--;
508         }
509     }
510
511     struct DuplicateMethodEntry
512     {
513         MethodDesc * pMD;
514         MethodDesc * pDuplicateMD;
515     };
516
517     class DuplicateMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<DuplicateMethodEntry> >
518     {
519     public:
520         typedef MethodDesc *key_t;
521         static MethodDesc * GetKey(DuplicateMethodEntry e) { return e.pMD; }
522         static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
523         static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
524         {
525             return md1 == md2;
526         }
527         static const DuplicateMethodEntry Null() { DuplicateMethodEntry e; e.pMD = NULL; return e; }
528         static bool IsNull(const DuplicateMethodEntry &e) { return e.pMD == NULL; }
529     };
530
531     SHash<DuplicateMethodTraits> m_duplicateMethodsHash;
532
533     MethodDesc * CompileMethodStubIfNeeded(
534             MethodDesc *pMD,
535             MethodDesc *pStubMD,
536             ICorCompilePreloader::CORCOMPILE_CompileStubCallback pfnCallback,
537             LPVOID pCallbackContext);
538
539   public:
540     CEEPreloader(Module *pModule,
541                  ICorCompileDataStore *pData);
542     virtual ~CEEPreloader();
543
544     void Preload(CorProfileData * profileData);
545     DataImage * GetDataImage() { LIMITED_METHOD_CONTRACT; return m_image; }
546     ICorCompileDataStore * GetDataStore() { LIMITED_METHOD_CONTRACT; return m_pData; }
547
548     //
549     // ICorCompilerPreloader
550     //
551
552     DWORD MapMethodEntryPoint(CORINFO_METHOD_HANDLE handle);
553     DWORD MapClassHandle(CORINFO_CLASS_HANDLE handle);
554     DWORD MapMethodHandle(CORINFO_METHOD_HANDLE handle);
555     DWORD MapFieldHandle(CORINFO_FIELD_HANDLE handle);
556     DWORD MapAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
557     DWORD MapGenericHandle(CORINFO_GENERIC_HANDLE handle);    
558     DWORD MapModuleIDHandle(CORINFO_MODULE_HANDLE handle);
559
560     void AddMethodToTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
561     void AddTypeToTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
562     BOOL IsMethodInTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
563     BOOL IsTypeInTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
564
565     void MethodReferencedByCompiledCode(CORINFO_METHOD_HANDLE handle);
566
567     BOOL IsUncompiledMethod(CORINFO_METHOD_HANDLE handle);
568
569 private:
570     void AddToUncompiledMethods(MethodDesc *pMethod, BOOL fForStubs);
571
572     void ApplyTypeDependencyProductionsForType(TypeHandle t);
573     void ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceMT, TypeHandle elemTypeHnd);
574
575     friend class Module;
576     void TriageTypeForZap(TypeHandle th, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
577     void TriageMethodForZap(MethodDesc* pMethod, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
578
579     void ExpandTypeDependencies(TypeHandle th);
580     void ExpandMethodDependencies(MethodDesc * pMD);
581
582     void TriageTypeSpecsFromSoftBoundModule(Module * pSoftBoundModule);
583     void TriageTypeFromSoftBoundModule(TypeHandle th, Module * pSoftBoundModule);
584     void TriageSpeculativeType(TypeHandle th);
585     void TriageSpeculativeInstantiations();
586
587     // Returns TRUE if new types or methods have been added by the triage
588     BOOL TriageForZap(BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
589
590 public:
591     CORINFO_METHOD_HANDLE NextUncompiledMethod();
592
593     void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
594
595     void GenerateMethodStubs(
596             CORINFO_METHOD_HANDLE hMethod,
597             bool                  fNgenProfileImage,
598             CORCOMPILE_CompileStubCallback pfnCallback,
599             LPVOID                pCallbackContext);
600
601     bool IsDynamicMethod(CORINFO_METHOD_HANDLE hMethod);
602     void SetMethodProfilingFlags(CORINFO_METHOD_HANDLE hMethod, DWORD flags);
603
604     bool CanSkipMethodPreparation (
605             CORINFO_METHOD_HANDLE   callerHnd,      /* IN  */
606             CORINFO_METHOD_HANDLE   calleeHnd,      /* IN  */
607             CorInfoIndirectCallReason *pReason = NULL,
608             CORINFO_ACCESS_FLAGS    accessFlags = CORINFO_ACCESS_ANY);
609
610     BOOL CanEmbedClassID     (CORINFO_CLASS_HANDLE    typeHandle);
611     BOOL CanEmbedModuleID    (CORINFO_MODULE_HANDLE   moduleHandle);    
612     BOOL CanEmbedModuleHandle(CORINFO_MODULE_HANDLE   moduleHandle);
613     BOOL CanEmbedClassHandle (CORINFO_CLASS_HANDLE    typeHandle);
614     BOOL CanEmbedMethodHandle(CORINFO_METHOD_HANDLE   methodHandle, 
615                               CORINFO_METHOD_HANDLE   contextHandle);
616     BOOL CanEmbedFieldHandle (CORINFO_FIELD_HANDLE    fieldHandle);
617
618     BOOL CanPrerestoreEmbedClassHandle (CORINFO_CLASS_HANDLE  classHnd);
619     BOOL CanPrerestoreEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHnd);
620
621     BOOL CanEmbedFunctionEntryPoint(CORINFO_METHOD_HANDLE   methodHandle,
622                                     CORINFO_METHOD_HANDLE   contextHandle,
623                                     CORINFO_ACCESS_FLAGS    accessFlags = CORINFO_ACCESS_ANY);
624
625     BOOL DoesMethodNeedRestoringBeforePrestubIsRun(CORINFO_METHOD_HANDLE   methodHandle);
626
627     BOOL CanSkipDependencyActivation(CORINFO_METHOD_HANDLE   context,
628                                      CORINFO_MODULE_HANDLE   moduleFrom,
629                                      CORINFO_MODULE_HANDLE   moduleTo);
630
631     CORINFO_MODULE_HANDLE GetPreferredZapModuleForClassHandle(CORINFO_CLASS_HANDLE classHnd);
632
633     void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
634
635     CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token);
636     bool GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo);
637
638     CorCompileILRegion GetILRegion(mdMethodDef token);
639
640     CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
641
642     void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee);
643     
644     void Link();
645     void FixupRVAs();
646
647     void SetRVAsForFields(IMetaDataEmit * pEmit);
648
649     void GetRVAFieldData(mdFieldDef fd, PVOID * ppData, DWORD * pcbSize, DWORD * pcbAlignment);
650
651     ULONG Release();
652
653 #ifdef FEATURE_READYTORUN_COMPILER
654     void GetSerializedInlineTrackingMap(SBuffer* pBuffer);
655 #endif
656
657     void Error(mdToken token, Exception * pException);
658 };
659
660
661 struct RefCache
662 {
663     RefCache(Module *pModule)
664     {
665         CONTRACTL
666         {
667             NOTHROW;
668             GC_NOTRIGGER;
669             FORBID_FAULT;
670         }
671         CONTRACTL_END
672
673
674         m_pModule = pModule;
675
676         {
677             // HashMap::Init can throw due to OOM. Our ctor can't. Since this whole
678             // thing is for use inside CEECompileInfo methods, it doesn't make sense to
679             // use an exception model. Thus we probably have to move the hashmap init
680             // calls out of the ctor so can catch these exceptions and translate them to
681             // hresults.
682             // 
683             CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
684
685             m_sAssemblyRefMap.Init(FALSE,NULL);
686         }
687     }
688
689     Module *m_pModule;
690
691     HashMap m_sAssemblyRefMap;
692 };
693
694 struct AssemblySpecDefRefMapEntry {
695     AssemblySpec * m_pDef;
696     AssemblySpec * m_pRef;
697 };
698
699 class AssemblySpecDefRefMapTraits : public NoRemoveSHashTraits<DefaultSHashTraits<AssemblySpecDefRefMapEntry> >
700 {
701 public:
702     typedef const AssemblySpec *key_t;
703     static const AssemblySpec * GetKey(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef; }
704
705     static count_t Hash(const AssemblySpec * k)
706     {
707         return const_cast<AssemblySpec *>(k)->Hash();
708     }
709
710     static BOOL Equals(const AssemblySpec * lhs, const AssemblySpec * rhs)
711     {
712         return const_cast<AssemblySpec *>(lhs)->CompareEx(const_cast<AssemblySpec *>(rhs), AssemblySpec::ASC_DefinitionEquality);
713     }
714
715     static const AssemblySpecDefRefMapEntry Null() { AssemblySpecDefRefMapEntry e; e.m_pDef = NULL; return e; }
716     static bool IsNull(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef == NULL; }
717
718     void OnDestructPerEntryCleanupAction(const AssemblySpecDefRefMapEntry& e)
719     {
720         WRAPPER_NO_CONTRACT;
721         delete e.m_pDef;
722         delete e.m_pRef;
723     }
724     static const bool s_DestructPerEntryCleanupAction = true;
725 };
726
727 typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
728
729 class CompilationDomain : public AppDomain, 
730                           public ICorCompilationDomain
731 {
732
733  public:
734     BOOL                    m_fForceDebug; 
735     BOOL                    m_fForceProfiling;
736     BOOL                    m_fForceInstrument;
737
738     // TODO:  During ngen, we need to determine whether we can call NeedsRestore
739     // before the preloader has been initialized.  This is accomplished via this
740     // method.  This code needs to be cleaned up.  See bug #284709 for background.
741     BOOL canCallNeedsRestore() { return  (m_pTargetImage != NULL); };
742
743     // DDB 175659: Make sure that canCallNeedsRestore() returns FALSE during compilation 
744     // domain shutdown.
745     void setCannotCallNeedsRestore() { m_pTargetImage = NULL; }
746     
747   private:
748
749     Assembly                *m_pTargetAssembly;     // Assembly being compiled
750     Module                  *m_pTargetModule;       // Module currently being compiled. Needed for multi-module assemblies
751     DataImage               *m_pTargetImage;        // Data image
752     CEEPreloader            *m_pTargetPreloader;
753
754     ReleaseHolder<IMetaDataAssemblyEmit>    m_pEmit;
755
756     NewHolder<AssemblySpecHash>             m_pDependencyRefSpecs;
757
758     AssemblySpecMapDefRefMapTable           m_dependencyDefRefMap;
759
760     CORCOMPILE_DEPENDENCY   *m_pDependencies;
761     USHORT                   m_cDependenciesCount, m_cDependenciesAlloc;
762
763     CQuickArray<RefCache*> m_rRefCaches;
764
765     HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
766     void ReleaseDependencyEmitter();
767
768
769   public:
770
771 #ifndef DACCESS_COMPILE
772     CompilationDomain(BOOL fForceDebug = FALSE, 
773                       BOOL fForceProfiling = FALSE,
774                       BOOL fForceInstrument = FALSE);
775     ~CompilationDomain();
776 #endif
777
778     void Init();
779
780     HRESULT AddDependency(AssemblySpec *pRefSpec, PEAssembly *pFile);
781
782     AssemblySpec* FindAssemblyRefSpecForDefSpec(
783         AssemblySpec* pDefSpec);
784
785     PEAssembly *BindAssemblySpec(
786         AssemblySpec *pSpec,
787         BOOL fThrowOnFileNotFound,
788         BOOL fRaisePrebindEvents,
789         StackCrawlMark *pCallerStackMark = NULL,
790         BOOL fUseHostBinderIfAvailable = TRUE) DAC_EMPTY_RET(NULL);
791
792     BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
793
794
795
796     // Returns NULL on out-of-memory
797     RefCache *GetRefCache(Module *pModule)
798     {
799         CONTRACTL
800         {
801             NOTHROW;
802             GC_NOTRIGGER;
803             INJECT_FAULT(return NULL;);
804         }
805         CONTRACTL_END
806
807         unsigned uSize = (unsigned) m_rRefCaches.Size();
808         for (unsigned i = 0; i < uSize; i++)
809             if (m_rRefCaches[i]->m_pModule == pModule)
810                 return m_rRefCaches[i];
811
812         // Add a new cache entry
813         HRESULT hr;
814         
815         if (FAILED(hr = m_rRefCaches.ReSizeNoThrow(uSize + 1)))
816         {
817             _ASSERTE(hr == E_OUTOFMEMORY);
818             return NULL;
819         }
820         
821         m_rRefCaches[uSize] = new (nothrow) RefCache(pModule);
822         return m_rRefCaches[uSize];
823     }
824
825     void SetTarget(Assembly * pAssembly, Module *pModule);
826     
827     void SetTargetImage(DataImage * pImage, CEEPreloader * pPreloader);
828     DataImage * GetTargetImage() { LIMITED_METHOD_CONTRACT; return m_pTargetImage; }
829
830     Assembly * GetTargetAssembly()
831         { LIMITED_METHOD_CONTRACT; return m_pTargetAssembly; }
832     Module * GetTargetModule()
833         { LIMITED_METHOD_CONTRACT; return m_pTargetModule; }
834
835     // ICorCompilationDomain
836
837     HRESULT SetContextInfo(LPCWSTR exePath, BOOL isExe) DAC_EMPTY_RET(E_FAIL);
838     HRESULT GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
839                             DWORD *cDependencies) DAC_EMPTY_RET(E_FAIL);
840
841 #ifdef CROSSGEN_COMPILE
842     HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
843 #endif
844
845     void SetDependencyEmitter(IMetaDataAssemblyEmit *pEmitter);
846 };
847
848 #endif // FEATURE_NATIVE_IMAGE_GENERATION
849
850 #endif // COMPILE_H_