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);
355 SIZE_T getPersonalityValue();
358 void* GetStubSize(void *pStubAddress, DWORD *pSizeToCopy);
360 HRESULT GetStubClone(void *pStub, BYTE *pBuffer, DWORD dwBufferSize);
362 BOOL GetIsGeneratingNgenPDB();
363 void SetIsGeneratingNgenPDB(BOOL fGeneratingNgenPDB);
365 #ifdef FEATURE_READYTORUN_COMPILER
366 CORCOMPILE_FIXUP_BLOB_KIND GetFieldBaseOffset(
367 CORINFO_CLASS_HANDLE classHnd,
368 DWORD * pBaseOffset);
370 BOOL NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd);
371 void EncodeTypeLayout(CORINFO_CLASS_HANDLE classHandle, SigBuilder * pSigBuilder);
373 BOOL AreAllClassesFullyLoaded(CORINFO_MODULE_HANDLE moduleHandle);
375 int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
377 int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
380 BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
382 //--------------------------------------------------------------------
383 // ZapperLoaderModules and the ZapperLoaderModuleTable
385 // When NGEN'ing we want to adjust the
386 // places where some items (i.e. generic instantiations) are placed, in order to get some of them
387 // placed into the module we are compiling. However, the
388 // results of ComputeLoaderModule must be stable for the duration
389 // of an entire instance of the VM, i.e. for the duration of a compilation
390 // process. Thus each time we place an item into a non-standard LoaderModule we record
393 Module *LookupZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey)
396 const ZapperLoaderModuleTableEntry *pEntry = m_ZapperLoaderModuleTable.LookupPtr(pKey);
398 return pEntry->result;
402 void RecordZapperLoaderModule(const ZapperLoaderModuleTableKey *pKey,
403 Module *pZapperLoaderModuleTable)
413 ZapperLoaderModuleTableEntry entry(*pKey, pZapperLoaderModuleTable);
414 m_ZapperLoaderModuleTable.Add(entry);
417 ZapperLoaderModuleTable m_ZapperLoaderModuleTable;
420 BOOL m_fCachingOfInliningHintsEnabled;
421 BOOL m_fGeneratingNgenPDB;
424 extern CEECompileInfo *g_pCEECompileInfo;
426 BOOL IsNgenPDBCompilationProcess();
429 // See comment at top of file for an explanation on the preloader
433 class CEEPreloader : public ICorCompilePreloader
437 ICorCompileDataStore *m_pData;
439 class MethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodDesc *> >
442 typedef MethodDesc *key_t;
443 static MethodDesc * GetKey(MethodDesc *md) { return md; }
444 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
445 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
451 class TypeSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<TypeHandle> >
454 typedef TypeHandle key_t;
455 static const TypeHandle Null() { return TypeHandle(); }
456 static bool IsNull(const TypeHandle &th) { return !!th.IsNull(); }
457 static TypeHandle GetKey(TypeHandle th) { return th; }
458 static count_t Hash(TypeHandle th) { return (count_t) th.AsTAddr(); }
459 static BOOL Equals(TypeHandle th1, TypeHandle th2) { return th1 == th2; }
462 // Cached results of instantiations triage
463 SHash<TypeSetTraits> m_acceptedTypes;
464 SHash<MethodSetTraits> m_acceptedMethods;
465 SHash<TypeSetTraits> m_rejectedTypes;
466 SHash<MethodSetTraits> m_rejectedMethods;
468 #ifdef FEATURE_FULL_NGEN
469 // Tentatively accepted instantiations
470 InlineSArray<TypeHandle, 20> m_speculativeTypes;
471 BOOL m_fSpeculativeTriage;
472 BOOL m_fDictionariesPopulated;
475 struct CompileMethodEntry
478 #ifndef FEATURE_FULL_NGEN // Unreferenced methods
479 bool fReferenced; // true when this method was referenced by other code
480 bool fScheduled; // true when this method was scheduled for compilation
484 class CompileMethodSetTraits : public NoRemoveSHashTraits< DefaultSHashTraits<CompileMethodEntry> >
487 typedef MethodDesc *key_t;
488 static MethodDesc * GetKey(CompileMethodEntry e) { return e.pMD; }
489 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
490 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
494 static const CompileMethodEntry Null() { CompileMethodEntry e; e.pMD = NULL; return e; }
495 static bool IsNull(const CompileMethodEntry &e) { return e.pMD == NULL; }
498 SHash<CompileMethodSetTraits> m_compileMethodsHash;
500 // Array of methods that we need to compile.
501 SArray<MethodDesc*> m_uncompiledMethods;
503 int m_methodCompileLimit;
505 void AppendUncompiledMethod(MethodDesc *pMD)
507 STANDARD_VM_CONTRACT;
508 if (m_methodCompileLimit > 0)
510 m_uncompiledMethods.Append(pMD);
511 m_methodCompileLimit--;
515 struct DuplicateMethodEntry
518 MethodDesc * pDuplicateMD;
521 class DuplicateMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<DuplicateMethodEntry> >
524 typedef MethodDesc *key_t;
525 static MethodDesc * GetKey(DuplicateMethodEntry e) { return e.pMD; }
526 static count_t Hash(MethodDesc *md) { return (count_t) (UINT_PTR) md; }
527 static BOOL Equals(MethodDesc *md1, MethodDesc *md2)
531 static const DuplicateMethodEntry Null() { DuplicateMethodEntry e; e.pMD = NULL; return e; }
532 static bool IsNull(const DuplicateMethodEntry &e) { return e.pMD == NULL; }
535 SHash<DuplicateMethodTraits> m_duplicateMethodsHash;
537 MethodDesc * CompileMethodStubIfNeeded(
540 ICorCompilePreloader::CORCOMPILE_CompileStubCallback pfnCallback,
541 LPVOID pCallbackContext);
544 CEEPreloader(Module *pModule,
545 ICorCompileDataStore *pData);
546 virtual ~CEEPreloader();
548 void Preload(CorProfileData * profileData);
549 DataImage * GetDataImage() { LIMITED_METHOD_CONTRACT; return m_image; }
550 ICorCompileDataStore * GetDataStore() { LIMITED_METHOD_CONTRACT; return m_pData; }
553 // ICorCompilerPreloader
556 DWORD MapMethodEntryPoint(CORINFO_METHOD_HANDLE handle);
557 DWORD MapClassHandle(CORINFO_CLASS_HANDLE handle);
558 DWORD MapMethodHandle(CORINFO_METHOD_HANDLE handle);
559 DWORD MapFieldHandle(CORINFO_FIELD_HANDLE handle);
560 DWORD MapAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE handle);
561 DWORD MapGenericHandle(CORINFO_GENERIC_HANDLE handle);
562 DWORD MapModuleIDHandle(CORINFO_MODULE_HANDLE handle);
564 void AddMethodToTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
565 void AddTypeToTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
566 BOOL IsMethodInTransitiveClosureOfInstantiations(CORINFO_METHOD_HANDLE handle);
567 BOOL IsTypeInTransitiveClosureOfInstantiations(CORINFO_CLASS_HANDLE handle);
569 void MethodReferencedByCompiledCode(CORINFO_METHOD_HANDLE handle);
571 BOOL IsUncompiledMethod(CORINFO_METHOD_HANDLE handle);
574 void AddToUncompiledMethods(MethodDesc *pMethod, BOOL fForStubs);
576 void ApplyTypeDependencyProductionsForType(TypeHandle t);
577 void ApplyTypeDependencyForSZArrayHelper(MethodTable * pInterfaceMT, TypeHandle elemTypeHnd);
580 void TriageTypeForZap(TypeHandle th, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
581 void TriageMethodForZap(MethodDesc* pMethod, BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
583 void ExpandTypeDependencies(TypeHandle th);
584 void ExpandMethodDependencies(MethodDesc * pMD);
586 void TriageTypeSpecsFromSoftBoundModule(Module * pSoftBoundModule);
587 void TriageTypeFromSoftBoundModule(TypeHandle th, Module * pSoftBoundModule);
588 void TriageSpeculativeType(TypeHandle th);
589 void TriageSpeculativeInstantiations();
591 // Returns TRUE if new types or methods have been added by the triage
592 BOOL TriageForZap(BOOL fAcceptIfNotSure, BOOL fExpandDependencies = TRUE);
595 CORINFO_METHOD_HANDLE NextUncompiledMethod();
597 void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
599 void GenerateMethodStubs(
600 CORINFO_METHOD_HANDLE hMethod,
601 bool fNgenProfileImage,
602 CORCOMPILE_CompileStubCallback pfnCallback,
603 LPVOID pCallbackContext);
605 bool IsDynamicMethod(CORINFO_METHOD_HANDLE hMethod);
606 void SetMethodProfilingFlags(CORINFO_METHOD_HANDLE hMethod, DWORD flags);
608 bool CanSkipMethodPreparation (
609 CORINFO_METHOD_HANDLE callerHnd, /* IN */
610 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
611 CorInfoIndirectCallReason *pReason = NULL,
612 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
614 BOOL CanEmbedClassID (CORINFO_CLASS_HANDLE typeHandle);
615 BOOL CanEmbedModuleID (CORINFO_MODULE_HANDLE moduleHandle);
616 BOOL CanEmbedModuleHandle(CORINFO_MODULE_HANDLE moduleHandle);
617 BOOL CanEmbedClassHandle (CORINFO_CLASS_HANDLE typeHandle);
618 BOOL CanEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHandle,
619 CORINFO_METHOD_HANDLE contextHandle);
620 BOOL CanEmbedFieldHandle (CORINFO_FIELD_HANDLE fieldHandle);
622 BOOL CanPrerestoreEmbedClassHandle (CORINFO_CLASS_HANDLE classHnd);
623 BOOL CanPrerestoreEmbedMethodHandle(CORINFO_METHOD_HANDLE methodHnd);
625 BOOL CanEmbedFunctionEntryPoint(CORINFO_METHOD_HANDLE methodHandle,
626 CORINFO_METHOD_HANDLE contextHandle,
627 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
629 BOOL DoesMethodNeedRestoringBeforePrestubIsRun(CORINFO_METHOD_HANDLE methodHandle);
631 BOOL CanSkipDependencyActivation(CORINFO_METHOD_HANDLE context,
632 CORINFO_MODULE_HANDLE moduleFrom,
633 CORINFO_MODULE_HANDLE moduleTo);
635 CORINFO_MODULE_HANDLE GetPreferredZapModuleForClassHandle(CORINFO_CLASS_HANDLE classHnd);
637 void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
639 CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token);
640 bool GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo);
642 CorCompileILRegion GetILRegion(mdMethodDef token);
644 CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry);
646 void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee);
651 void SetRVAsForFields(IMetaDataEmit * pEmit);
653 void GetRVAFieldData(mdFieldDef fd, PVOID * ppData, DWORD * pcbSize, DWORD * pcbAlignment);
657 #ifdef FEATURE_READYTORUN_COMPILER
658 void GetSerializedInlineTrackingMap(SBuffer* pBuffer);
661 void Error(mdToken token, Exception * pException);
667 RefCache(Module *pModule)
681 // HashMap::Init can throw due to OOM. Our ctor can't. Since this whole
682 // thing is for use inside CEECompileInfo methods, it doesn't make sense to
683 // use an exception model. Thus we probably have to move the hashmap init
684 // calls out of the ctor so can catch these exceptions and translate them to
687 CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
689 m_sAssemblyRefMap.Init(FALSE,NULL);
695 HashMap m_sAssemblyRefMap;
698 struct AssemblySpecDefRefMapEntry {
699 AssemblySpec * m_pDef;
700 AssemblySpec * m_pRef;
703 class AssemblySpecDefRefMapTraits : public NoRemoveSHashTraits<DefaultSHashTraits<AssemblySpecDefRefMapEntry> >
706 typedef const AssemblySpec *key_t;
707 static const AssemblySpec * GetKey(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef; }
709 static count_t Hash(const AssemblySpec * k)
711 return const_cast<AssemblySpec *>(k)->Hash();
714 static BOOL Equals(const AssemblySpec * lhs, const AssemblySpec * rhs)
716 return const_cast<AssemblySpec *>(lhs)->CompareEx(const_cast<AssemblySpec *>(rhs), AssemblySpec::ASC_DefinitionEquality);
719 static const AssemblySpecDefRefMapEntry Null() { AssemblySpecDefRefMapEntry e; e.m_pDef = NULL; return e; }
720 static bool IsNull(const AssemblySpecDefRefMapEntry &e) { return e.m_pDef == NULL; }
722 void OnDestructPerEntryCleanupAction(const AssemblySpecDefRefMapEntry& e)
728 static const bool s_DestructPerEntryCleanupAction = true;
731 typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
733 class CompilationDomain : public AppDomain,
734 public ICorCompilationDomain
739 BOOL m_fForceProfiling;
740 BOOL m_fForceInstrument;
742 // TODO: During ngen, we need to determine whether we can call NeedsRestore
743 // before the preloader has been initialized. This is accomplished via this
744 // method. This code needs to be cleaned up. See bug #284709 for background.
745 BOOL canCallNeedsRestore() { return (m_pTargetImage != NULL); };
747 // DDB 175659: Make sure that canCallNeedsRestore() returns FALSE during compilation
749 void setCannotCallNeedsRestore() { m_pTargetImage = NULL; }
753 Assembly *m_pTargetAssembly; // Assembly being compiled
754 Module *m_pTargetModule; // Module currently being compiled. Needed for multi-module assemblies
755 DataImage *m_pTargetImage; // Data image
756 CEEPreloader *m_pTargetPreloader;
758 ReleaseHolder<IMetaDataAssemblyEmit> m_pEmit;
760 NewHolder<AssemblySpecHash> m_pDependencyRefSpecs;
762 AssemblySpecMapDefRefMapTable m_dependencyDefRefMap;
764 CORCOMPILE_DEPENDENCY *m_pDependencies;
765 USHORT m_cDependenciesCount, m_cDependenciesAlloc;
767 CQuickArray<RefCache*> m_rRefCaches;
769 HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
770 void ReleaseDependencyEmitter();
775 #ifndef DACCESS_COMPILE
776 CompilationDomain(BOOL fForceDebug = FALSE,
777 BOOL fForceProfiling = FALSE,
778 BOOL fForceInstrument = FALSE);
779 ~CompilationDomain();
784 HRESULT AddDependency(AssemblySpec *pRefSpec, PEAssembly *pFile);
786 AssemblySpec* FindAssemblyRefSpecForDefSpec(
787 AssemblySpec* pDefSpec);
789 PEAssembly *BindAssemblySpec(
791 BOOL fThrowOnFileNotFound,
792 BOOL fRaisePrebindEvents,
793 StackCrawlMark *pCallerStackMark = NULL,
794 BOOL fUseHostBinderIfAvailable = TRUE) DAC_EMPTY_RET(NULL);
796 BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
800 // Returns NULL on out-of-memory
801 RefCache *GetRefCache(Module *pModule)
807 INJECT_FAULT(return NULL;);
811 unsigned uSize = (unsigned) m_rRefCaches.Size();
812 for (unsigned i = 0; i < uSize; i++)
813 if (m_rRefCaches[i]->m_pModule == pModule)
814 return m_rRefCaches[i];
816 // Add a new cache entry
819 if (FAILED(hr = m_rRefCaches.ReSizeNoThrow(uSize + 1)))
821 _ASSERTE(hr == E_OUTOFMEMORY);
825 m_rRefCaches[uSize] = new (nothrow) RefCache(pModule);
826 return m_rRefCaches[uSize];
829 void SetTarget(Assembly * pAssembly, Module *pModule);
831 void SetTargetImage(DataImage * pImage, CEEPreloader * pPreloader);
832 DataImage * GetTargetImage() { LIMITED_METHOD_CONTRACT; return m_pTargetImage; }
834 Assembly * GetTargetAssembly()
835 { LIMITED_METHOD_CONTRACT; return m_pTargetAssembly; }
836 Module * GetTargetModule()
837 { LIMITED_METHOD_CONTRACT; return m_pTargetModule; }
839 // ICorCompilationDomain
841 HRESULT SetContextInfo(LPCWSTR exePath, BOOL isExe) DAC_EMPTY_RET(E_FAIL);
842 HRESULT GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
843 DWORD *cDependencies) DAC_EMPTY_RET(E_FAIL);
845 #ifdef CROSSGEN_COMPILE
846 HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
849 void SetDependencyEmitter(IMetaDataAssemblyEmit *pEmitter);
852 #endif // FEATURE_NATIVE_IMAGE_GENERATION