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);
239 BOOL CheckAssemblyZap(
240 CORINFO_ASSEMBLY_HANDLE assembly,
241 __out_ecount_opt(*cAssemblyManifestModulePath)
242 LPWSTR assemblyManifestModulePath,
243 LPDWORD cAssemblyManifestModulePath);
245 HRESULT SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE assembly,
246 CORINFO_MODULE_HANDLE module);
248 IMDInternalImport * GetAssemblyMetaDataImport(CORINFO_ASSEMBLY_HANDLE scope);
250 IMDInternalImport * GetModuleMetaDataImport(CORINFO_MODULE_HANDLE scope);
252 CORINFO_MODULE_HANDLE GetAssemblyModule(CORINFO_ASSEMBLY_HANDLE module);
254 CORINFO_ASSEMBLY_HANDLE GetModuleAssembly(CORINFO_MODULE_HANDLE module);
256 PEDecoder * GetModuleDecoder(CORINFO_MODULE_HANDLE scope);
258 void GetModuleFileName(CORINFO_MODULE_HANDLE module,
261 void EncodeModuleAsIndexes( CORINFO_MODULE_HANDLE fromHandle,
262 CORINFO_MODULE_HANDLE handle,
263 DWORD *pAssemblyIndex,
265 IMetaDataAssemblyEmit *pAssemblyEmit);
267 void EncodeClass( CORINFO_MODULE_HANDLE referencingModule,
268 CORINFO_CLASS_HANDLE classHandle,
269 SigBuilder *pSigBuilder,
270 LPVOID encodeContext,
271 ENCODEMODULE_CALLBACK pfnEncodeModule);
273 void EncodeMethod( CORINFO_MODULE_HANDLE referencingModule,
274 CORINFO_METHOD_HANDLE methHnd,
275 SigBuilder *pSigBuilder,
276 LPVOID encodeContext,
277 ENCODEMODULE_CALLBACK pfnEncodeModule,
278 CORINFO_RESOLVED_TOKEN *pResolvedToken,
279 CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken,
280 BOOL fEncodeUsingResolvedTokenSpecStreams);
282 virtual mdToken TryEncodeMethodAsToken(CORINFO_METHOD_HANDLE handle,
283 CORINFO_RESOLVED_TOKEN * pResolvedToken,
284 CORINFO_MODULE_HANDLE * referencingModule);
286 virtual DWORD TryEncodeMethodSlot(CORINFO_METHOD_HANDLE handle);
288 void EncodeField( CORINFO_MODULE_HANDLE referencingModule,
289 CORINFO_FIELD_HANDLE handle,
290 SigBuilder *pSigBuilder,
291 LPVOID encodeContext,
292 ENCODEMODULE_CALLBACK pfnEncodeModule,
293 CORINFO_RESOLVED_TOKEN *pResolvedToken,
294 BOOL fEncodeUsingResolvedTokenSpecStreams);
296 // Encode generic dictionary signature
297 virtual void EncodeGenericSignature(
300 SigBuilder * pSigBuilder,
301 LPVOID encodeContext,
302 ENCODEMODULE_CALLBACK pfnEncodeModule);
305 BOOL IsEmptyString(mdString token,
306 CORINFO_MODULE_HANDLE module);
308 BOOL IsNativeCallableMethod(CORINFO_METHOD_HANDLE handle);
310 BOOL IsCachingOfInliningHintsEnabled()
312 return m_fCachingOfInliningHintsEnabled;
315 void DisableCachingOfInliningHints()
317 m_fCachingOfInliningHintsEnabled = FALSE;
320 HRESULT GetTypeDef( CORINFO_CLASS_HANDLE classHandle,
322 HRESULT GetMethodDef( CORINFO_METHOD_HANDLE methodHandle,
324 HRESULT GetFieldDef( CORINFO_FIELD_HANDLE fieldHandle,
327 void SetAssemblyHardBindList(__in_ecount( cHardBindList )
328 LPWSTR *pHardBindList,
329 DWORD cHardBindList);
331 CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib();
332 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableType(CORINFO_CLASS_HANDLE classHandle);
333 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableMethod(CORINFO_METHOD_HANDLE methodHandle);
334 CORINFO_MODULE_HANDLE GetLoaderModuleForEmbeddableField(CORINFO_FIELD_HANDLE fieldHandle);
336 ICorCompilePreloader * PreloadModule(CORINFO_MODULE_HANDLE moduleHandle,
337 ICorCompileDataStore *pData,
338 CorProfileData *profileData);
340 #ifdef FEATURE_FUSION
341 HRESULT GetAssemblyName(
342 CORINFO_ASSEMBLY_HANDLE hAssembly,
344 __out_z LPWSTR wzAssemblyName,
345 LPDWORD cchAssemblyName);
346 #endif //FEATURE_FUSION
348 HRESULT GetLoadHint(CORINFO_ASSEMBLY_HANDLE hAssembly,
349 CORINFO_ASSEMBLY_HANDLE hAssemblyDependency,
350 LoadHintEnum *loadHint,
351 LoadHintEnum *defaultLoadHint);
353 HRESULT GetAssemblyVersionInfo(CORINFO_ASSEMBLY_HANDLE Handle,
354 CORCOMPILE_VERSION_INFO *pInfo);
356 void GetAssemblyCodeBase(CORINFO_ASSEMBLY_HANDLE hAssembly,
359 void GetCallRefMap(CORINFO_METHOD_HANDLE hMethod,
360 GCRefMapBuilder * pBuilder);
362 void CompressDebugInfo(
363 IN ICorDebugInfo::OffsetMapping * pOffsetMapping,
364 IN ULONG iOffsetMapping,
365 IN ICorDebugInfo::NativeVarInfo * pNativeVarInfo,
366 IN ULONG iNativeVarInfo,
367 IN OUT SBuffer * pDebugInfoBuffer);
369 HRESULT SetVerboseLevel(
370 IN VerboseLevel level);
372 HRESULT GetBaseJitFlags(
373 IN CORINFO_METHOD_HANDLE hMethod,
374 OUT CORJIT_FLAGS *pFlags);
377 SIZE_T getPersonalityValue();
380 void* GetStubSize(void *pStubAddress, DWORD *pSizeToCopy);
382 HRESULT GetStubClone(void *pStub, BYTE *pBuffer, DWORD dwBufferSize);
384 BOOL GetIsGeneratingNgenPDB();
385 void SetIsGeneratingNgenPDB(BOOL fGeneratingNgenPDB);
387 #ifdef FEATURE_READYTORUN_COMPILER
388 CORCOMPILE_FIXUP_BLOB_KIND GetFieldBaseOffset(
389 CORINFO_CLASS_HANDLE classHnd,
390 DWORD * pBaseOffset);
392 BOOL NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd);
393 void EncodeTypeLayout(CORINFO_CLASS_HANDLE classHandle, SigBuilder * pSigBuilder);
395 BOOL AreAllClassesFullyLoaded(CORINFO_MODULE_HANDLE moduleHandle);
397 int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
399 int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
402 BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
404 //--------------------------------------------------------------------
405 // ZapperLoaderModules and the ZapperLoaderModuleTable
407 // When NGEN'ing we want to adjust the
408 // places where some items (i.e. generic instantiations) are placed, in order to get some of them
409 // placed into the module we are compiling. However, the
410 // results of ComputeLoaderModule must be stable for the duration
411 // of an entire instance of the VM, i.e. for the duration of a compilation
412 // process. Thus each time we place an item into a non-standard LoaderModule we record
415 Module *LookupZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey)
418 const ZapperLoaderModuleTableEntry *pEntry = m_ZapperLoaderModuleTable.LookupPtr(pKey);
420 return pEntry->result;
424 void RecordZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey,
425 Module *pZapperLoaderModuleTable)
435 ZapperLoaderModuleTableEntry entry(*pKey, pZapperLoaderModuleTable);
436 m_ZapperLoaderModuleTable.Add(entry);
439 ZapperLoaderModuleTable m_ZapperLoaderModuleTable;
442 BOOL m_fCachingOfInliningHintsEnabled;
443 BOOL m_fGeneratingNgenPDB;
446 extern CEECompileInfo *g_pCEECompileInfo;
448 BOOL IsNgenPDBCompilationProcess();
451 // See comment at top of file for an explanation on the preloader
455 class CEEPreloader : public ICorCompilePreloader
459 ICorCompileDataStore *m_pData;
461 class MethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodDesc *> >
464 typedef MethodDesc *key_t;
465 static MethodDesc * GetKey(MethodDesc *md) { return md; }
466 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
467 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
473 class TypeSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<TypeHandle> >
476 typedef TypeHandle key_t;
477 static const TypeHandle Null() { return TypeHandle(); }
478 static bool IsNull(const TypeHandle &th) { return !!th.IsNull(); }
479 static TypeHandle GetKey(TypeHandle th) { return th; }
480 static count_t Hash(TypeHandle th) { return (count_t) th.AsTAddr(); }
481 static BOOL Equals(TypeHandle th1, TypeHandle th2) { return th1 == th2; }
484 // Cached results of instantiations triage
485 SHash<TypeSetTraits> m_acceptedTypes;
486 SHash<MethodSetTraits> m_acceptedMethods;
487 SHash<TypeSetTraits> m_rejectedTypes;
488 SHash<MethodSetTraits> m_rejectedMethods;
490 #ifdef FEATURE_FULL_NGEN
491 // Tentatively accepted instantiations
492 InlineSArray<TypeHandle, 20> m_speculativeTypes;
493 BOOL m_fSpeculativeTriage;
494 BOOL m_fDictionariesPopulated;
497 struct CompileMethodEntry
500 #ifndef FEATURE_FULL_NGEN // Unreferenced methods
501 bool fReferenced; // true when this method was referenced by other code
502 bool fScheduled; // true when this method was scheduled for compilation
506 class CompileMethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<CompileMethodEntry> >
509 typedef MethodDesc *key_t;
510 static MethodDesc * GetKey(CompileMethodEntry e) { return e.pMD; }
511 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
512 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
516 static const CompileMethodEntry Null() { CompileMethodEntry e; e.pMD = NULL; return e; }
517 static bool IsNull(const CompileMethodEntry &e) { return e.pMD == NULL; }
520 SHash<CompileMethodSetTraits> m_compileMethodsHash;
522 // Array of methods that we need to compile.
523 SArray<MethodDesc*> m_uncompiledMethods;
525 int m_methodCompileLimit;
527 void AppendUncompiledMethod(MethodDesc *pMD)
529 STANDARD_VM_CONTRACT;
530 if (m_methodCompileLimit > 0)
532 m_uncompiledMethods.Append(pMD);
533 m_methodCompileLimit--;
537 struct DuplicateMethodEntry
540 MethodDesc * pDuplicateMD;
543 class DuplicateMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<DuplicateMethodEntry> >
546 typedef MethodDesc *key_t;
547 static MethodDesc * GetKey(DuplicateMethodEntry e) { return e.pMD; }
548 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
549 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
553 static const DuplicateMethodEntry Null() { DuplicateMethodEntry e; e.pMD = NULL; return e; }
554 static bool IsNull(const DuplicateMethodEntry &e) { return e.pMD == NULL; }
557 SHash<DuplicateMethodTraits> m_duplicateMethodsHash;
559 MethodDesc * CompileMethodStubIfNeeded(
562 ICorCompilePreloader::CORCOMPILE_CompileStubCallback pfnCallback,
563 LPVOID pCallbackContext);
566 CEEPreloader(Module *pModule,
567 ICorCompileDataStore *pData);
568 virtual ~CEEPreloader();
570 void Preload(CorProfileData * profileData);
571 DataImage * GetDataImage() { LIMITED_METHOD_CONTRACT; return m_image; }
572 ICorCompileDataStore * GetDataStore() { LIMITED_METHOD_CONTRACT; return m_pData; }
575 // ICorCompilerPreloader
578 DWORD MapMethodEntryPoint(CORINFO_METHOD_HANDLE handle);
579 DWORD MapClassHandle(CORINFO_CLASS_HANDLE handle);
580 DWORD MapMethodHandle(CORINFO_METHOD_HANDLE handle);
581 DWORD MapFieldHandle(CORINFO_FIELD_HANDLE handle);
582 DWORD MapAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
583 DWORD MapGenericHandle(CORINFO_GENERIC_HANDLE handle);
584 DWORD MapModuleIDHandle(CORINFO_MODULE_HANDLE handle);
586 void AddMethodToTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
587 void AddTypeToTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
588 BOOL IsMethodInTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
589 BOOL IsTypeInTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
591 void MethodReferencedByCompiledCode(CORINFO_METHOD_HANDLE handle);
593 BOOL IsUncompiledMethod(CORINFO_METHOD_HANDLE handle);
596 void AddToUncompiledMethods(MethodDesc *pMethod, BOOL fForStubs);
598 void ApplyTypeDependencyProductionsForType(TypeHandle t);
599 void ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceMT, TypeHandle elemTypeHnd);
602 void TriageTypeForZap(TypeHandle th, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
603 void TriageMethodForZap(MethodDesc* pMethod, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
605 void ExpandTypeDependencies(TypeHandle th);
606 void ExpandMethodDependencies(MethodDesc * pMD);
608 void TriageTypeSpecsFromSoftBoundModule(Module * pSoftBoundModule);
609 void TriageTypeFromSoftBoundModule(TypeHandle th, Module * pSoftBoundModule);
610 void TriageSpeculativeType(TypeHandle th);
611 void TriageSpeculativeInstantiations();
613 // Returns TRUE if new types or methods have been added by the triage
614 BOOL TriageForZap(BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
617 CORINFO_METHOD_HANDLE NextUncompiledMethod();
619 void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
621 void GenerateMethodStubs(
622 CORINFO_METHOD_HANDLE hMethod,
623 bool fNgenProfileImage,
624 CORCOMPILE_CompileStubCallback pfnCallback,
625 LPVOID pCallbackContext);
627 bool IsDynamicMethod(CORINFO_METHOD_HANDLE hMethod);
628 void SetMethodProfilingFlags(CORINFO_METHOD_HANDLE hMethod, DWORD flags);
630 bool CanSkipMethodPreparation (
631 CORINFO_METHOD_HANDLE callerHnd, /* IN */
632 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
633 CorInfoIndirectCallReason *pReason = NULL,
634 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
636 BOOL CanEmbedClassID (CORINFO_CLASS_HANDLE typeHandle);
637 BOOL CanEmbedModuleID (CORINFO_MODULE_HANDLE moduleHandle);
638 BOOL CanEmbedModuleHandle(CORINFO_MODULE_HANDLE moduleHandle);
639 BOOL CanEmbedClassHandle (CORINFO_CLASS_HANDLE typeHandle);
640 BOOL CanEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHandle,
641 CORINFO_METHOD_HANDLE contextHandle);
642 BOOL CanEmbedFieldHandle (CORINFO_FIELD_HANDLE fieldHandle);
644 BOOL CanPrerestoreEmbedClassHandle (CORINFO_CLASS_HANDLE classHnd);
645 BOOL CanPrerestoreEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHnd);
647 BOOL CanEmbedFunctionEntryPoint(CORINFO_METHOD_HANDLE methodHandle,
648 CORINFO_METHOD_HANDLE contextHandle,
649 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
651 BOOL DoesMethodNeedRestoringBeforePrestubIsRun(CORINFO_METHOD_HANDLE methodHandle);
653 BOOL CanSkipDependencyActivation(CORINFO_METHOD_HANDLE context,
654 CORINFO_MODULE_HANDLE moduleFrom,
655 CORINFO_MODULE_HANDLE moduleTo);
657 CORINFO_MODULE_HANDLE GetPreferredZapModuleForClassHandle(CORINFO_CLASS_HANDLE classHnd);
659 void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
661 CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token);
663 CorCompileILRegion GetILRegion(mdMethodDef token);
665 CORINFO_CLASS_HANDLE FindTypeForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
666 CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
668 void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee);
673 void SetRVAsForFields(IMetaDataEmit * pEmit);
675 void GetRVAFieldData(mdFieldDef fd, PVOID * ppData, DWORD * pcbSize, DWORD * pcbAlignment);
679 void Error(mdToken token, Exception * pException);
685 RefCache(Module *pModule)
699 // HashMap::Init can throw due to OOM. Our ctor can't. Since this whole
700 // thing is for use inside CEECompileInfo methods, it doesn't make sense to
701 // use an exception model. Thus we probably have to move the hashmap init
702 // calls out of the ctor so can catch these exceptions and translate them to
705 CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
707 m_sAssemblyRefMap.Init(FALSE,NULL);
713 HashMap m_sAssemblyRefMap;
716 struct AssemblySpecDefRefMapEntry {
717 AssemblySpec * m_pDef;
718 AssemblySpec * m_pRef;
721 class AssemblySpecDefRefMapTraits : public NoRemoveSHashTraits<DefaultSHashTraits<AssemblySpecDefRefMapEntry> >
724 typedef const AssemblySpec *key_t;
725 static const AssemblySpec * GetKey(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef; }
727 static count_t Hash(const AssemblySpec * k)
729 return const_cast<AssemblySpec *>(k)->Hash();
732 static BOOL Equals(const AssemblySpec * lhs, const AssemblySpec * rhs)
734 return const_cast<AssemblySpec *>(lhs)->CompareEx(const_cast<AssemblySpec *>(rhs), AssemblySpec::ASC_DefinitionEquality);
737 static const AssemblySpecDefRefMapEntry Null() { AssemblySpecDefRefMapEntry e; e.m_pDef = NULL; return e; }
738 static bool IsNull(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef == NULL; }
740 void OnDestructPerEntryCleanupAction(const AssemblySpecDefRefMapEntry& e)
746 static const bool s_DestructPerEntryCleanupAction = true;
749 typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
751 class CompilationDomain : public AppDomain,
752 public ICorCompilationDomain
757 BOOL m_fForceProfiling;
758 BOOL m_fForceInstrument;
760 // TODO: During ngen, we need to determine whether we can call NeedsRestore
761 // before the preloader has been initialized. This is accomplished via this
762 // method. This code needs to be cleaned up. See bug #284709 for background.
763 BOOL canCallNeedsRestore() { return (m_pTargetImage != NULL); };
765 // DDB 175659: Make sure that canCallNeedsRestore() returns FALSE during compilation
767 void setCannotCallNeedsRestore() { m_pTargetImage = NULL; }
771 Assembly *m_pTargetAssembly; // Assembly being compiled
772 Module *m_pTargetModule; // Module currently being compiled. Needed for multi-module assemblies
773 DataImage *m_pTargetImage; // Data image
774 CEEPreloader *m_pTargetPreloader;
776 ReleaseHolder<IMetaDataAssemblyEmit> m_pEmit;
778 NewHolder<AssemblySpecHash> m_pDependencyRefSpecs;
780 AssemblySpecMapDefRefMapTable m_dependencyDefRefMap;
782 CORCOMPILE_DEPENDENCY *m_pDependencies;
783 USHORT m_cDependenciesCount, m_cDependenciesAlloc;
785 CQuickArray<RefCache*> m_rRefCaches;
787 HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
788 void ReleaseDependencyEmitter();
793 #ifndef DACCESS_COMPILE
794 CompilationDomain(BOOL fForceDebug = FALSE,
795 BOOL fForceProfiling = FALSE,
796 BOOL fForceInstrument = FALSE);
797 ~CompilationDomain();
802 HRESULT AddDependency(AssemblySpec *pRefSpec, PEAssembly *pFile);
804 AssemblySpec* FindAssemblyRefSpecForDefSpec(
805 AssemblySpec* pDefSpec);
807 PEAssembly *BindAssemblySpec(
809 BOOL fThrowOnFileNotFound,
810 BOOL fRaisePrebindEvents,
811 StackCrawlMark *pCallerStackMark = NULL,
812 AssemblyLoadSecurity *pLoadSecurity = NULL,
813 BOOL fUseHostBinderIfAvailable = TRUE) DAC_EMPTY_RET(NULL);
815 BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
819 // Returns NULL on out-of-memory
820 RefCache *GetRefCache(Module *pModule)
826 INJECT_FAULT(return NULL;);
830 unsigned uSize = (unsigned) m_rRefCaches.Size();
831 for (unsigned i = 0; i < uSize; i++)
832 if (m_rRefCaches[i]->m_pModule == pModule)
833 return m_rRefCaches[i];
835 // Add a new cache entry
838 if (FAILED(hr = m_rRefCaches.ReSizeNoThrow(uSize + 1)))
840 _ASSERTE(hr == E_OUTOFMEMORY);
844 m_rRefCaches[uSize] = new (nothrow) RefCache(pModule);
845 return m_rRefCaches[uSize];
848 void SetTarget(Assembly * pAssembly, Module *pModule);
850 void SetTargetImage(DataImage * pImage, CEEPreloader * pPreloader);
851 DataImage * GetTargetImage() { LIMITED_METHOD_CONTRACT; return m_pTargetImage; }
853 Assembly * GetTargetAssembly()
854 { LIMITED_METHOD_CONTRACT; return m_pTargetAssembly; }
855 Module * GetTargetModule()
856 { LIMITED_METHOD_CONTRACT; return m_pTargetModule; }
858 // ICorCompilationDomain
860 HRESULT SetContextInfo(LPCWSTR exePath, BOOL isExe) DAC_EMPTY_RET(E_FAIL);
861 HRESULT GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
862 DWORD *cDependencies) DAC_EMPTY_RET(E_FAIL);
863 #ifdef FEATURE_FUSION
864 HRESULT GetIBindContext(IBindContext **ppBindCtx) DAC_EMPTY_RET(E_FAIL);
867 #ifdef CROSSGEN_COMPILE
868 HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
871 void SetDependencyEmitter(IMetaDataAssemblyEmit *pEmitter);
874 #endif // FEATURE_NATIVE_IMAGE_GENERATION