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 // ===========================================================================
7 // Interfaces and support for zap compiler and zap files
10 // ===========================================================================
15 The preloader is used to serialize internal EE data structures in the
16 zapped image. The object model looks like the following:
18 +--------------------+
22 +--------------------+
25 ICorCompileDataStore Zapper
27 =====================================================
29 ICorCompilePreloader EE
32 +--------------------+
36 +--------------------+
42 +--------------------+
46 +--------------------+
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).
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).
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
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).
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:
86 MethodTable::Save (in profile order)
88 MethodDescChunk::Save (method desc chunks can be split into hot
89 and cold based on profile info)
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.
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).
117 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
119 struct ZapperLoaderModuleTableKey {
120 ZapperLoaderModuleTableKey(Module *pDefinitionModule,
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; }
129 Module *m_pDefinitionModule;
131 SigTypeContext m_inst;
134 struct ZapperLoaderModuleTableEntry {
135 ZapperLoaderModuleTableEntry(): key(0,0,Instantiation(),Instantiation()) { WRAPPER_NO_CONTRACT; this->result = 0; }
136 ZapperLoaderModuleTableEntry(const ZapperLoaderModuleTableKey &_key,Module *_result)
138 { this->result = _result; }
140 ZapperLoaderModuleTableKey key;
144 class ZapperLoaderModuleTableTraits : public NoRemoveSHashTraits<DefaultSHashTraits<ZapperLoaderModuleTableEntry> >
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)
152 LIMITED_METHOD_CONTRACT;
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);
162 static BOOL Equals(const ZapperLoaderModuleTableKey *e1, const ZapperLoaderModuleTableKey *e2)
165 return e1->m_pDefinitionModule == e2->m_pDefinitionModule &&
166 e1->m_token == e2->m_token &&
167 SigTypeContext::Equal(&e1->m_inst, &e2->m_inst);
169 static const ZapperLoaderModuleTableEntry Null()
170 { return ZapperLoaderModuleTableEntry(); }
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(); }
178 typedef SHash<ZapperLoaderModuleTableTraits> ZapperLoaderModuleTable;
180 class CEECompileInfo : public ICorCompileInfo
183 virtual ~CEECompileInfo()
188 HRESULT Startup( BOOL fForceDebug,
189 BOOL fForceProfiling,
190 BOOL fForceInstrument);
192 HRESULT CreateDomain(ICorCompilationDomain **ppDomain,
193 IMetaDataAssemblyEmit *pEmitter,
195 BOOL fForceProfiling,
196 BOOL fForceInstrument,
197 BOOL fForceFulltrustDomain);
199 HRESULT MakeCrossDomainCallback(
200 ICorCompilationDomain* pDomain,
201 CROSS_DOMAIN_CALLBACK pfnCallback,
204 HRESULT DestroyDomain(ICorCompilationDomain *pDomain);
206 HRESULT LoadAssemblyByPath(LPCWSTR wzPath,
207 BOOL fExplicitBindToNativeImage,
208 CORINFO_ASSEMBLY_HANDLE *pHandle);
210 #ifdef FEATURE_FUSION
211 HRESULT LoadAssemblyByName(LPCWSTR wzName,
212 CORINFO_ASSEMBLY_HANDLE *pHandle);
214 HRESULT LoadAssemblyRef(IMDInternalImport *pAssemblyImport,
216 CORINFO_ASSEMBLY_HANDLE *pHandle,
217 IAssemblyName **refAssemblyName = NULL);
219 HRESULT LoadAssemblyByIAssemblyName(
220 IAssemblyName *pAssemblyName,
221 CORINFO_ASSEMBLY_HANDLE *pHandle
224 #endif //FEATURE_FUSION
226 #ifdef FEATURE_COMINTEROP
227 HRESULT LoadTypeRefWinRT(IMDInternalImport *pAssemblyImport,
229 CORINFO_ASSEMBLY_HANDLE *pHandle);
232 BOOL IsInCurrentVersionBubble(CORINFO_MODULE_HANDLE hModule);
234 HRESULT LoadAssemblyModule(CORINFO_ASSEMBLY_HANDLE assembly,
236 CORINFO_MODULE_HANDLE *pHandle);
238 #ifndef FEATURE_CORECLR
239 // Check if the assembly supports automatic NGen
240 BOOL SupportsAutoNGen(CORINFO_ASSEMBLY_HANDLE assembly);
242 HRESULT SetCachedSigningLevel(HANDLE hNI, HANDLE *pModules, COUNT_T nModules);
245 BOOL CheckAssemblyZap(
246 CORINFO_ASSEMBLY_HANDLE assembly,
247 __out_ecount_opt(*cAssemblyManifestModulePath)
248 LPWSTR assemblyManifestModulePath,
249 LPDWORD cAssemblyManifestModulePath);
251 HRESULT SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE assembly,
252 CORINFO_MODULE_HANDLE module);
254 IMDInternalImport * GetAssemblyMetaDataImport(CORINFO_ASSEMBLY_HANDLE scope);
256 IMDInternalImport * GetModuleMetaDataImport(CORINFO_MODULE_HANDLE scope);
258 CORINFO_MODULE_HANDLE GetAssemblyModule(CORINFO_ASSEMBLY_HANDLE module);
260 CORINFO_ASSEMBLY_HANDLE GetModuleAssembly(CORINFO_MODULE_HANDLE module);
262 PEDecoder * GetModuleDecoder(CORINFO_MODULE_HANDLE scope);
264 void GetModuleFileName(CORINFO_MODULE_HANDLE module,
267 void EncodeModuleAsIndexes( CORINFO_MODULE_HANDLE fromHandle,
268 CORINFO_MODULE_HANDLE handle,
269 DWORD *pAssemblyIndex,
271 IMetaDataAssemblyEmit *pAssemblyEmit);
273 void EncodeClass( CORINFO_MODULE_HANDLE referencingModule,
274 CORINFO_CLASS_HANDLE classHandle,
275 SigBuilder *pSigBuilder,
276 LPVOID encodeContext,
277 ENCODEMODULE_CALLBACK pfnEncodeModule);
279 void EncodeMethod( CORINFO_MODULE_HANDLE referencingModule,
280 CORINFO_METHOD_HANDLE methHnd,
281 SigBuilder *pSigBuilder,
282 LPVOID encodeContext,
283 ENCODEMODULE_CALLBACK pfnEncodeModule,
284 CORINFO_RESOLVED_TOKEN *pResolvedToken,
285 CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken,
286 BOOL fEncodeUsingResolvedTokenSpecStreams);
288 virtual mdToken TryEncodeMethodAsToken(CORINFO_METHOD_HANDLE handle,
289 CORINFO_RESOLVED_TOKEN * pResolvedToken,
290 CORINFO_MODULE_HANDLE * referencingModule);
292 virtual DWORD TryEncodeMethodSlot(CORINFO_METHOD_HANDLE handle);
294 void EncodeField( CORINFO_MODULE_HANDLE referencingModule,
295 CORINFO_FIELD_HANDLE handle,
296 SigBuilder *pSigBuilder,
297 LPVOID encodeContext,
298 ENCODEMODULE_CALLBACK pfnEncodeModule,
299 CORINFO_RESOLVED_TOKEN *pResolvedToken,
300 BOOL fEncodeUsingResolvedTokenSpecStreams);
302 // Encode generic dictionary signature
303 virtual void EncodeGenericSignature(
306 SigBuilder * pSigBuilder,
307 LPVOID encodeContext,
308 ENCODEMODULE_CALLBACK pfnEncodeModule);
311 BOOL IsEmptyString(mdString token,
312 CORINFO_MODULE_HANDLE module);
314 BOOL IsNativeCallableMethod(CORINFO_METHOD_HANDLE handle);
316 BOOL IsCachingOfInliningHintsEnabled()
318 return m_fCachingOfInliningHintsEnabled;
321 void DisableCachingOfInliningHints()
323 m_fCachingOfInliningHintsEnabled = FALSE;
326 HRESULT GetTypeDef( CORINFO_CLASS_HANDLE classHandle,
328 HRESULT GetMethodDef( CORINFO_METHOD_HANDLE methodHandle,
330 HRESULT GetFieldDef( CORINFO_FIELD_HANDLE fieldHandle,
333 void SetAssemblyHardBindList(__in_ecount( cHardBindList )
334 LPWSTR *pHardBindList,
335 DWORD cHardBindList);
337 CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib();
338 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableType(CORINFO_CLASS_HANDLE classHandle);
339 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableMethod(CORINFO_METHOD_HANDLE methodHandle);
340 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableField(CORINFO_FIELD_HANDLE fieldHandle);
342 ICorCompilePreloader * PreloadModule(CORINFO_MODULE_HANDLE moduleHandle,
343 ICorCompileDataStore *pData,
344 CorProfileData *profileData);
346 #ifdef FEATURE_FUSION
347 HRESULT GetAssemblyName(
348 CORINFO_ASSEMBLY_HANDLE hAssembly,
350 __out_z LPWSTR wzAssemblyName,
351 LPDWORD cchAssemblyName);
352 #endif //FEATURE_FUSION
354 HRESULT GetLoadHint(CORINFO_ASSEMBLY_HANDLE hAssembly,
355 CORINFO_ASSEMBLY_HANDLE hAssemblyDependency,
356 LoadHintEnum *loadHint,
357 LoadHintEnum *defaultLoadHint);
359 HRESULT GetAssemblyVersionInfo(CORINFO_ASSEMBLY_HANDLE Handle,
360 CORCOMPILE_VERSION_INFO *pInfo);
362 void GetAssemblyCodeBase(CORINFO_ASSEMBLY_HANDLE hAssembly,
365 void GetCallRefMap(CORINFO_METHOD_HANDLE hMethod,
366 GCRefMapBuilder * pBuilder);
368 void CompressDebugInfo(
369 IN ICorDebugInfo::OffsetMapping * pOffsetMapping,
370 IN ULONG iOffsetMapping,
371 IN ICorDebugInfo::NativeVarInfo * pNativeVarInfo,
372 IN ULONG iNativeVarInfo,
373 IN OUT SBuffer * pDebugInfoBuffer);
375 HRESULT SetVerboseLevel(
376 IN VerboseLevel level);
378 HRESULT GetBaseJitFlags(
379 IN CORINFO_METHOD_HANDLE hMethod,
380 OUT CORJIT_FLAGS *pFlags);
383 SIZE_T getPersonalityValue();
386 void* GetStubSize(void *pStubAddress, DWORD *pSizeToCopy);
388 HRESULT GetStubClone(void *pStub, BYTE *pBuffer, DWORD dwBufferSize);
390 BOOL GetIsGeneratingNgenPDB();
391 void SetIsGeneratingNgenPDB(BOOL fGeneratingNgenPDB);
393 #ifdef FEATURE_READYTORUN_COMPILER
394 CORCOMPILE_FIXUP_BLOB_KIND GetFieldBaseOffset(
395 CORINFO_CLASS_HANDLE classHnd,
396 DWORD * pBaseOffset);
398 BOOL NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd);
399 void EncodeTypeLayout(CORINFO_CLASS_HANDLE classHandle, SigBuilder * pSigBuilder);
401 BOOL AreAllClassesFullyLoaded(CORINFO_MODULE_HANDLE moduleHandle);
403 int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
405 int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
408 BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
410 //--------------------------------------------------------------------
411 // ZapperLoaderModules and the ZapperLoaderModuleTable
413 // When NGEN'ing we want to adjust the
414 // places where some items (i.e. generic instantiations) are placed, in order to get some of them
415 // placed into the module we are compiling. However, the
416 // results of ComputeLoaderModule must be stable for the duration
417 // of an entire instance of the VM, i.e. for the duration of a compilation
418 // process. Thus each time we place an item into a non-standard LoaderModule we record
421 Module *LookupZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey)
424 const ZapperLoaderModuleTableEntry *pEntry = m_ZapperLoaderModuleTable.LookupPtr(pKey);
426 return pEntry->result;
430 void RecordZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey,
431 Module *pZapperLoaderModuleTable)
441 ZapperLoaderModuleTableEntry entry(*pKey, pZapperLoaderModuleTable);
442 m_ZapperLoaderModuleTable.Add(entry);
445 ZapperLoaderModuleTable m_ZapperLoaderModuleTable;
448 BOOL m_fCachingOfInliningHintsEnabled;
449 BOOL m_fGeneratingNgenPDB;
452 extern CEECompileInfo *g_pCEECompileInfo;
454 BOOL IsNgenPDBCompilationProcess();
457 // See comment at top of file for an explanation on the preloader
461 class CEEPreloader : public ICorCompilePreloader
465 ICorCompileDataStore *m_pData;
467 class MethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodDesc *> >
470 typedef MethodDesc *key_t;
471 static MethodDesc * GetKey(MethodDesc *md) { return md; }
472 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
473 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
479 class TypeSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<TypeHandle> >
482 typedef TypeHandle key_t;
483 static const TypeHandle Null() { return TypeHandle(); }
484 static bool IsNull(const TypeHandle &th) { return !!th.IsNull(); }
485 static TypeHandle GetKey(TypeHandle th) { return th; }
486 static count_t Hash(TypeHandle th) { return (count_t) th.AsTAddr(); }
487 static BOOL Equals(TypeHandle th1, TypeHandle th2) { return th1 == th2; }
490 // Cached results of instantiations triage
491 SHash<TypeSetTraits> m_acceptedTypes;
492 SHash<MethodSetTraits> m_acceptedMethods;
493 SHash<TypeSetTraits> m_rejectedTypes;
494 SHash<MethodSetTraits> m_rejectedMethods;
496 #ifdef FEATURE_FULL_NGEN
497 // Tentatively accepted instantiations
498 InlineSArray<TypeHandle, 20> m_speculativeTypes;
499 BOOL m_fSpeculativeTriage;
500 BOOL m_fDictionariesPopulated;
503 struct CompileMethodEntry
506 #ifndef FEATURE_FULL_NGEN // Unreferenced methods
507 bool fReferenced; // true when this method was referenced by other code
508 bool fScheduled; // true when this method was scheduled for compilation
512 class CompileMethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<CompileMethodEntry> >
515 typedef MethodDesc *key_t;
516 static MethodDesc * GetKey(CompileMethodEntry e) { return e.pMD; }
517 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
518 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
522 static const CompileMethodEntry Null() { CompileMethodEntry e; e.pMD = NULL; return e; }
523 static bool IsNull(const CompileMethodEntry &e) { return e.pMD == NULL; }
526 SHash<CompileMethodSetTraits> m_compileMethodsHash;
528 // Array of methods that we need to compile.
529 SArray<MethodDesc*> m_uncompiledMethods;
531 int m_methodCompileLimit;
533 void AppendUncompiledMethod(MethodDesc *pMD)
535 STANDARD_VM_CONTRACT;
536 if (m_methodCompileLimit > 0)
538 m_uncompiledMethods.Append(pMD);
539 m_methodCompileLimit--;
543 struct DuplicateMethodEntry
546 MethodDesc * pDuplicateMD;
549 class DuplicateMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<DuplicateMethodEntry> >
552 typedef MethodDesc *key_t;
553 static MethodDesc * GetKey(DuplicateMethodEntry e) { return e.pMD; }
554 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
555 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
559 static const DuplicateMethodEntry Null() { DuplicateMethodEntry e; e.pMD = NULL; return e; }
560 static bool IsNull(const DuplicateMethodEntry &e) { return e.pMD == NULL; }
563 SHash<DuplicateMethodTraits> m_duplicateMethodsHash;
565 MethodDesc * CompileMethodStubIfNeeded(
568 ICorCompilePreloader::CORCOMPILE_CompileStubCallback pfnCallback,
569 LPVOID pCallbackContext);
572 CEEPreloader(Module *pModule,
573 ICorCompileDataStore *pData);
574 virtual ~CEEPreloader();
576 void Preload(CorProfileData * profileData);
577 DataImage * GetDataImage() { LIMITED_METHOD_CONTRACT; return m_image; }
578 ICorCompileDataStore * GetDataStore() { LIMITED_METHOD_CONTRACT; return m_pData; }
581 // ICorCompilerPreloader
584 DWORD MapMethodEntryPoint(CORINFO_METHOD_HANDLE handle);
585 DWORD MapClassHandle(CORINFO_CLASS_HANDLE handle);
586 DWORD MapMethodHandle(CORINFO_METHOD_HANDLE handle);
587 DWORD MapFieldHandle(CORINFO_FIELD_HANDLE handle);
588 DWORD MapAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
589 DWORD MapGenericHandle(CORINFO_GENERIC_HANDLE handle);
590 DWORD MapModuleIDHandle(CORINFO_MODULE_HANDLE handle);
592 void AddMethodToTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
593 void AddTypeToTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
594 BOOL IsMethodInTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
595 BOOL IsTypeInTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
597 void MethodReferencedByCompiledCode(CORINFO_METHOD_HANDLE handle);
599 BOOL IsUncompiledMethod(CORINFO_METHOD_HANDLE handle);
602 void AddToUncompiledMethods(MethodDesc *pMethod, BOOL fForStubs);
604 void ApplyTypeDependencyProductionsForType(TypeHandle t);
605 void ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceMT, TypeHandle elemTypeHnd);
608 void TriageTypeForZap(TypeHandle th, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
609 void TriageMethodForZap(MethodDesc* pMethod, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
611 void ExpandTypeDependencies(TypeHandle th);
612 void ExpandMethodDependencies(MethodDesc * pMD);
614 void TriageTypeSpecsFromSoftBoundModule(Module * pSoftBoundModule);
615 void TriageTypeFromSoftBoundModule(TypeHandle th, Module * pSoftBoundModule);
616 void TriageSpeculativeType(TypeHandle th);
617 void TriageSpeculativeInstantiations();
619 // Returns TRUE if new types or methods have been added by the triage
620 BOOL TriageForZap(BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
623 CORINFO_METHOD_HANDLE NextUncompiledMethod();
625 void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
627 void GenerateMethodStubs(
628 CORINFO_METHOD_HANDLE hMethod,
629 bool fNgenProfileImage,
630 CORCOMPILE_CompileStubCallback pfnCallback,
631 LPVOID pCallbackContext);
633 bool IsDynamicMethod(CORINFO_METHOD_HANDLE hMethod);
634 void SetMethodProfilingFlags(CORINFO_METHOD_HANDLE hMethod, DWORD flags);
636 bool CanSkipMethodPreparation (
637 CORINFO_METHOD_HANDLE callerHnd, /* IN */
638 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
639 CorInfoIndirectCallReason *pReason = NULL,
640 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
642 BOOL CanEmbedClassID (CORINFO_CLASS_HANDLE typeHandle);
643 BOOL CanEmbedModuleID (CORINFO_MODULE_HANDLE moduleHandle);
644 BOOL CanEmbedModuleHandle(CORINFO_MODULE_HANDLE moduleHandle);
645 BOOL CanEmbedClassHandle (CORINFO_CLASS_HANDLE typeHandle);
646 BOOL CanEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHandle,
647 CORINFO_METHOD_HANDLE contextHandle);
648 BOOL CanEmbedFieldHandle (CORINFO_FIELD_HANDLE fieldHandle);
650 BOOL CanPrerestoreEmbedClassHandle (CORINFO_CLASS_HANDLE classHnd);
651 BOOL CanPrerestoreEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHnd);
653 BOOL CanEmbedFunctionEntryPoint(CORINFO_METHOD_HANDLE methodHandle,
654 CORINFO_METHOD_HANDLE contextHandle,
655 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
657 BOOL DoesMethodNeedRestoringBeforePrestubIsRun(CORINFO_METHOD_HANDLE methodHandle);
659 BOOL CanSkipDependencyActivation(CORINFO_METHOD_HANDLE context,
660 CORINFO_MODULE_HANDLE moduleFrom,
661 CORINFO_MODULE_HANDLE moduleTo);
663 CORINFO_MODULE_HANDLE GetPreferredZapModuleForClassHandle(CORINFO_CLASS_HANDLE classHnd);
665 void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
667 CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token);
669 CorCompileILRegion GetILRegion(mdMethodDef token);
671 CORINFO_CLASS_HANDLE FindTypeForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
672 CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
674 void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee);
679 void SetRVAsForFields(IMetaDataEmit * pEmit);
681 void GetRVAFieldData(mdFieldDef fd, PVOID * ppData, DWORD * pcbSize, DWORD * pcbAlignment);
685 void Error(mdToken token, Exception * pException);
691 RefCache(Module *pModule)
705 // HashMap::Init can throw due to OOM. Our ctor can't. Since this whole
706 // thing is for use inside CEECompileInfo methods, it doesn't make sense to
707 // use an exception model. Thus we probably have to move the hashmap init
708 // calls out of the ctor so can catch these exceptions and translate them to
711 CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
713 m_sAssemblyRefMap.Init(FALSE,NULL);
719 HashMap m_sAssemblyRefMap;
722 struct AssemblySpecDefRefMapEntry {
723 AssemblySpec * m_pDef;
724 AssemblySpec * m_pRef;
727 class AssemblySpecDefRefMapTraits : public NoRemoveSHashTraits<DefaultSHashTraits<AssemblySpecDefRefMapEntry> >
730 typedef const AssemblySpec *key_t;
731 static const AssemblySpec * GetKey(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef; }
733 static count_t Hash(const AssemblySpec * k)
735 return const_cast<AssemblySpec *>(k)->Hash();
738 static BOOL Equals(const AssemblySpec * lhs, const AssemblySpec * rhs)
740 return const_cast<AssemblySpec *>(lhs)->CompareEx(const_cast<AssemblySpec *>(rhs), AssemblySpec::ASC_DefinitionEquality);
743 static const AssemblySpecDefRefMapEntry Null() { AssemblySpecDefRefMapEntry e; e.m_pDef = NULL; return e; }
744 static bool IsNull(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef == NULL; }
746 void OnDestructPerEntryCleanupAction(const AssemblySpecDefRefMapEntry& e)
752 static const bool s_DestructPerEntryCleanupAction = true;
755 typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
757 class CompilationDomain : public AppDomain,
758 public ICorCompilationDomain
760 #ifndef FEATURE_CORECLR
761 VPTR_MULTI_VTABLE_CLASS(CompilationDomain, AppDomain);
766 BOOL m_fForceProfiling;
767 BOOL m_fForceInstrument;
769 // TODO: During ngen, we need to determine whether we can call NeedsRestore
770 // before the preloader has been initialized. This is accomplished via this
771 // method. This code needs to be cleaned up. See bug #284709 for background.
772 BOOL canCallNeedsRestore() { return (m_pTargetImage != NULL); };
774 // DDB 175659: Make sure that canCallNeedsRestore() returns FALSE during compilation
776 void setCannotCallNeedsRestore() { m_pTargetImage = NULL; }
780 Assembly *m_pTargetAssembly; // Assembly being compiled
781 Module *m_pTargetModule; // Module currently being compiled. Needed for multi-module assemblies
782 DataImage *m_pTargetImage; // Data image
783 CEEPreloader *m_pTargetPreloader;
785 ReleaseHolder<IMetaDataAssemblyEmit> m_pEmit;
787 NewHolder<AssemblySpecHash> m_pDependencyRefSpecs;
789 AssemblySpecMapDefRefMapTable m_dependencyDefRefMap;
791 CORCOMPILE_DEPENDENCY *m_pDependencies;
792 USHORT m_cDependenciesCount, m_cDependenciesAlloc;
794 CQuickArray<RefCache*> m_rRefCaches;
796 HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
797 void ReleaseDependencyEmitter();
799 #ifndef FEATURE_CORECLR // hardbinding
800 PtrHashMap m_hardBoundModules; // Hard dependency on native image of these dependency modules
801 PtrHashMap m_cantHardBindModules;
802 void UpdateDependencyEntryForHardBind(PEAssembly * pDependencyAssembly);
803 void IncludeHardBindClosure(PEAssembly * pDependencyAssembly);
804 void CheckHardBindToZapFile(SString dependencyNameFromCustomAttribute);
805 void CheckLoadHints();
810 #ifndef DACCESS_COMPILE
811 CompilationDomain(BOOL fForceDebug = FALSE,
812 BOOL fForceProfiling = FALSE,
813 BOOL fForceInstrument = FALSE);
814 ~CompilationDomain();
819 HRESULT AddDependency(AssemblySpec *pRefSpec, PEAssembly *pFile);
821 AssemblySpec* FindAssemblyRefSpecForDefSpec(
822 AssemblySpec* pDefSpec);
824 PEAssembly *BindAssemblySpec(
826 BOOL fThrowOnFileNotFound,
827 BOOL fRaisePrebindEvents,
828 StackCrawlMark *pCallerStackMark = NULL,
829 AssemblyLoadSecurity *pLoadSecurity = NULL,
830 BOOL fUseHostBinderIfAvailable = TRUE) DAC_EMPTY_RET(NULL);
832 BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
834 #ifndef FEATURE_CORECLR // hardbinding
835 PtrHashMap::PtrIterator IterateHardBoundModules();
837 // List of full display names of assemblies to hard-bind to
838 SArray<SString,FALSE> m_assemblyHardBindList;
839 BOOL m_useHardBindList;
840 BOOL IsInHardBindRequestList(Assembly * pAssembly);
841 BOOL IsInHardBindRequestList(PEAssembly * pAssembly);
842 BOOL IsSafeToHardBindTo(PEAssembly * pAssembly);
844 void SetAssemblyHardBindList(
845 __in_ecount( cHardBindList )
846 LPWSTR *pHardBindList,
847 DWORD cHardBindList);
850 #if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
851 void ComputeAssemblyHardBindList(IMDInternalImport * pImport);
852 BOOL IsInHardBindList(SString& simpleName);
854 static BOOL FindImage(const SString& fileName, MDInternalImportFlags flags, PEImage ** ppImage);
857 // Returns NULL on out-of-memory
858 RefCache *GetRefCache(Module *pModule)
864 INJECT_FAULT(return NULL;);
868 unsigned uSize = (unsigned) m_rRefCaches.Size();
869 for (unsigned i = 0; i < uSize; i++)
870 if (m_rRefCaches[i]->m_pModule == pModule)
871 return m_rRefCaches[i];
873 // Add a new cache entry
876 if (FAILED(hr = m_rRefCaches.ReSizeNoThrow(uSize + 1)))
878 _ASSERTE(hr == E_OUTOFMEMORY);
882 m_rRefCaches[uSize] = new (nothrow) RefCache(pModule);
883 return m_rRefCaches[uSize];
886 void SetTarget(Assembly * pAssembly, Module *pModule);
888 void SetTargetImage(DataImage * pImage, CEEPreloader * pPreloader);
889 DataImage * GetTargetImage() { LIMITED_METHOD_CONTRACT; return m_pTargetImage; }
891 Assembly * GetTargetAssembly()
892 { LIMITED_METHOD_CONTRACT; return m_pTargetAssembly; }
893 Module * GetTargetModule()
894 { LIMITED_METHOD_CONTRACT; return m_pTargetModule; }
896 // ICorCompilationDomain
898 HRESULT SetContextInfo(LPCWSTR exePath, BOOL isExe) DAC_EMPTY_RET(E_FAIL);
899 HRESULT GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
900 DWORD *cDependencies) DAC_EMPTY_RET(E_FAIL);
901 #ifdef FEATURE_FUSION
902 HRESULT GetIBindContext(IBindContext **ppBindCtx) DAC_EMPTY_RET(E_FAIL);
905 #ifdef CROSSGEN_COMPILE
906 HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
909 void SetDependencyEmitter(IMetaDataAssemblyEmit *pEmitter);
912 #endif // FEATURE_NATIVE_IMAGE_GENERATION