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);
211 #ifdef FEATURE_COMINTEROP
212 HRESULT LoadTypeRefWinRT(IMDInternalImport *pAssemblyImport,
214 CORINFO_ASSEMBLY_HANDLE *pHandle);
217 BOOL IsInCurrentVersionBubble(CORINFO_MODULE_HANDLE hModule);
219 HRESULT LoadAssemblyModule(CORINFO_ASSEMBLY_HANDLE assembly,
221 CORINFO_MODULE_HANDLE *pHandle);
224 BOOL CheckAssemblyZap(
225 CORINFO_ASSEMBLY_HANDLE assembly,
226 __out_ecount_opt(*cAssemblyManifestModulePath)
227 LPWSTR assemblyManifestModulePath,
228 LPDWORD cAssemblyManifestModulePath);
230 HRESULT SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE assembly,
231 CORINFO_MODULE_HANDLE module);
233 IMDInternalImport * GetAssemblyMetaDataImport(CORINFO_ASSEMBLY_HANDLE scope);
235 IMDInternalImport * GetModuleMetaDataImport(CORINFO_MODULE_HANDLE scope);
237 CORINFO_MODULE_HANDLE GetAssemblyModule(CORINFO_ASSEMBLY_HANDLE module);
239 CORINFO_ASSEMBLY_HANDLE GetModuleAssembly(CORINFO_MODULE_HANDLE module);
241 PEDecoder * GetModuleDecoder(CORINFO_MODULE_HANDLE scope);
243 void GetModuleFileName(CORINFO_MODULE_HANDLE module,
246 void EncodeModuleAsIndexes( CORINFO_MODULE_HANDLE fromHandle,
247 CORINFO_MODULE_HANDLE handle,
248 DWORD *pAssemblyIndex,
250 IMetaDataAssemblyEmit *pAssemblyEmit);
252 void EncodeClass( CORINFO_MODULE_HANDLE referencingModule,
253 CORINFO_CLASS_HANDLE classHandle,
254 SigBuilder *pSigBuilder,
255 LPVOID encodeContext,
256 ENCODEMODULE_CALLBACK pfnEncodeModule);
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);
267 virtual mdToken TryEncodeMethodAsToken(CORINFO_METHOD_HANDLE handle,
268 CORINFO_RESOLVED_TOKEN * pResolvedToken,
269 CORINFO_MODULE_HANDLE * referencingModule);
271 virtual DWORD TryEncodeMethodSlot(CORINFO_METHOD_HANDLE handle);
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);
281 // Encode generic dictionary signature
282 virtual void EncodeGenericSignature(
285 SigBuilder * pSigBuilder,
286 LPVOID encodeContext,
287 ENCODEMODULE_CALLBACK pfnEncodeModule);
290 BOOL IsEmptyString(mdString token,
291 CORINFO_MODULE_HANDLE module);
293 BOOL IsNativeCallableMethod(CORINFO_METHOD_HANDLE handle);
295 BOOL IsCachingOfInliningHintsEnabled()
297 return m_fCachingOfInliningHintsEnabled;
300 void DisableCachingOfInliningHints()
302 m_fCachingOfInliningHintsEnabled = FALSE;
305 HRESULT GetTypeDef( CORINFO_CLASS_HANDLE classHandle,
307 HRESULT GetMethodDef( CORINFO_METHOD_HANDLE methodHandle,
309 HRESULT GetFieldDef( CORINFO_FIELD_HANDLE fieldHandle,
312 void SetAssemblyHardBindList(__in_ecount( cHardBindList )
313 LPWSTR *pHardBindList,
314 DWORD cHardBindList);
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);
321 ICorCompilePreloader * PreloadModule(CORINFO_MODULE_HANDLE moduleHandle,
322 ICorCompileDataStore *pData,
323 CorProfileData *profileData);
326 HRESULT GetLoadHint(CORINFO_ASSEMBLY_HANDLE hAssembly,
327 CORINFO_ASSEMBLY_HANDLE hAssemblyDependency,
328 LoadHintEnum *loadHint,
329 LoadHintEnum *defaultLoadHint);
331 HRESULT GetAssemblyVersionInfo(CORINFO_ASSEMBLY_HANDLE Handle,
332 CORCOMPILE_VERSION_INFO *pInfo);
334 void GetAssemblyCodeBase(CORINFO_ASSEMBLY_HANDLE hAssembly,
337 void GetCallRefMap(CORINFO_METHOD_HANDLE hMethod,
338 GCRefMapBuilder * pBuilder);
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);
347 HRESULT SetVerboseLevel(
348 IN VerboseLevel level);
350 HRESULT GetBaseJitFlags(
351 IN CORINFO_METHOD_HANDLE hMethod,
352 OUT CORJIT_FLAGS *pFlags);
354 void* GetStubSize(void *pStubAddress, DWORD *pSizeToCopy);
356 HRESULT GetStubClone(void *pStub, BYTE *pBuffer, DWORD dwBufferSize);
358 BOOL GetIsGeneratingNgenPDB();
359 void SetIsGeneratingNgenPDB(BOOL fGeneratingNgenPDB);
361 #ifdef FEATURE_READYTORUN_COMPILER
362 CORCOMPILE_FIXUP_BLOB_KIND GetFieldBaseOffset(
363 CORINFO_CLASS_HANDLE classHnd,
364 DWORD * pBaseOffset);
366 BOOL NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd);
367 void EncodeTypeLayout(CORINFO_CLASS_HANDLE classHandle, SigBuilder * pSigBuilder);
369 BOOL AreAllClassesFullyLoaded(CORINFO_MODULE_HANDLE moduleHandle);
371 int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
373 int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
376 BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
378 //--------------------------------------------------------------------
379 // ZapperLoaderModules and the ZapperLoaderModuleTable
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
389 Module *LookupZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey)
392 const ZapperLoaderModuleTableEntry *pEntry = m_ZapperLoaderModuleTable.LookupPtr(pKey);
394 return pEntry->result;
398 void RecordZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey,
399 Module *pZapperLoaderModuleTable)
409 ZapperLoaderModuleTableEntry entry(*pKey, pZapperLoaderModuleTable);
410 m_ZapperLoaderModuleTable.Add(entry);
413 ZapperLoaderModuleTable m_ZapperLoaderModuleTable;
416 BOOL m_fCachingOfInliningHintsEnabled;
417 BOOL m_fGeneratingNgenPDB;
420 extern CEECompileInfo *g_pCEECompileInfo;
422 BOOL IsNgenPDBCompilationProcess();
425 // See comment at top of file for an explanation on the preloader
429 class CEEPreloader : public ICorCompilePreloader
433 ICorCompileDataStore *m_pData;
435 class MethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodDesc *> >
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)
447 class TypeSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<TypeHandle> >
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; }
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;
464 #ifdef FEATURE_FULL_NGEN
465 // Tentatively accepted instantiations
466 InlineSArray<TypeHandle, 20> m_speculativeTypes;
467 BOOL m_fSpeculativeTriage;
468 BOOL m_fDictionariesPopulated;
471 struct CompileMethodEntry
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
480 class CompileMethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<CompileMethodEntry> >
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)
490 static const CompileMethodEntry Null() { CompileMethodEntry e; e.pMD = NULL; return e; }
491 static bool IsNull(const CompileMethodEntry &e) { return e.pMD == NULL; }
494 SHash<CompileMethodSetTraits> m_compileMethodsHash;
496 // Array of methods that we need to compile.
497 SArray<MethodDesc*> m_uncompiledMethods;
499 int m_methodCompileLimit;
501 void AppendUncompiledMethod(MethodDesc *pMD)
503 STANDARD_VM_CONTRACT;
504 if (m_methodCompileLimit > 0)
506 m_uncompiledMethods.Append(pMD);
507 m_methodCompileLimit--;
511 struct DuplicateMethodEntry
514 MethodDesc * pDuplicateMD;
517 class DuplicateMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<DuplicateMethodEntry> >
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)
527 static const DuplicateMethodEntry Null() { DuplicateMethodEntry e; e.pMD = NULL; return e; }
528 static bool IsNull(const DuplicateMethodEntry &e) { return e.pMD == NULL; }
531 SHash<DuplicateMethodTraits> m_duplicateMethodsHash;
533 MethodDesc * CompileMethodStubIfNeeded(
536 ICorCompilePreloader::CORCOMPILE_CompileStubCallback pfnCallback,
537 LPVOID pCallbackContext);
540 CEEPreloader(Module *pModule,
541 ICorCompileDataStore *pData);
542 virtual ~CEEPreloader();
544 void Preload(CorProfileData * profileData);
545 DataImage * GetDataImage() { LIMITED_METHOD_CONTRACT; return m_image; }
546 ICorCompileDataStore * GetDataStore() { LIMITED_METHOD_CONTRACT; return m_pData; }
549 // ICorCompilerPreloader
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);
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);
565 void MethodReferencedByCompiledCode(CORINFO_METHOD_HANDLE handle);
567 BOOL IsUncompiledMethod(CORINFO_METHOD_HANDLE handle);
570 void AddToUncompiledMethods(MethodDesc *pMethod, BOOL fForStubs);
572 void ApplyTypeDependencyProductionsForType(TypeHandle t);
573 void ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceMT, TypeHandle elemTypeHnd);
576 void TriageTypeForZap(TypeHandle th, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
577 void TriageMethodForZap(MethodDesc* pMethod, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
579 void ExpandTypeDependencies(TypeHandle th);
580 void ExpandMethodDependencies(MethodDesc * pMD);
582 void TriageTypeSpecsFromSoftBoundModule(Module * pSoftBoundModule);
583 void TriageTypeFromSoftBoundModule(TypeHandle th, Module * pSoftBoundModule);
584 void TriageSpeculativeType(TypeHandle th);
585 void TriageSpeculativeInstantiations();
587 // Returns TRUE if new types or methods have been added by the triage
588 BOOL TriageForZap(BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
591 CORINFO_METHOD_HANDLE NextUncompiledMethod();
593 void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
595 void GenerateMethodStubs(
596 CORINFO_METHOD_HANDLE hMethod,
597 bool fNgenProfileImage,
598 CORCOMPILE_CompileStubCallback pfnCallback,
599 LPVOID pCallbackContext);
601 bool IsDynamicMethod(CORINFO_METHOD_HANDLE hMethod);
602 void SetMethodProfilingFlags(CORINFO_METHOD_HANDLE hMethod, DWORD flags);
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);
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);
618 BOOL CanPrerestoreEmbedClassHandle (CORINFO_CLASS_HANDLE classHnd);
619 BOOL CanPrerestoreEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHnd);
621 BOOL CanEmbedFunctionEntryPoint(CORINFO_METHOD_HANDLE methodHandle,
622 CORINFO_METHOD_HANDLE contextHandle,
623 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
625 BOOL DoesMethodNeedRestoringBeforePrestubIsRun(CORINFO_METHOD_HANDLE methodHandle);
627 BOOL CanSkipDependencyActivation(CORINFO_METHOD_HANDLE context,
628 CORINFO_MODULE_HANDLE moduleFrom,
629 CORINFO_MODULE_HANDLE moduleTo);
631 CORINFO_MODULE_HANDLE GetPreferredZapModuleForClassHandle(CORINFO_CLASS_HANDLE classHnd);
633 void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
635 CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token);
636 bool GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo);
638 CorCompileILRegion GetILRegion(mdMethodDef token);
640 CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
642 void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee);
647 void SetRVAsForFields(IMetaDataEmit * pEmit);
649 void GetRVAFieldData(mdFieldDef fd, PVOID * ppData, DWORD * pcbSize, DWORD * pcbAlignment);
653 #ifdef FEATURE_READYTORUN_COMPILER
654 void GetSerializedInlineTrackingMap(SBuffer* pBuffer);
657 void Error(mdToken token, Exception * pException);
663 RefCache(Module *pModule)
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
683 CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
685 m_sAssemblyRefMap.Init(FALSE,NULL);
691 HashMap m_sAssemblyRefMap;
694 struct AssemblySpecDefRefMapEntry {
695 AssemblySpec * m_pDef;
696 AssemblySpec * m_pRef;
699 class AssemblySpecDefRefMapTraits : public NoRemoveSHashTraits<DefaultSHashTraits<AssemblySpecDefRefMapEntry> >
702 typedef const AssemblySpec *key_t;
703 static const AssemblySpec * GetKey(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef; }
705 static count_t Hash(const AssemblySpec * k)
707 return const_cast<AssemblySpec *>(k)->Hash();
710 static BOOL Equals(const AssemblySpec * lhs, const AssemblySpec * rhs)
712 return const_cast<AssemblySpec *>(lhs)->CompareEx(const_cast<AssemblySpec *>(rhs), AssemblySpec::ASC_DefinitionEquality);
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; }
718 void OnDestructPerEntryCleanupAction(const AssemblySpecDefRefMapEntry& e)
724 static const bool s_DestructPerEntryCleanupAction = true;
727 typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
729 class CompilationDomain : public AppDomain,
730 public ICorCompilationDomain
735 BOOL m_fForceProfiling;
736 BOOL m_fForceInstrument;
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); };
743 // DDB 175659: Make sure that canCallNeedsRestore() returns FALSE during compilation
745 void setCannotCallNeedsRestore() { m_pTargetImage = NULL; }
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;
754 ReleaseHolder<IMetaDataAssemblyEmit> m_pEmit;
756 NewHolder<AssemblySpecHash> m_pDependencyRefSpecs;
758 AssemblySpecMapDefRefMapTable m_dependencyDefRefMap;
760 CORCOMPILE_DEPENDENCY *m_pDependencies;
761 USHORT m_cDependenciesCount, m_cDependenciesAlloc;
763 CQuickArray<RefCache*> m_rRefCaches;
765 HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
766 void ReleaseDependencyEmitter();
771 #ifndef DACCESS_COMPILE
772 CompilationDomain(BOOL fForceDebug = FALSE,
773 BOOL fForceProfiling = FALSE,
774 BOOL fForceInstrument = FALSE);
775 ~CompilationDomain();
780 HRESULT AddDependency(AssemblySpec *pRefSpec, PEAssembly *pFile);
782 AssemblySpec* FindAssemblyRefSpecForDefSpec(
783 AssemblySpec* pDefSpec);
785 PEAssembly *BindAssemblySpec(
787 BOOL fThrowOnFileNotFound,
788 BOOL fRaisePrebindEvents,
789 StackCrawlMark *pCallerStackMark = NULL,
790 BOOL fUseHostBinderIfAvailable = TRUE) DAC_EMPTY_RET(NULL);
792 BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
796 // Returns NULL on out-of-memory
797 RefCache *GetRefCache(Module *pModule)
803 INJECT_FAULT(return NULL;);
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];
812 // Add a new cache entry
815 if (FAILED(hr = m_rRefCaches.ReSizeNoThrow(uSize + 1)))
817 _ASSERTE(hr == E_OUTOFMEMORY);
821 m_rRefCaches[uSize] = new (nothrow) RefCache(pModule);
822 return m_rRefCaches[uSize];
825 void SetTarget(Assembly * pAssembly, Module *pModule);
827 void SetTargetImage(DataImage * pImage, CEEPreloader * pPreloader);
828 DataImage * GetTargetImage() { LIMITED_METHOD_CONTRACT; return m_pTargetImage; }
830 Assembly * GetTargetAssembly()
831 { LIMITED_METHOD_CONTRACT; return m_pTargetAssembly; }
832 Module * GetTargetModule()
833 { LIMITED_METHOD_CONTRACT; return m_pTargetModule; }
835 // ICorCompilationDomain
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);
841 #ifdef CROSSGEN_COMPILE
842 HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
845 void SetDependencyEmitter(IMetaDataAssemblyEmit *pEmitter);
848 #endif // FEATURE_NATIVE_IMAGE_GENERATION