From d4a84e41d18f6154d6751eb4203e8748560a362d Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 1 Nov 2018 19:07:49 -0700 Subject: [PATCH 01/28] Preliminary Changes --- src/inc/pedecoder.h | 7 ++++++- src/inc/readytorun.h | 3 ++- src/tools/crossgen/crossgen.cpp | 19 +++++++++++++++++-- src/tools/r2rdump/R2RSection.cs | 3 ++- src/utilcode/pedecoder.cpp | 23 ++++++++++++++++++++--- src/vm/ceeload.cpp | 23 ++++++++++++++++++----- src/vm/ceeload.h | 1 + src/vm/inlinetracking.h | 21 +++++++++++---------- src/vm/jitinterface.cpp | 7 ++++--- src/vm/peimage.cpp | 2 +- src/vm/readytoruninfo.cpp | 16 ++++++++++++++-- src/vm/readytoruninfo.h | 2 ++ src/vm/zapsig.cpp | 2 +- src/zap/zapimage.cpp | 7 +++---- src/zap/zapimage.h | 2 ++ src/zap/zapimport.cpp | 11 ++++++----- src/zap/zapinfo.cpp | 10 +++++----- src/zap/zapper.cpp | 2 +- src/zap/zapreadytorun.cpp | 19 ++++++++++++++++++- src/zap/zapreadytorun.h | 2 ++ 20 files changed, 136 insertions(+), 46 deletions(-) diff --git a/src/inc/pedecoder.h b/src/inc/pedecoder.h index 2d6c5f5f4f0f..5344aca75122 100644 --- a/src/inc/pedecoder.h +++ b/src/inc/pedecoder.h @@ -49,6 +49,7 @@ typedef DPTR(struct CORCOMPILE_HEADER) PTR_CORCOMPILE_HEADER; #include "readytorun.h" typedef DPTR(struct READYTORUN_HEADER) PTR_READYTORUN_HEADER; +typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION; typedef DPTR(IMAGE_COR20_HEADER) PTR_IMAGE_COR20_HEADER; @@ -340,6 +341,10 @@ class PEDecoder BOOL HasReadyToRunHeader() const; READYTORUN_HEADER *GetReadyToRunHeader() const; +#ifdef FEATURE_READYTORUN_COMPILER + PTR_CVOID GetReadyToRunManifestMetadata() const; +#endif + void GetEXEStackSizes(SIZE_T *PE_SizeOfStackReserve, SIZE_T *PE_SizeOfStackCommit) const; CHECK CheckWillCreateGuardPage() const; @@ -400,7 +405,7 @@ class PEDecoder IMAGE_NT_HEADERS *FindNTHeaders() const; IMAGE_COR20_HEADER *FindCorHeader() const; CORCOMPILE_HEADER *FindNativeHeader() const; - READYTORUN_HEADER *FindReadyToRunHeader() const; + READYTORUN_HEADER *FindReadyToRunHeader() const; // Flat mapping utilities RVA InternalAddressToRva(SIZE_T address) const; diff --git a/src/inc/readytorun.h b/src/inc/readytorun.h index 0f5183ff3a77..882edc4687fa 100644 --- a/src/inc/readytorun.h +++ b/src/inc/readytorun.h @@ -60,7 +60,8 @@ enum ReadyToRunSectionType READYTORUN_SECTION_AVAILABLE_TYPES = 108, READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109, READYTORUN_SECTION_INLINING_INFO = 110, // Added in V2.1 - READYTORUN_SECTION_PROFILEDATA_INFO = 111 // Added in V2.2 + READYTORUN_SECTION_PROFILEDATA_INFO = 111, // Added in V2.2 + READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.2 // If you add a new section consider whether it is a breaking or non-breaking change. // Usually it is non-breaking, but if it is preferable to have older runtimes fail diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 48e52db41414..275d9acc5e30 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -34,7 +34,7 @@ enum ReturnValues #define NumItems(s) (sizeof(s) / sizeof(s[0])) STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzPlatformWinmdPaths, LPCWSTR pwzDiasymreaderPath); -STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr); +STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, LPCWSTR pwzVersionBubbleAssemblyPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr); void SetSvcLogger(ICorSvcLogger *pCorSvcLogger); void SetMscorlibPath(LPCWSTR wzSystemDirectory); @@ -106,6 +106,7 @@ void PrintUsageHelper() Output( W("Usage: crossgen [args] \n") W("\n") + // Command-Line switch help W(" /? or /help - Display this screen\n") W(" /nologo - Prevents displaying the logo\n") W(" /silent - Do not display completion message\n") @@ -121,6 +122,8 @@ void PrintUsageHelper() W(" - List of paths containing localized assembly directories\n") W(" /App_Paths \n") W(" - List of paths containing user-application assemblies and resources\n") + W(" /Version_Bubble_Assembly_Paths \n") + W(" - List of paths containing assemblies contained in a single version bubble\n") #ifndef NO_NGENPDB W(" /App_Ni_Paths \n") W(" - List of paths containing user-application native images\n") @@ -416,6 +419,8 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) LPCWSTR pwzAppNiPaths = nullptr; LPCWSTR pwzPlatformAssembliesPaths = nullptr; LPCWSTR pwzPlatformWinmdPaths = nullptr; + // TODO Add Variable Num of cli arguments + LPCWSTR pwzVersionBubbleAssemblyPaths = nullptr; StackSString wzDirectoryToStorePDB; bool fCreatePDB = false; bool fGeneratePDBLinesInfo = false; @@ -468,6 +473,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) while (argc > 0) { + // Command-line parsing if (MatchParameter(*argv, W("?")) || MatchParameter(*argv, W("help"))) { @@ -585,6 +591,14 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) { pwzPlatformAssembliesPaths = argv[1]; + // skip path list + argv++; + argc--; + } + else if (MatchParameter(*argv, W("Version_Bubble_Assembly_Paths")) && (argc > 1)) + { + pwzVersionBubbleAssemblyPaths = argv[1]; + // skip path list argv++; argc--; @@ -911,7 +925,8 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) pwzPlatformResourceRoots, pwzAppPaths, pwzOutputFilename, - pwzPlatformWinmdPaths + pwzPlatformWinmdPaths, + pwzVersionBubbleAssemblyPaths #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) , NULL, // ICorSvcLogger diff --git a/src/tools/r2rdump/R2RSection.cs b/src/tools/r2rdump/R2RSection.cs index 125d04065752..d56e386367af 100644 --- a/src/tools/r2rdump/R2RSection.cs +++ b/src/tools/r2rdump/R2RSection.cs @@ -26,7 +26,8 @@ public enum SectionType READYTORUN_SECTION_AVAILABLE_TYPES = 108, READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109, READYTORUN_SECTION_INLINING_INFO = 110, - READYTORUN_SECTION_PROFILEDATA_INFO = 111 + READYTORUN_SECTION_PROFILEDATA_INFO = 111, + READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.2 } /// diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index bd0451d7bde0..65e5e77a95ed 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2474,8 +2474,6 @@ CORCOMPILE_METHOD_PROFILE_LIST *PEDecoder::GetNativeProfileDataList(COUNT_T * pS RETURN PTR_CORCOMPILE_METHOD_PROFILE_LIST(GetDirectoryData(pDir)); } - - PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const { CONTRACT(PTR_CVOID) @@ -2487,8 +2485,27 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const GC_NOTRIGGER; } CONTRACT_END; + IMAGE_DATA_DIRECTORY *pDir; + if (HasReadyToRunHeader()) + { + READYTORUN_HEADER * pHeader = GetReadyToRunHeader(); + + PTR_READYTORUN_SECTION pSections = dac_cast(dac_cast(pHeader) + sizeof(READYTORUN_HEADER)); + for (DWORD i = 0; i < pHeader->NumberOfSections; i++) + { + // Verify that section types are sorted + _ASSERTE(i == 0 || (pSections[i - 1].Type < pSections[i].Type)); - IMAGE_DATA_DIRECTORY *pDir = GetMetaDataHelper(METADATA_SECTION_MANIFEST); + READYTORUN_SECTION * pSection = pSections + i; + if (pSection->Type == READYTORUN_SECTION_MANIFEST_METADATA) + // Set pDir to the address of the manifest metadata section + pDir = &pSection->Section; + } + } + else + { + pDir = GetMetaDataHelper(METADATA_SECTION_MANIFEST); + } if (pSize != NULL) *pSize = VAL32(pDir->Size); diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 9c272e9b2425..8d722cd8b144 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -3579,7 +3579,7 @@ BOOL Module::IsWindowsRuntimeModule() return IsAfContentType_WindowsRuntime(dwFlags); } - +// Update this? BOOL Module::IsInCurrentVersionBubble() { LIMITED_METHOD_CONTRACT; @@ -3594,7 +3594,7 @@ BOOL Module::IsInCurrentVersionBubble() return TRUE; if (IsReadyToRunCompilation()) - return FALSE; + return TRUE; #ifdef FEATURE_COMINTEROP if (g_fNGenWinMDResilient) @@ -10277,9 +10277,22 @@ Module *Module::GetModuleFromIndex(DWORD ix) } CONTRACT_END; - if (HasNativeImage()) + if (HasNativeOrReadyToRunImage()) { RETURN ZapSig::DecodeModuleFromIndex(this, ix); + // CORCOMPILE_IMPORT_TABLE_ENTRY *p; + // if (IsReadyToRun()) + // { + // //PRECONDITION(GetNativeImage()->CheckReadyToRunImportFromIndex(ix)); + // p = GetNativeOrReadyToRunImage()->GetReadyToRunImportFromIndex(ix); + // } + // else + // { + // PRECONDITION(GetNativeImage()->CheckNativeImportFromIndex(ix)); + // p = GetNativeImage()->GetNativeImportFromIndex(ix); + // } + + // RETURN ZapSig::DecodeModuleFromIndexes(this, p->wAssemblyRid, p->wModuleRid); } else { @@ -10354,8 +10367,8 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - - RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed); + // Check if Image is even R2R? + RETURN GetFile()->IsILImageReadyToRun() ? GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed) : GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed); } diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index b421484e5aaf..98b5f05371c3 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -2393,6 +2393,7 @@ class Module CrstHolder ch(this->GetLookupTableCrst()); m_pMemberRefToDescHashTable->Insert(token, value); } + // This call void StoreMemberRef(mdMemberRef token, MethodDesc *value) { WRAPPER_NO_CONTRACT; diff --git a/src/vm/inlinetracking.h b/src/vm/inlinetracking.h index 976a0e72db84..0d729099e89d 100644 --- a/src/vm/inlinetracking.h +++ b/src/vm/inlinetracking.h @@ -166,17 +166,17 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap; // It doesn't require any load time unpacking and serves requests directly from NGEN image. // // It is composed of two arrays: -// m_inlineeIndex - sorted (by ZapInlineeRecord.key i.e. by module then token) array of ZapInlineeRecords, given an inlinee module name hash (8 bits) -// and a method token (24 bits) we use binary search to find if this method has ever been inlined in NGen-ed code of this image. -// Each record has m_offset, which is an offset inside m_inlinersBuffer, it has more data on where the method got inlined. +// m_inlineeIndex - sorted (by ZapInlineeRecord.key i.e. by module then token) array of ZapInlineeRecords, given an inlinee module name hash (8 bits) +// and a method token (24 bits) we use binary search to find if this method has ever been inlined in NGen-ed code of this image. +// Each record has m_offset, which is an offset inside m_inlinersBuffer, it has more data on where the method got inlined. // -// It is totally possible to have more than one ZapInlineeRecords with the same key, not only due hash collision, but also due to -// the fact that we create one record for each (inlinee module / inliner module) pair. -// For example: we have MyModule!MyType that uses mscorlib!List. Let's say List.ctor got inlined into -// MyType.GetAllThinds() and into List.FindAll. In this case we'll have two InlineeRecords for mscorlib!List.ctor -// one for MyModule and another one for mscorlib. -// PersistentInlineTrackingMap.GetInliners() always reads all ZapInlineeRecords as long as they have the same key, few of them filtered out -// as hash collisions others provide legitimate inlining information for methods from different modules. +// It is totally possible to have more than one ZapInlineeRecords with the same key, not only due hash collision, but also due to +// the fact that we create one record for each (inlinee module / inliner module) pair. +// For example: we have MyModule!MyType that uses mscorlib!List. Let's say List.ctor got inlined into +// MyType.GetAllThinds() and into List.FindAll. In this case we'll have two InlineeRecords for mscorlib!List.ctor +// one for MyModule and another one for mscorlib. +// PersistentInlineTrackingMap.GetInliners() always reads all ZapInlineeRecords as long as they have the same key, few of them filtered out +// as hash collisions others provide legitimate inlining information for methods from different modules. // // m_inlinersBuffer - byte array compressed by NibbleWriter. At any valid offset taken from ZapInlineeRecord from m_inlineeIndex, there is a compressed chunk // of this format: @@ -257,6 +257,7 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap; // +-----------------+------------------------+------+------+--------+------+-------------+ // | - - - | SavedInlinersCount (N) | rid1 | rid2 | ...... | ridN | - - - | // +-----------------+------------------------+------+------+--------+------+-------------+ +// Contents above will either likely need changing or some other mechanism will be required to reference methods // diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 266f0c8f1893..3f86250564f2 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -676,17 +676,18 @@ BOOL CEEInfo::shouldEnforceCallvirtRestriction( // and the impact of the cut was vetted with partners. It would not be appropriate // to increase that unreported set without additional review. - +// This needs to be updated to allow cross-assembly inlining +// TODO Undo this once prototyping is finished bool IsInSameVersionBubble(Assembly * current, Assembly * target) { LIMITED_METHOD_CONTRACT; // trivial case: current and target are identical // DO NOT change this without reading the notice above - if (current == target) + //if (current == target) return true; - return false; + // return false; } // Returns true if the assemblies defining current and target are in the same version bubble diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index 6b066ff2f505..a7f1cd2e530a 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -469,7 +469,7 @@ IMDInternalImport* PEImage::GetNativeMDImport(BOOL loadAllowed) MODE_ANY; } CONTRACTL_END; - + // Does this need to be something else? It might work either way if (m_pNativeMDImport == NULL) { if (loadAllowed) diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index c608070d2b88..6aef45ac8df8 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -455,7 +455,7 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker STANDARD_VM_CONTRACT; PEFile * pFile = pModule->GetFile(); - + // ? if (!IsReadyToRunEnabled()) { // Log message is ignored in this case. @@ -601,7 +601,8 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT pamTracker, &m_pPersistentInlineTrackingMap); } } - // Fpr format version 2.2 and later, there is an optional profile-data section + + // For format version 2.2 and later, there is an optional profile-data section if (IsImageVersionAtLeast(2, 2)) { IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = FindSection(READYTORUN_SECTION_PROFILEDATA_INFO); @@ -613,6 +614,17 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT pModule->SetMethodProfileList(pMethodProfileList); } } + + // TODO Change to incremented version + if (IsImageVersionAtLeast(2, 2)) + { + IMAGE_DATA_DIRECTORY * pManifestMetadata = FindSection(READYTORUN_SECTION_MANIFEST_METADATA); + if (pManifestMetadata != NULL) + { + NativeParser parser = NativeParser(&m_nativeReader, pManifestMetadata->VirtualAddress); + m_pMetaDataHashtable = NativeHashtable(parser); + } + } } static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pModule) diff --git a/src/vm/readytoruninfo.h b/src/vm/readytoruninfo.h index fea5b33c14a3..ff55b8de8503 100644 --- a/src/vm/readytoruninfo.h +++ b/src/vm/readytoruninfo.h @@ -43,6 +43,8 @@ class ReadyToRunInfo NativeFormat::NativeArray m_methodDefEntryPoints; NativeFormat::NativeHashtable m_instMethodEntryPoints; NativeFormat::NativeHashtable m_availableTypesHashtable; + // TODO Should this be a hash table? + NativeFormat::NativeHashtable m_pMetaDataHashtable; Crst m_Crst; PtrHashMap m_entryPointToMethodDescMap; diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index b883eaf14d62..57550932af42 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -1202,7 +1202,7 @@ BOOL ZapSig::EncodeMethod( // GetSvcLogger()->Printf(W("ReadyToRun: Method reference outside of current version bubble cannot be encoded\n")); ThrowHR(E_FAIL); } - _ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); + //_ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); methodToken = pResolvedToken->token; diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 7dce3af285d6..90be1b2b47db 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1082,10 +1082,7 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) { - if (!IsReadyToRunCompilation()) - { - OutputManifestMetadata(); - } + OutputManifestMetadata(); OutputTables(); @@ -1835,6 +1832,8 @@ void ZapImage::Compile() OutputTypesTableForReadyToRun(m_pMDImport); OutputInliningTableForReadyToRun(); OutputProfileDataForReadyToRun(); + OutputManifestMetadataForReadyToRun(); + } else #endif diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h index 36266d337018..832f2b198e99 100644 --- a/src/zap/zapimage.h +++ b/src/zap/zapimage.h @@ -596,6 +596,7 @@ class ZapImage void OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport); void OutputInliningTableForReadyToRun(); void OutputProfileDataForReadyToRun(); + void OutputManifestMetadataForReadyToRun(); void CopyDebugDirEntry(); void CopyWin32VersionResource(); @@ -691,6 +692,7 @@ class ZapImage } static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags); + static DWORD EncodeModuleHelper(LPVOID compileContext, CORINFO_MODULE_HANDLE referencedModule); BOOL IsVTableGapMethod(mdMethodDef md); diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index 7b847e943037..6debf62903c9 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -941,6 +941,7 @@ ZapImport * ZapImportTable::GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE CORINFO_MODULE_HANDLE ZapImportTable::TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder) { + // Use def tokens and module references? if (!GetCompileInfo()->IsInCurrentVersionBubble(module)) module = GetImage()->GetModuleHandle(); @@ -1777,7 +1778,7 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k if ((kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DICTIONARY_LOOKUP_THISOBJ) { CORINFO_CLASS_HANDLE hClassContext = GetJitInfo()->getMethodClass(pResolvedToken->tokenContext); - GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), hClassContext, &sigBuilder, NULL, NULL); + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), hClassContext, &sigBuilder, this, EncodeModuleHelper); } switch (pLookup->runtimeLookupFlags) @@ -1795,7 +1796,7 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k { _ASSERTE(pLookup->runtimeLookupArgs != NULL); sigBuilder.AppendData(ENCODE_DECLARINGTYPE_HANDLE); - GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), (CORINFO_CLASS_HANDLE)pLookup->runtimeLookupArgs, &sigBuilder, NULL, NULL); + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), (CORINFO_CLASS_HANDLE)pLookup->runtimeLookupArgs, &sigBuilder, this, EncodeModuleHelper); } else { @@ -1844,8 +1845,8 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind sigBuilder.AppendData(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); - GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), handle, &sigBuilder, NULL, NULL); - + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), handle, &sigBuilder, this, EncodeModuleHelper); + // CHANGE IT HERE pImport->SetBlob(GetBlob(&sigBuilder)); } @@ -1863,7 +1864,7 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind if (delegateType != NULL) { _ASSERTE((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DELEGATE_CTOR); - GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), delegateType, &sigBuilder, NULL, NULL); + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), delegateType, &sigBuilder, this, EncodeModuleHelper); } return GetImportForSignature((void *)(uintptr_t)((kind << 1) | 1), &sigBuilder); diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index b94809f45ebc..3ce3e6d845bc 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -1425,11 +1425,11 @@ CORINFO_MODULE_HANDLE ZapInfo::embedModuleHandle(CORINFO_MODULE_HANDLE handle, { _ASSERTE(ppIndirection != NULL); - if (IsReadyToRunCompilation()) - { - _ASSERTE(!"embedModuleHandle"); - ThrowHR(E_NOTIMPL); - } + //if (IsReadyToRunCompilation()) + //{ + // _ASSERTE(!"embedModuleHandle"); + // ThrowHR(E_NOTIMPL); + //} BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedModuleHandle(handle); if (fHardbound) diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 6d1cbd99d18f..d43ce43de9f7 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -32,7 +32,7 @@ static bool s_fNGenNoMetaData; // Zapper Object instead of creating one on your own. -STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr) +STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, LPCWSTR pwzVersionBubbleAssemblyPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr) { HRESULT hr = S_OK; diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp index 099ef41c2cb0..94b8534cd6d7 100644 --- a/src/zap/zapreadytorun.cpp +++ b/src/zap/zapreadytorun.cpp @@ -254,7 +254,7 @@ void ZapImage::OutputEntrypointsTableForReadyToRun() resolvedToken.token = token; resolvedToken.hClass = pMethod->GetClassHandle(); resolvedToken.hMethod = pMethod->GetHandle(); - GetCompileInfo()->EncodeMethod(module, pMethod->GetHandle(), &sigBuilder, NULL, NULL, &resolvedToken); + GetCompileInfo()->EncodeMethod(module, pMethod->GetHandle(), &sigBuilder, m_pImportTable, EncodeModuleHelper, &resolvedToken); DWORD cbBlob; PVOID pBlob = sigBuilder.GetSignature(&cbBlob); @@ -326,6 +326,15 @@ class DebugInfoVertex : public NativeFormat::Vertex } } }; +// At ngen time Zapper::CompileModule PlaceFixups called from +// code:ZapSig.GetSignatureForTypeHandle +// +/*static*/ DWORD ZapImage::EncodeModuleHelper(LPVOID compileContext, + CORINFO_MODULE_HANDLE referencedModule) +{ + ZapImportTable * pTable = (ZapImportTable *)compileContext; + return pTable->GetIndexOfModule(referencedModule); +} void ZapImage::OutputDebugInfoForReadyToRun() { @@ -397,6 +406,14 @@ void ZapImage::OutputProfileDataForReadyToRun() } } +void ZapImage::OutputManifestMetadataForReadyToRun() +{ + if (m_pMetaDataSection != nullptr) + { + GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_MANIFEST_METADATA, m_pMetaDataSection); + } +} + void ZapImage::OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport) { NativeWriter writer; diff --git a/src/zap/zapreadytorun.h b/src/zap/zapreadytorun.h index cf7ad0677b7a..d9409e9b6253 100644 --- a/src/zap/zapreadytorun.h +++ b/src/zap/zapreadytorun.h @@ -59,6 +59,8 @@ class ZapReadyToRunHeader : public ZapNode } virtual void Save(ZapWriter * pZapWriter); + + DWORD EncodeModuleHelper(LPVOID compileContext, CORINFO_MODULE_HANDLE referencedModule); }; #endif // __ZAPREADYTORUN_H__ From 802198e753ea5e5d47fb17092bba9c53f358fc5a Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Fri, 2 Nov 2018 21:00:43 -0700 Subject: [PATCH 02/28] Module Index Resolution --- src/inc/readytorun.h | 2 +- src/vm/ceeload.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/inc/readytorun.h b/src/inc/readytorun.h index 882edc4687fa..faccfd07a6d4 100644 --- a/src/inc/readytorun.h +++ b/src/inc/readytorun.h @@ -61,7 +61,7 @@ enum ReadyToRunSectionType READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109, READYTORUN_SECTION_INLINING_INFO = 110, // Added in V2.1 READYTORUN_SECTION_PROFILEDATA_INFO = 111, // Added in V2.2 - READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.2 + READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.3 // If you add a new section consider whether it is a breaking or non-breaking change. // Usually it is non-breaking, but if it is preferable to have older runtimes fail diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 8d722cd8b144..0d498a9b3291 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10280,11 +10280,26 @@ Module *Module::GetModuleFromIndex(DWORD ix) if (HasNativeOrReadyToRunImage()) { RETURN ZapSig::DecodeModuleFromIndex(this, ix); + // // CORCOMPILE_IMPORT_TABLE_ENTRY *p; + // // if (IsReadyToRun()) + // // { + // // //PRECONDITION(GetNativeImage()->CheckReadyToRunImportFromIndex(ix)); + // // p = GetNativeOrReadyToRunImage()->GetReadyToRunImportFromIndex(ix); + // // } + // // else + // // { + // // PRECONDITION(GetNativeImage()->CheckNativeImportFromIndex(ix)); + // // p = GetNativeImage()->GetNativeImportFromIndex(ix); + // // } + + // // RETURN ZapSig::DecodeModuleFromIndexes(this, p->wAssemblyRid, p->wModuleRid); // CORCOMPILE_IMPORT_TABLE_ENTRY *p; // if (IsReadyToRun()) // { // //PRECONDITION(GetNativeImage()->CheckReadyToRunImportFromIndex(ix)); - // p = GetNativeOrReadyToRunImage()->GetReadyToRunImportFromIndex(ix); + // //GetReadyToRunInfo()->GetReadyToRunImportFromIndex(ix); + // RETURN ZapSig::DecodeModuleFromIndexes(this, ix, 0); + // } // else // { From 6225fe0afbbba5cc09ce17e2b6fe50d846ea4a0a Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 20 Nov 2018 11:32:17 -0800 Subject: [PATCH 03/28] Change infoModule encoding --- src/utilcode/pedecoder.cpp | 3 ++- src/vm/ceeload.cpp | 11 +++++++++-- src/vm/peimage.cpp | 4 ++-- src/vm/zapsig.cpp | 27 ++++++++++++++++++++------- src/zap/zapimport.cpp | 5 +++++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 65e5e77a95ed..8db0c9fdd999 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2479,7 +2479,8 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const CONTRACT(PTR_CVOID) { INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); + // Check R2R + //PRECONDITION(CheckNativeHeader() || true); POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); // TBD - may not store metadata for IJW NOTHROW; GC_NOTRIGGER; diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 0d498a9b3291..3f3387c1ce60 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10378,12 +10378,19 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) if (loadAllowed) THROWS; else NOTHROW; if (loadAllowed) INJECT_FAULT(COMPlusThrowOM()); else FORBID_FAULT; MODE_ANY; - PRECONDITION(HasNativeImage()); + PRECONDITION(HasNativeOrReadyToRunImage()); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; // Check if Image is even R2R? - RETURN GetFile()->IsILImageReadyToRun() ? GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed) : GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed); + if (GetFile()->IsILImageReadyToRun()) + { + RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed); + } + else + { + RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed); + } } diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index a7f1cd2e530a..0711a7a8fe8c 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -462,7 +462,7 @@ IMDInternalImport* PEImage::GetNativeMDImport(BOOL loadAllowed) CONTRACTL { INSTANCE_CHECK; - PRECONDITION(HasNativeHeader()); + PRECONDITION(HasNativeHeader() || HasReadyToRunHeader()); if (loadAllowed) GC_TRIGGERS; else GC_NOTRIGGER; if (loadAllowed) THROWS; else NOTHROW; if (loadAllowed) INJECT_FAULT(COMPlusThrowOM()); else FORBID_FAULT; @@ -487,7 +487,7 @@ void PEImage::OpenNativeMDImport() CONTRACTL { INSTANCE_CHECK; - PRECONDITION(HasNativeHeader()); + PRECONDITION(HasNativeHeader() || HasReadyToRunHeader()); GC_TRIGGERS; THROWS; MODE_ANY; diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 57550932af42..4b3025c61c25 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -760,7 +760,7 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, fValidAssemblyRef = FALSE; } } - + if (fValidAssemblyRef) { pAssembly = fromModule->GetAssemblyIfLoaded( @@ -781,9 +781,9 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, TypeHandle ZapSig::DecodeType(Module *pEncodeModuleContext, - Module *pInfoModule, - PCCOR_SIGNATURE pBuffer, - ClassLoadLevel level) + Module *pInfoModule, + PCCOR_SIGNATURE pBuffer, + ClassLoadLevel level) { CONTRACTL { @@ -803,11 +803,11 @@ TypeHandle ZapSig::DecodeType(Module *pEncodeModuleContext, TypeHandle th = p.GetTypeHandleThrowing(pInfoModule, &typeContext, ClassLoader::LoadTypes, - level, + level, level < CLASS_LOADED, // For non-full loads, drop a level when loading generic arguments NULL, pZapSigContext); - + return th; } @@ -846,6 +846,19 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, TypeHandle thOwner = NULL; + // Module * dbg_infoModule; + + // if (wcscmp(pInfoModule->GetDebugName(), L"test") != 0) { + // int refModuleTest = wcscmp(pReferencingModule->GetDebugName(), L"test"); + // int refModuleMain = wcscmp(pReferencingModule->GetDebugName(), L"mainv1"); + // dbg_infoModule = pInfoModule; + // } + // else if (wcscmp(pInfoModule->GetDebugName(), L"mainv1") != 0) { + // int refModuleTest = wcscmp(pReferencingModule->GetDebugName(), L"test"); + // int refModuleMain = wcscmp(pReferencingModule->GetDebugName(), L"mainv1"); + // dbg_infoModule = pReferencingModule; + // } + if ( methodFlags & ENCODE_METHOD_SIG_OwnerType ) { if (ppOwnerTypeSpecWithVars != NULL) @@ -879,7 +892,7 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, // RID rid; IfFailThrow(sig.GetData(&rid)); - + // MemberRef token is interpreted in the incorrect module if (methodFlags & ENCODE_METHOD_SIG_MemberRefToken) { if (thOwner.IsNull()) diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index 6debf62903c9..d134fa25532e 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -990,8 +990,13 @@ void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHO CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle); CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder); +#ifdef FEATURE_READYTORUN_COMPILER + GetCompileInfo()->EncodeMethod(pResolvedToken->tokenScope, handle, pSigBuilder, this, EncodeModuleHelper, + pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams); +#else GetCompileInfo()->EncodeMethod(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper, pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams); +#endif } // ====================================================================================== From 9501e85087a2337c1029413729feda300afcaf5a Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 20 Nov 2018 17:10:55 -0800 Subject: [PATCH 04/28] Change referencing module in R2R --- src/zap/zapimport.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index d134fa25532e..c50932383f82 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -988,15 +988,15 @@ void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHO CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams) { CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle); - CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); - referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder); #ifdef FEATURE_READYTORUN_COMPILER - GetCompileInfo()->EncodeMethod(pResolvedToken->tokenScope, handle, pSigBuilder, this, EncodeModuleHelper, - pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams); + CORINFO_MODULE_HANDLE referencingModule = pResolvedToken->tokenScope; #else + CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); +#endif + referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder); + GetCompileInfo()->EncodeMethod(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper, pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams); -#endif } // ====================================================================================== From 2b4078cd1b75d44f64e5821dedaac449568d2d05 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Mon, 26 Nov 2018 16:16:44 -0800 Subject: [PATCH 05/28] Pre-condition Check --- src/vm/ceeload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 3f3387c1ce60..b7577d0ad02f 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10338,7 +10338,7 @@ Module *Module::GetModuleFromIndexIfLoaded(DWORD ix) NOTHROW; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(HasNativeImage()); + PRECONDITION(HasNativeOrReadyToRunImage()); POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); } CONTRACT_END; From e18693513bb1f5b6a6061b4a360ba4eb33a147ef Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 27 Nov 2018 18:02:56 -0800 Subject: [PATCH 06/28] Virtual Method Module Resolution --- src/inc/corinfo.h | 1 + src/jit/importer.cpp | 4 +++- src/zap/zapimport.cpp | 8 ++++---- src/zap/zapimport.h | 4 ++-- src/zap/zapinfo.cpp | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index 68eec6b57e3e..023de34727ae 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -1571,6 +1571,7 @@ enum CORINFO_CALLINFO_FLAGS CORINFO_CALLINFO_SECURITYCHECKS = 0x0010, // Perform security checks. CORINFO_CALLINFO_LDFTN = 0x0020, // Resolving target of LDFTN CORINFO_CALLINFO_ATYPICAL_CALLSITE = 0x0040, // Atypical callsite that cannot be disassembled by delay loading helper + CORINFO_CALLINFO_DEVIRT_CALLSITE = 0x0080, }; enum CorInfoIsAccessAllowedResult diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 6062511ce18f..660ccabc0f4e 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -19906,7 +19906,9 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, // Look up the new call info. CORINFO_CALL_INFO derivedCallInfo; - eeGetCallInfo(&derivedResolvedToken, nullptr, addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), &derivedCallInfo); + eeGetCallInfo(&derivedResolvedToken, nullptr, + addVerifyFlag(combine(CORINFO_CALLINFO_ALLOWINSTPARAM, CORINFO_CALLINFO_DEVIRT_CALLSITE)), + &derivedCallInfo); // Update the call. call->gtCallMoreFlags &= ~GTF_CALL_M_VIRTSTUB_REL_INDIRECT; diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index c50932383f82..5428ff1389bd 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -985,11 +985,11 @@ void ZapImportTable::EncodeField(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_ } void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder, - CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams) + CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams, BOOL isDevirtualizedCall) { CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle); #ifdef FEATURE_READYTORUN_COMPILER - CORINFO_MODULE_HANDLE referencingModule = pResolvedToken->tokenScope; + CORINFO_MODULE_HANDLE referencingModule = isDevirtualizedCall ? GetJitInfo()->getClassModule(clsHandle) : pResolvedToken->tokenScope; #else CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); #endif @@ -1623,7 +1623,7 @@ ZapImport * ZapImportTable::GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolv return GetImportForSignature((PVOID)handle, &sigBuilder); } -ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken) +ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL isDevirtualizedCall) { SigBuilder sigBuilder; @@ -1641,7 +1641,7 @@ ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, } else { - EncodeMethod(ENCODE_METHOD_ENTRY, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken); + EncodeMethod(ENCODE_METHOD_ENTRY, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken, false, isDevirtualizedCall); } return GetImportForSignature((PVOID)handle, &sigBuilder); diff --git a/src/zap/zapimport.h b/src/zap/zapimport.h index 058cb0b1459f..8c9ac3236274 100644 --- a/src/zap/zapimport.h +++ b/src/zap/zapimport.h @@ -338,7 +338,7 @@ class ZapImportTable CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); void EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder, CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL, - BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); + BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE, BOOL isDevirtualizedCall = FALSE); // Encode module if the reference is within current version bubble. If not, return a suitable module within current version bubble. CORINFO_MODULE_HANDLE TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder); @@ -426,7 +426,7 @@ class ZapImportTable ZapImport * GetCheckFieldOffsetImport(CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, DWORD offset); ZapImport * GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolvedToken); - ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken); + ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL isDevirtualizedCall); ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle); ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE delegateType = NULL); diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 3ce3e6d845bc..8ab381f990b3 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -2198,7 +2198,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, } else { - pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken); + BOOL isDevirtualizedCall = (flags & CORINFO_CALLINFO_DEVIRT_CALLSITE) != 0; + pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken, isDevirtualizedCall); } // READYTORUN: FUTURE: Direct calls if possible From 77bd515dca286601c0f1d1102c2ac7bd7ed7c0d3 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 29 Nov 2018 15:55:59 -0800 Subject: [PATCH 07/28] Remove Workarounds and add conditional import loading --- src/inc/corinfo.h | 1 - src/jit/importer.cpp | 2 +- src/vm/ceeload.cpp | 52 ++++++++++++++++++++----------------------- src/vm/ceeload.h | 1 + src/vm/zapsig.cpp | 6 ++--- src/zap/zapimport.cpp | 10 +++------ src/zap/zapimport.h | 4 ++-- src/zap/zapinfo.cpp | 3 +-- 8 files changed, 35 insertions(+), 44 deletions(-) diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index 023de34727ae..68eec6b57e3e 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -1571,7 +1571,6 @@ enum CORINFO_CALLINFO_FLAGS CORINFO_CALLINFO_SECURITYCHECKS = 0x0010, // Perform security checks. CORINFO_CALLINFO_LDFTN = 0x0020, // Resolving target of LDFTN CORINFO_CALLINFO_ATYPICAL_CALLSITE = 0x0040, // Atypical callsite that cannot be disassembled by delay loading helper - CORINFO_CALLINFO_DEVIRT_CALLSITE = 0x0080, }; enum CorInfoIsAccessAllowedResult diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 660ccabc0f4e..6a359788b2d9 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -19907,7 +19907,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, // Look up the new call info. CORINFO_CALL_INFO derivedCallInfo; eeGetCallInfo(&derivedResolvedToken, nullptr, - addVerifyFlag(combine(CORINFO_CALLINFO_ALLOWINSTPARAM, CORINFO_CALLINFO_DEVIRT_CALLSITE)), + addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), &derivedCallInfo); // Update the call. diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index b7577d0ad02f..c4ad1be0608f 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10280,34 +10280,6 @@ Module *Module::GetModuleFromIndex(DWORD ix) if (HasNativeOrReadyToRunImage()) { RETURN ZapSig::DecodeModuleFromIndex(this, ix); - // // CORCOMPILE_IMPORT_TABLE_ENTRY *p; - // // if (IsReadyToRun()) - // // { - // // //PRECONDITION(GetNativeImage()->CheckReadyToRunImportFromIndex(ix)); - // // p = GetNativeOrReadyToRunImage()->GetReadyToRunImportFromIndex(ix); - // // } - // // else - // // { - // // PRECONDITION(GetNativeImage()->CheckNativeImportFromIndex(ix)); - // // p = GetNativeImage()->GetNativeImportFromIndex(ix); - // // } - - // // RETURN ZapSig::DecodeModuleFromIndexes(this, p->wAssemblyRid, p->wModuleRid); - // CORCOMPILE_IMPORT_TABLE_ENTRY *p; - // if (IsReadyToRun()) - // { - // //PRECONDITION(GetNativeImage()->CheckReadyToRunImportFromIndex(ix)); - // //GetReadyToRunInfo()->GetReadyToRunImportFromIndex(ix); - // RETURN ZapSig::DecodeModuleFromIndexes(this, ix, 0); - - // } - // else - // { - // PRECONDITION(GetNativeImage()->CheckNativeImportFromIndex(ix)); - // p = GetNativeImage()->GetNativeImportFromIndex(ix); - // } - - // RETURN ZapSig::DecodeModuleFromIndexes(this, p->wAssemblyRid, p->wModuleRid); } else { @@ -10393,6 +10365,30 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) } } +IMDInternalImport *Module::GetNativeAssemblyImportIfLoaded() +{ + CONTRACT(IMDInternalImport *) + { + INSTANCE_CHECK; + GC_NOTRIGGER; + NOTHROW; + FORBID_FAULT; + MODE_ANY; + PRECONDITION(HasNativeOrReadyToRunImage()); + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } + + CONTRACT_END; + // Check if Image is even R2R? + if (GetFile()->IsILImageReadyToRun()) + { + RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(false); + } + else + { + RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(false); + } +} /*static*/ void Module::RestoreMethodTablePointerRaw(MethodTable ** ppMT, diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index 98b5f05371c3..17dbc9238c19 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -2826,6 +2826,7 @@ class Module BYTE *GetNativeFixupBlobData(RVA fixup); IMDInternalImport *GetNativeAssemblyImport(BOOL loadAllowed = TRUE); + IMDInternalImport *GetNativeAssemblyImportIfLoaded(); BOOL FixupNativeEntry(CORCOMPILE_IMPORT_SECTION * pSection, SIZE_T fixupIndex, SIZE_T *fixup); diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 4b3025c61c25..46d36768556d 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -702,7 +702,7 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, { index -= fromModule->GetAssemblyRefMax(); tkAssemblyRef = RidToToken(index, mdtAssemblyRef); - IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImport(FALSE); + IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImportIfLoaded(); if (pMDImportOverride != NULL) { CHAR szFullName[MAX_CLASS_NAME + 1]; @@ -1140,7 +1140,7 @@ BOOL ZapSig::EncodeMethod( TypeHandle ownerType; #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) + if (IsReadyToRunCompilation() && !pMethod->GetModule()->IsInCurrentVersionBubble()) { if (pResolvedToken == NULL) { @@ -1199,7 +1199,7 @@ BOOL ZapSig::EncodeMethod( } #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) + if (IsReadyToRunCompilation() && !pMethod->GetModule()->IsInCurrentVersionBubble()) { if (pConstrainedResolvedToken != NULL) { diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index 5428ff1389bd..26815a6987be 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -985,14 +985,10 @@ void ZapImportTable::EncodeField(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_ } void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder, - CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams, BOOL isDevirtualizedCall) + CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams) { CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle); -#ifdef FEATURE_READYTORUN_COMPILER - CORINFO_MODULE_HANDLE referencingModule = isDevirtualizedCall ? GetJitInfo()->getClassModule(clsHandle) : pResolvedToken->tokenScope; -#else CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); -#endif referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder); GetCompileInfo()->EncodeMethod(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper, @@ -1623,7 +1619,7 @@ ZapImport * ZapImportTable::GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolv return GetImportForSignature((PVOID)handle, &sigBuilder); } -ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL isDevirtualizedCall) +ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken) { SigBuilder sigBuilder; @@ -1641,7 +1637,7 @@ ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, } else { - EncodeMethod(ENCODE_METHOD_ENTRY, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken, false, isDevirtualizedCall); + EncodeMethod(ENCODE_METHOD_ENTRY, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken, false); } return GetImportForSignature((PVOID)handle, &sigBuilder); diff --git a/src/zap/zapimport.h b/src/zap/zapimport.h index 8c9ac3236274..058cb0b1459f 100644 --- a/src/zap/zapimport.h +++ b/src/zap/zapimport.h @@ -338,7 +338,7 @@ class ZapImportTable CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); void EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder, CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL, - BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE, BOOL isDevirtualizedCall = FALSE); + BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); // Encode module if the reference is within current version bubble. If not, return a suitable module within current version bubble. CORINFO_MODULE_HANDLE TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder); @@ -426,7 +426,7 @@ class ZapImportTable ZapImport * GetCheckFieldOffsetImport(CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, DWORD offset); ZapImport * GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolvedToken); - ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL isDevirtualizedCall); + ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken); ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle); ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE delegateType = NULL); diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 8ab381f990b3..3ce3e6d845bc 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -2198,8 +2198,7 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, } else { - BOOL isDevirtualizedCall = (flags & CORINFO_CALLINFO_DEVIRT_CALLSITE) != 0; - pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken, isDevirtualizedCall); + pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken); } // READYTORUN: FUTURE: Direct calls if possible From 0a493d33261ae2f0012868119f388a7111190d83 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 5 Dec 2018 17:31:22 -0800 Subject: [PATCH 08/28] Add signature kind module override --- src/vm/genericdict.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vm/genericdict.cpp b/src/vm/genericdict.cpp index 5fad30f4b81d..906f5c57fad2 100644 --- a/src/vm/genericdict.cpp +++ b/src/vm/genericdict.cpp @@ -686,8 +686,20 @@ Dictionary::PopulateEntry( pBlob = p.GetPtr(); } - CORCOMPILE_FIXUP_BLOB_KIND signatureKind = (CORCOMPILE_FIXUP_BLOB_KIND)CorSigUncompressData(pBlob); - switch (signatureKind) + BYTE signatureKind = *pBlob++; + if (signatureKind & ENCODE_MODULE_OVERRIDE) + { + DWORD moduleIndex = CorSigUncompressData(pBlob); + Module * pSignatureModule = pModule->GetModuleFromIndex(moduleIndex); + if (pInfoModule == pModule) + { + pInfoModule = pSignatureModule; + } + _ASSERTE(pInfoModule == pSignatureModule); + signatureKind &= ~ENCODE_MODULE_OVERRIDE; + } + + switch ((CORCOMPILE_FIXUP_BLOB_KIND) signatureKind) { case ENCODE_DECLARINGTYPE_HANDLE: kind = DeclaringTypeHandleSlot; break; case ENCODE_TYPE_HANDLE: kind = TypeHandleSlot; break; From 52b3b14d8321a8e340737cd88b204038aa6d5f89 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 13 Dec 2018 22:46:30 -0800 Subject: [PATCH 09/28] Add ELEMENT_TYPE_MODULE_ZAPSIG --- src/vm/zapsig.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 46d36768556d..33cccb9fcf64 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -1325,6 +1325,14 @@ BOOL ZapSig::EncodeMethod( if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pTypeSpec != NULL) { _ASSERTE(pResolvedToken->cbTypeSpec > 0); + + if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope) + { + pSigBuilder->AppendElementType((CorElementType)ELEMENT_TYPE_MODULE_ZAPSIG); + DWORD index = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope); + pSigBuilder->AppendData(index); + } + pSigBuilder->AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); } else From 9d5c7f1592de852de16ba9d3d1b8a567c75edd0f Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 18 Dec 2018 18:15:50 -0800 Subject: [PATCH 10/28] Add switch to enable large version bubble --- src/inc/corcompile.h | 10 ++++++++++ src/inc/coregen.h | 1 + src/tools/crossgen/crossgen.cpp | 8 ++++++++ src/vm/ceeload.cpp | 4 ++-- src/vm/jitinterface.cpp | 4 ++-- src/vm/vars.hpp | 1 + src/vm/zapsig.cpp | 14 -------------- src/zap/zapper.cpp | 2 ++ 8 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h index e04da79365c7..ff8ebe5ade91 100644 --- a/src/inc/corcompile.h +++ b/src/inc/corcompile.h @@ -1811,6 +1811,7 @@ extern bool g_fNGenWinMDResilient; #ifdef FEATURE_READYTORUN_COMPILER extern bool g_fReadyToRunCompilation; +extern bool g_fLargeVersionBubble; #endif inline bool IsReadyToRunCompilation() @@ -1822,4 +1823,13 @@ inline bool IsReadyToRunCompilation() #endif } +inline bool IsLargeVersionBubbleEnabled() +{ +#ifdef FEATURE_READYTORUN_COMPILER + return g_fLargeVersionBubble; +#else + return false; +#endif +} + #endif /* COR_COMPILE_H_ */ diff --git a/src/inc/coregen.h b/src/inc/coregen.h index f8d07a57ad8b..8ef075a07a04 100644 --- a/src/inc/coregen.h +++ b/src/inc/coregen.h @@ -13,6 +13,7 @@ #define NGENWORKER_FLAGS_TUNING 0x0001 #define NGENWORKER_FLAGS_MISSINGDEPENDENCIESOK 0x0004 +#define NGENWORKER_FLAGS_LARGEVERSIONBUBBLE 0x0008 #define NGENWORKER_FLAGS_WINMD_RESILIENT 0x1000 #define NGENWORKER_FLAGS_READYTORUN 0x2000 diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 275d9acc5e30..2f61a15c81e9 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -155,6 +155,9 @@ void PrintUsageHelper() #ifdef FEATURE_READYTORUN_COMPILER W(" /ReadyToRun - Generate images resilient to the runtime and\n") W(" dependency versions\n") + W(" /LargeVersionBubble - Generate image with a version bubble including all\n") + W(" input assemblies\n") + #endif #ifdef FEATURE_WINMD_RESILIENT W(" WinMD Parameters\n") @@ -428,6 +431,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) LPCWSTR pwzOutputFilename = NULL; LPCWSTR pwzPublicKeys = nullptr; bool fExplicitReadyToRunSwitch = false; + bool fLargeVersionBubbleSwitch = false; #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) LPCWSTR pwszCLRJITPath = nullptr; @@ -526,6 +530,10 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) { dwFlags &= ~NGENWORKER_FLAGS_READYTORUN; } + else if (MatchParameter(*argv, W("LargeVersionBubble"))) + { + dwFlags |= NGENWORKER_FLAGS_LARGEVERSIONBUBBLE; + } #endif else if (MatchParameter(*argv, W("NoMetaData"))) { diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index c4ad1be0608f..2a10a3f16c83 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -3579,7 +3579,7 @@ BOOL Module::IsWindowsRuntimeModule() return IsAfContentType_WindowsRuntime(dwFlags); } -// Update this? + BOOL Module::IsInCurrentVersionBubble() { LIMITED_METHOD_CONTRACT; @@ -3594,7 +3594,7 @@ BOOL Module::IsInCurrentVersionBubble() return TRUE; if (IsReadyToRunCompilation()) - return TRUE; + return IsLargeVersionBubbleEnabled(); #ifdef FEATURE_COMINTEROP if (g_fNGenWinMDResilient) diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 3f86250564f2..2b6330ea19dc 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -684,10 +684,10 @@ bool IsInSameVersionBubble(Assembly * current, Assembly * target) // trivial case: current and target are identical // DO NOT change this without reading the notice above - //if (current == target) + if (current == target) return true; - // return false; + return IsLargeVersionBubbleEnabled(); } // Returns true if the assemblies defining current and target are in the same version bubble diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp index a062f0b3fc69..1b5133cbbca3 100644 --- a/src/vm/vars.hpp +++ b/src/vm/vars.hpp @@ -818,6 +818,7 @@ extern CEECompileInfo *g_pCEECompileInfo; #ifdef FEATURE_READYTORUN_COMPILER extern bool g_fReadyToRunCompilation; +extern bool g_fLargeVersionBubble; #endif // Returns true if this is NGen compilation process. diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 33cccb9fcf64..4b003495c451 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -846,19 +846,6 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, TypeHandle thOwner = NULL; - // Module * dbg_infoModule; - - // if (wcscmp(pInfoModule->GetDebugName(), L"test") != 0) { - // int refModuleTest = wcscmp(pReferencingModule->GetDebugName(), L"test"); - // int refModuleMain = wcscmp(pReferencingModule->GetDebugName(), L"mainv1"); - // dbg_infoModule = pInfoModule; - // } - // else if (wcscmp(pInfoModule->GetDebugName(), L"mainv1") != 0) { - // int refModuleTest = wcscmp(pReferencingModule->GetDebugName(), L"test"); - // int refModuleMain = wcscmp(pReferencingModule->GetDebugName(), L"mainv1"); - // dbg_infoModule = pReferencingModule; - // } - if ( methodFlags & ENCODE_METHOD_SIG_OwnerType ) { if (ppOwnerTypeSpecWithVars != NULL) @@ -892,7 +879,6 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, // RID rid; IfFailThrow(sig.GetData(&rid)); - // MemberRef token is interpreted in the incorrect module if (methodFlags & ENCODE_METHOD_SIG_MemberRefToken) { if (thOwner.IsNull()) diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index d43ce43de9f7..5fbe92c20853 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -21,6 +21,7 @@ bool g_fNGenWinMDResilient; #ifdef FEATURE_READYTORUN_COMPILER bool g_fReadyToRunCompilation; +bool g_fLargeVersionBubble; #endif static bool s_fNGenNoMetaData; @@ -110,6 +111,7 @@ STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembl #ifdef FEATURE_READYTORUN_COMPILER g_fReadyToRunCompilation = !!(dwFlags & NGENWORKER_FLAGS_READYTORUN); + g_fLargeVersionBubble = !!(dwFlags & NGENWORKER_FLAGS_LARGEVERSIONBUBBLE); #endif if (pLogger != NULL) From dfde9699362d67b897612f971b5d8ff97fed1c5e Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Fri, 28 Dec 2018 11:18:36 -0800 Subject: [PATCH 11/28] Cleanup --- src/jit/importer.cpp | 4 +--- src/tools/crossgen/crossgen.cpp | 17 +++-------------- src/vm/ceeload.h | 1 - src/vm/readytoruninfo.cpp | 1 - src/vm/readytoruninfo.h | 1 - src/vm/zapsig.cpp | 8 ++++---- src/zap/zapimage.cpp | 1 - src/zap/zapimport.cpp | 3 --- src/zap/zapinfo.cpp | 6 ------ src/zap/zapper.cpp | 2 +- 10 files changed, 9 insertions(+), 35 deletions(-) diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 6a359788b2d9..6062511ce18f 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -19906,9 +19906,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, // Look up the new call info. CORINFO_CALL_INFO derivedCallInfo; - eeGetCallInfo(&derivedResolvedToken, nullptr, - addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), - &derivedCallInfo); + eeGetCallInfo(&derivedResolvedToken, nullptr, addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), &derivedCallInfo); // Update the call. call->gtCallMoreFlags &= ~GTF_CALL_M_VIRTSTUB_REL_INDIRECT; diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 2f61a15c81e9..a37655d640fb 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -34,7 +34,7 @@ enum ReturnValues #define NumItems(s) (sizeof(s) / sizeof(s[0])) STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzPlatformWinmdPaths, LPCWSTR pwzDiasymreaderPath); -STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, LPCWSTR pwzVersionBubbleAssemblyPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr); +STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr); void SetSvcLogger(ICorSvcLogger *pCorSvcLogger); void SetMscorlibPath(LPCWSTR wzSystemDirectory); @@ -422,8 +422,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) LPCWSTR pwzAppNiPaths = nullptr; LPCWSTR pwzPlatformAssembliesPaths = nullptr; LPCWSTR pwzPlatformWinmdPaths = nullptr; - // TODO Add Variable Num of cli arguments - LPCWSTR pwzVersionBubbleAssemblyPaths = nullptr; StackSString wzDirectoryToStorePDB; bool fCreatePDB = false; bool fGeneratePDBLinesInfo = false; @@ -474,7 +472,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) // By default, Crossgen will generate readytorun images unless /FragileNonVersionable switch is specified dwFlags |= NGENWORKER_FLAGS_READYTORUN; - while (argc > 0) { // Command-line parsing @@ -533,6 +530,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) else if (MatchParameter(*argv, W("LargeVersionBubble"))) { dwFlags |= NGENWORKER_FLAGS_LARGEVERSIONBUBBLE; + fLargeVersionBubbleSwitch = true; } #endif else if (MatchParameter(*argv, W("NoMetaData"))) @@ -599,14 +597,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) { pwzPlatformAssembliesPaths = argv[1]; - // skip path list - argv++; - argc--; - } - else if (MatchParameter(*argv, W("Version_Bubble_Assembly_Paths")) && (argc > 1)) - { - pwzVersionBubbleAssemblyPaths = argv[1]; - // skip path list argv++; argc--; @@ -933,8 +923,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) pwzPlatformResourceRoots, pwzAppPaths, pwzOutputFilename, - pwzPlatformWinmdPaths, - pwzVersionBubbleAssemblyPaths + pwzPlatformWinmdPaths #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) , NULL, // ICorSvcLogger diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index 17dbc9238c19..4302836642fb 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -2393,7 +2393,6 @@ class Module CrstHolder ch(this->GetLookupTableCrst()); m_pMemberRefToDescHashTable->Insert(token, value); } - // This call void StoreMemberRef(mdMemberRef token, MethodDesc *value) { WRAPPER_NO_CONTRACT; diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index 6aef45ac8df8..1f0c88db9e94 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -455,7 +455,6 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker STANDARD_VM_CONTRACT; PEFile * pFile = pModule->GetFile(); - // ? if (!IsReadyToRunEnabled()) { // Log message is ignored in this case. diff --git a/src/vm/readytoruninfo.h b/src/vm/readytoruninfo.h index ff55b8de8503..93bed74aec6a 100644 --- a/src/vm/readytoruninfo.h +++ b/src/vm/readytoruninfo.h @@ -43,7 +43,6 @@ class ReadyToRunInfo NativeFormat::NativeArray m_methodDefEntryPoints; NativeFormat::NativeHashtable m_instMethodEntryPoints; NativeFormat::NativeHashtable m_availableTypesHashtable; - // TODO Should this be a hash table? NativeFormat::NativeHashtable m_pMetaDataHashtable; Crst m_Crst; diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 4b003495c451..88894835ff0e 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -781,9 +781,9 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, TypeHandle ZapSig::DecodeType(Module *pEncodeModuleContext, - Module *pInfoModule, - PCCOR_SIGNATURE pBuffer, - ClassLoadLevel level) + Module *pInfoModule, + PCCOR_SIGNATURE pBuffer, + ClassLoadLevel level) { CONTRACTL { @@ -879,6 +879,7 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, // RID rid; IfFailThrow(sig.GetData(&rid)); + if (methodFlags & ENCODE_METHOD_SIG_MemberRefToken) { if (thOwner.IsNull()) @@ -1201,7 +1202,6 @@ BOOL ZapSig::EncodeMethod( // GetSvcLogger()->Printf(W("ReadyToRun: Method reference outside of current version bubble cannot be encoded\n")); ThrowHR(E_FAIL); } - //_ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); methodToken = pResolvedToken->token; diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 90be1b2b47db..3c0009d17486 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1833,7 +1833,6 @@ void ZapImage::Compile() OutputInliningTableForReadyToRun(); OutputProfileDataForReadyToRun(); OutputManifestMetadataForReadyToRun(); - } else #endif diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index 26815a6987be..ab27c14fab2d 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -941,7 +941,6 @@ ZapImport * ZapImportTable::GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE CORINFO_MODULE_HANDLE ZapImportTable::TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder) { - // Use def tokens and module references? if (!GetCompileInfo()->IsInCurrentVersionBubble(module)) module = GetImage()->GetModuleHandle(); @@ -990,7 +989,6 @@ void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHO CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle); CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle); referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder); - GetCompileInfo()->EncodeMethod(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper, pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams); } @@ -1847,7 +1845,6 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind sigBuilder.AppendData(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), handle, &sigBuilder, this, EncodeModuleHelper); - // CHANGE IT HERE pImport->SetBlob(GetBlob(&sigBuilder)); } diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 3ce3e6d845bc..3d0255903003 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -1425,12 +1425,6 @@ CORINFO_MODULE_HANDLE ZapInfo::embedModuleHandle(CORINFO_MODULE_HANDLE handle, { _ASSERTE(ppIndirection != NULL); - //if (IsReadyToRunCompilation()) - //{ - // _ASSERTE(!"embedModuleHandle"); - // ThrowHR(E_NOTIMPL); - //} - BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedModuleHandle(handle); if (fHardbound) { diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 5fbe92c20853..f4ddb9201178 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -33,7 +33,7 @@ static bool s_fNGenNoMetaData; // Zapper Object instead of creating one on your own. -STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, LPCWSTR pwzVersionBubbleAssemblyPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr) +STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr) { HRESULT hr = S_OK; From 2243d12ffe103f327433a3cf815037f8b95b005b Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 1 Jan 2019 08:58:49 -0800 Subject: [PATCH 12/28] Change Native header check --- src/utilcode/pedecoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 8db0c9fdd999..2bc261663729 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2479,13 +2479,13 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const CONTRACT(PTR_CVOID) { INSTANCE_CHECK; - // Check R2R - //PRECONDITION(CheckNativeHeader() || true); + PRECONDITION(HasReadyToRunHeader() || CheckNativeHeader()); POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); // TBD - may not store metadata for IJW NOTHROW; GC_NOTRIGGER; } CONTRACT_END; + IMAGE_DATA_DIRECTORY *pDir; if (HasReadyToRunHeader()) { From 772fb76db2645cfa3f5edca7dfbec926d4f9b768 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Mon, 7 Jan 2019 19:36:11 -0800 Subject: [PATCH 13/28] Add large version bubble test --- src/jit/importer.cpp | 1 - tests/runtest.cmd | 88 ++++++++++--------- tests/runtest.py | 6 ++ tests/src/CLRTest.CrossGen.targets | 5 +- .../readytorun/tests/versionbubbles/helper.cs | 13 +++ .../tests/versionbubbles/helper.csproj | 33 +++++++ .../tests/versionbubbles/versionbubbles.cs | 46 ++++++++++ .../versionbubbles/versionbubbles.csproj | 59 +++++++++++++ 8 files changed, 207 insertions(+), 44 deletions(-) create mode 100644 tests/src/readytorun/tests/versionbubbles/helper.cs create mode 100644 tests/src/readytorun/tests/versionbubbles/helper.csproj create mode 100644 tests/src/readytorun/tests/versionbubbles/versionbubbles.cs create mode 100644 tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 6062511ce18f..047085449143 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -19186,7 +19186,6 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, inlineResult.NoteFatal(InlineObservation::CALLSITE_IS_CALL_TO_HELPER); return; } - /* Ignore indirect calls */ if (call->gtCallType == CT_INDIRECT) { diff --git a/tests/runtest.cmd b/tests/runtest.cmd index 7b458064dfc8..ba302b5d4e40 100644 --- a/tests/runtest.cmd +++ b/tests/runtest.cmd @@ -59,50 +59,52 @@ if /i "%1" == "-h" goto Usage if /i "%1" == "/help" goto Usage if /i "%1" == "-help" goto Usage -if /i "%1" == "x64" (set __BuildArch=x64&shift&goto Arg_Loop) -if /i "%1" == "x86" (set __BuildArch=x86&shift&goto Arg_Loop) -if /i "%1" == "arm" (set __BuildArch=arm&shift&goto Arg_Loop) -if /i "%1" == "arm64" (set __BuildArch=arm64&shift&goto Arg_Loop) - -if /i "%1" == "debug" (set __BuildType=Debug&shift&goto Arg_Loop) -if /i "%1" == "release" (set __BuildType=Release&shift&goto Arg_Loop) -if /i "%1" == "checked" (set __BuildType=Checked&shift&goto Arg_Loop) - -if /i "%1" == "vs2015" (set __VSVersion=%1&shift&goto Arg_Loop) -if /i "%1" == "vs2017" (set __VSVersion=%1&shift&goto Arg_Loop) - -if /i "%1" == "TestEnv" (set __TestEnv=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "AgainstPackages" (set __AgainstPackages=1&shift&goto Arg_Loop) -if /i "%1" == "sequential" (set __Sequential=1&shift&goto Arg_Loop) -if /i "%1" == "crossgen" (set __DoCrossgen=1&shift&goto Arg_Loop) -if /i "%1" == "crossgenaltjit" (set __DoCrossgen=1&set __CrossgenAltJit=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "longgc" (set __LongGCTests=1&shift&goto Arg_Loop) -if /i "%1" == "gcsimulator" (set __GCSimulatorTests=1&shift&goto Arg_Loop) -if /i "%1" == "jitstress" (set COMPlus_JitStress=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "jitstressregs" (set COMPlus_JitStressRegs=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "jitminopts" (set COMPlus_JITMinOpts=1&shift&goto Arg_Loop) -if /i "%1" == "jitforcerelocs" (set COMPlus_ForceRelocs=1&shift&goto Arg_Loop) -if /i "%1" == "jitdisasm" (set __JitDisasm=1&shift&goto Arg_Loop) -if /i "%1" == "ilasmroundtrip" (set __IlasmRoundTrip=1&shift&goto Arg_Loop) -if /i "%1" == "GenerateLayoutOnly" (set __GenerateLayoutOnly=1&shift&goto Arg_Loop) -if /i "%1" == "skipgeneratelayout" (set __SkipGenerateLayout=1&shift&goto Arg_Loop) -if /i "%1" == "buildxunitwrappers" (set __BuildXunitWrappers=1&shift&goto Arg_Loop) -if /i "%1" == "printlastresultsonly" (set __PrintLastResultsOnly=1&shift&goto Arg_Loop) -if /i "%1" == "PerfTests" (set __PerfTests=true&shift&goto Arg_Loop) -if /i "%1" == "CoreFXTests" (set __CoreFXTests=true&shift&goto Arg_Loop) -if /i "%1" == "CoreFXTestsAll" (set __CoreFXTests=true&set __CoreFXTestsRunAllAvailable=true&shift&goto Arg_Loop) -if /i "%1" == "CoreFXTestList" (set __CoreFXTests=true&set __CoreFXTestList=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "runcrossgentests" (set RunCrossGen=true&shift&goto Arg_Loop) -if /i "%1" == "link" (set DoLink=true&set ILLINK=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "x64" (set __BuildArch=x64&shift&goto Arg_Loop) +if /i "%1" == "x86" (set __BuildArch=x86&shift&goto Arg_Loop) +if /i "%1" == "arm" (set __BuildArch=arm&shift&goto Arg_Loop) +if /i "%1" == "arm64" (set __BuildArch=arm64&shift&goto Arg_Loop) + +if /i "%1" == "debug" (set __BuildType=Debug&shift&goto Arg_Loop) +if /i "%1" == "release" (set __BuildType=Release&shift&goto Arg_Loop) +if /i "%1" == "checked" (set __BuildType=Checked&shift&goto Arg_Loop) + +if /i "%1" == "vs2015" (set __VSVersion=%1&shift&goto Arg_Loop) +if /i "%1" == "vs2017" (set __VSVersion=%1&shift&goto Arg_Loop) + +if /i "%1" == "TestEnv" (set __TestEnv=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "AgainstPackages" (set __AgainstPackages=1&shift&goto Arg_Loop) +if /i "%1" == "sequential" (set __Sequential=1&shift&goto Arg_Loop) +if /i "%1" == "crossgen" (set __DoCrossgen=1&shift&goto Arg_Loop) +if /i "%1" == "crossgenaltjit" (set __DoCrossgen=1&set __CrossgenAltJit=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "longgc" (set __LongGCTests=1&shift&goto Arg_Loop) +if /i "%1" == "gcsimulator" (set __GCSimulatorTests=1&shift&goto Arg_Loop) +if /i "%1" == "jitstress" (set COMPlus_JitStress=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "jitstressregs" (set COMPlus_JitStressRegs=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "jitminopts" (set COMPlus_JITMinOpts=1&shift&goto Arg_Loop) +if /i "%1" == "jitforcerelocs" (set COMPlus_ForceRelocs=1&shift&goto Arg_Loop) +if /i "%1" == "jitdisasm" (set __JitDisasm=1&shift&goto Arg_Loop) +if /i "%1" == "ilasmroundtrip" (set __IlasmRoundTrip=1&shift&goto Arg_Loop) +if /i "%1" == "GenerateLayoutOnly" (set __GenerateLayoutOnly=1&shift&goto Arg_Loop) +if /i "%1" == "skipgeneratelayout" (set __SkipGenerateLayout=1&shift&goto Arg_Loop) +if /i "%1" == "buildxunitwrappers" (set __BuildXunitWrappers=1&shift&goto Arg_Loop) +if /i "%1" == "printlastresultsonly" (set __PrintLastResultsOnly=1&shift&goto Arg_Loop) +if /i "%1" == "PerfTests" (set __PerfTests=true&shift&goto Arg_Loop) +if /i "%1" == "CoreFXTests" (set __CoreFXTests=true&shift&goto Arg_Loop) +if /i "%1" == "CoreFXTestsAll" (set __CoreFXTests=true&set __CoreFXTestsRunAllAvailable=true&shift&goto Arg_Loop) +if /i "%1" == "CoreFXTestList" (set __CoreFXTests=true&set __CoreFXTestList=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "runcrossgentests" (set RunCrossGen=true&shift&goto Arg_Loop) +REM This test feature is currently intentionally undocumented +if /i "%1" == "runlargeversionbubblecrossgentests" (set RunCrossGen=true&set CrossgenLargeVersionBubble=true&shift&goto Arg_Loop) +if /i "%1" == "link" (set DoLink=true&set ILLINK=%2&shift&shift&goto Arg_Loop) REM tieredcompilation is on by default now, but setting this environment variable is harmless and I didn't want to break any automation that might be using it just yet -if /i "%1" == "tieredcompilation" (set COMPLUS_TieredCompilation=1&shift&goto Arg_Loop) -if /i "%1" == "gcname" (set COMPlus_GCName=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "timeout" (set __TestTimeout=%2&shift&shift&goto Arg_Loop) -if /i "%1" == "altjitarch" (set __AltJitArch=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "tieredcompilation" (set COMPLUS_TieredCompilation=1&shift&goto Arg_Loop) +if /i "%1" == "gcname" (set COMPlus_GCName=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "timeout" (set __TestTimeout=%2&shift&shift&goto Arg_Loop) +if /i "%1" == "altjitarch" (set __AltJitArch=%2&shift&shift&goto Arg_Loop) REM change it to COMPlus_GCStress when we stop using xunit harness -if /i "%1" == "gcstresslevel" (set COMPlus_GCStress=%2&set __TestTimeout=1800000&shift&shift&goto Arg_Loop) -if /i "%1" == "collectdumps" (set __CollectDumps=true&shift&goto Arg_Loop) +if /i "%1" == "gcstresslevel" (set COMPlus_GCStress=%2&set __TestTimeout=1800000&shift&shift&goto Arg_Loop) +if /i "%1" == "collectdumps" (set __CollectDumps=true&shift&goto Arg_Loop) if /i not "%1" == "msbuildargs" goto SkipMsbuildArgs :: All the rest of the args will be collected and passed directly to msbuild. @@ -205,6 +207,10 @@ if defined __DoCrossgen ( set __RuntestPyArgs=%__RuntestPyArgs% --precompile_core_root ) +if defined CrossgenLargeVersionBubble ( + set __RuntestPyArgs=%__RuntestPyArgs% --large_version_bubble +) + if defined __PrintLastResultsOnly ( set __RuntestPyArgs=%__RuntestPyArgs% --analyze_results_only ) diff --git a/tests/runtest.py b/tests/runtest.py index dee7c3a9344f..b8592345d483 100755 --- a/tests/runtest.py +++ b/tests/runtest.py @@ -118,6 +118,7 @@ parser.add_argument("--jitdisasm", dest="jitdisasm", action="store_true", default=False) parser.add_argument("--ilasmroundtrip", dest="ilasmroundtrip", action="store_true", default=False) parser.add_argument("--run_crossgen_tests", dest="run_crossgen_tests", action="store_true", default=False) +parser.add_argument("--large_version_bubble", dest="large_version_bubble", action="store_true", default=False) parser.add_argument("--precompile_core_root", dest="precompile_core_root", action="store_true", default=False) parser.add_argument("--sequential", dest="sequential", action="store_true", default=False) @@ -761,6 +762,10 @@ def run_tests(host_os, print("Running tests R2R") os.environ["RunCrossGen"] = "true" + if large_version_bubble: + print("Large Version Bubble enabled") + os.environ["LargeVersionBubble"] = "true" + if gc_stress: print("Running GCStress, extending timeout to 120 minutes.") os.environ["__TestTimeout"] = str(120*60*1000) # 1,800,000 ms @@ -2047,6 +2052,7 @@ def do_setup(host_os, is_ilasm=unprocessed_args.ilasmroundtrip, run_sequential=unprocessed_args.sequential, run_crossgen_tests=unprocessed_args.run_crossgen_tests, + large_version_bubble=unprocessed_args.large_version_bubble, test_env=test_env) ################################################################################ diff --git a/tests/src/CLRTest.CrossGen.targets b/tests/src/CLRTest.CrossGen.targets index 7dddfa2c365e..9dc441f63694 100644 --- a/tests/src/CLRTest.CrossGen.targets +++ b/tests/src/CLRTest.CrossGen.targets @@ -75,6 +75,7 @@ fi REM CrossGen Script if defined RunCrossGen ( + if defined LargeVersionBubble ( set OptionalArguments=!OptionalArguments! /largeversionbubble) set COMPlus_ZapRequire=$(ZapRequire) set COMPlus_ZapRequireList=$(MSBuildProjectName) if not exist "$(MSBuildProjectName).org" ( @@ -84,8 +85,8 @@ if defined RunCrossGen ( mkdir IL copy $(MSBuildProjectName).exe IL\$(MSBuildProjectName).exe ren $(MSBuildProjectName).exe $(MSBuildProjectName).org - echo "%_DebuggerFullPath% %CORE_ROOT%\crossgen.exe" /Platform_Assemblies_Paths %CORE_ROOT%%3B%25cd%25\IL%3B%25cd%25 /in $(MSBuildProjectName).org /out $(MSBuildProjectName).exe - %_DebuggerFullPath% "%CORE_ROOT%\crossgen.exe" /Platform_Assemblies_Paths %CORE_ROOT%%3B%25cd%25\IL%3B%25cd%25 /in $(MSBuildProjectName).org /out $(MSBuildProjectName).exe + echo "%_DebuggerFullPath% %CORE_ROOT%\crossgen.exe" !OptionalArguments! /Platform_Assemblies_Paths %CORE_ROOT%%3B%25cd%25\IL%3B%25cd%25 /in $(MSBuildProjectName).org /out $(MSBuildProjectName).exe + %_DebuggerFullPath% "%CORE_ROOT%\crossgen.exe" !OptionalArguments! /Platform_Assemblies_Paths %CORE_ROOT%%3B%25cd%25\IL%3B%25cd%25 /in $(MSBuildProjectName).org /out $(MSBuildProjectName).exe set CrossGenStatus=!ERRORLEVEL! ) call :ReleaseLock diff --git a/tests/src/readytorun/tests/versionbubbles/helper.cs b/tests/src/readytorun/tests/versionbubbles/helper.cs new file mode 100644 index 000000000000..8aeb51286326 --- /dev/null +++ b/tests/src/readytorun/tests/versionbubbles/helper.cs @@ -0,0 +1,13 @@ +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +public class Helper +{ + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public string GetLastMethodName() + { + StackTrace st = new StackTrace(); + return st.GetFrame(0).GetMethod().Name; + } +} \ No newline at end of file diff --git a/tests/src/readytorun/tests/versionbubbles/helper.csproj b/tests/src/readytorun/tests/versionbubbles/helper.csproj new file mode 100644 index 000000000000..45acb5ede084 --- /dev/null +++ b/tests/src/readytorun/tests/versionbubbles/helper.csproj @@ -0,0 +1,33 @@ + + + + + Debug + AnyCPU + 2.0 + {F74F55A1-DFCF-4C7C-B462-E96E1D0BB667} + library + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\ + $(DefineConstants);STATIC;CORECLR + SharedLibrary + True + + + + + + + + + False + + + + + + + + + + \ No newline at end of file diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs new file mode 100644 index 000000000000..f3af29731da1 --- /dev/null +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs @@ -0,0 +1,46 @@ +using System; + +public class Program +{ + public static int Main() + { + return RunTest(); + } + + public static int RunTest() + { + Helper helper = new Helper(); + string lastMethodName = String.Empty; + try + { + lastMethodName = helper.GetLastMethodName(); + } + catch (System.MissingMethodException e) + { + if((System.Environment.GetEnvironmentVariable("LargeVersionBubble") != null)) + { + // Cross-Assembly inlining is only allowed in multi-module version bubbles + Console.WriteLine("FAIL"); + return 101; + } + else + { + // The missing method is expected in the default crossgen case (i.e. no large version bubble) + Console.WriteLine("PASS"); + return 100; + } + } + + if (lastMethodName != "GetNumber") + { + // method in helper.cs has been inlined + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} \ No newline at end of file diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj b/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj new file mode 100644 index 000000000000..08f8ca8620d4 --- /dev/null +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + 2.0 + {7DECC55A-B584-4456-83BA-6C42A5B3B3CB} + exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + BuildAndRun + $(DefineConstants);STATIC;CORECLR + 1 + 1 + PdbOnly + True + + + + + + + + + False + + + + + {F74F55A1-DFCF-4C7C-B462-E96E1D0BB667} + + + + + + + + + + + + + From a9bd79f71cb4f0e243ecd842e9f6b442db32bffd Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 8 Jan 2019 18:43:20 -0800 Subject: [PATCH 14/28] Add Large Version Bubble Checks --- src/utilcode/pedecoder.cpp | 2 +- src/vm/readytoruninfo.cpp | 2 +- src/zap/zapimage.cpp | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 2bc261663729..89a0e8897be4 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2487,7 +2487,7 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const CONTRACT_END; IMAGE_DATA_DIRECTORY *pDir; - if (HasReadyToRunHeader()) + if (HasReadyToRunHeader() && IsLargeVersionBubbleEnabled()) { READYTORUN_HEADER * pHeader = GetReadyToRunHeader(); diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index b82c5c5e80ac..e82771332ee1 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -621,7 +621,7 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT } // TODO Change to incremented version - if (IsImageVersionAtLeast(2, 2)) + if (IsLargeVersionBubbleEnabled() && IsImageVersionAtLeast(2, 2)) { IMAGE_DATA_DIRECTORY * pManifestMetadata = FindSection(READYTORUN_SECTION_MANIFEST_METADATA); if (pManifestMetadata != NULL) diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 3c0009d17486..7239d53ffb5d 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1832,7 +1832,10 @@ void ZapImage::Compile() OutputTypesTableForReadyToRun(m_pMDImport); OutputInliningTableForReadyToRun(); OutputProfileDataForReadyToRun(); - OutputManifestMetadataForReadyToRun(); + if (IsLargeVersionBubbleEnabled()) + { + OutputManifestMetadataForReadyToRun(); + } } else #endif From ec660bdbd8f68b27b85cf61b6e98cf849190726a Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Tue, 8 Jan 2019 19:02:01 -0800 Subject: [PATCH 15/28] Cleanup --- src/jit/importer.cpp | 1 + src/tools/crossgen/crossgen.cpp | 4 ---- src/tools/r2rdump/R2RSection.cs | 1 - src/utilcode/pedecoder.cpp | 2 ++ src/vm/ceeload.cpp | 3 ++- src/vm/jitinterface.cpp | 3 +-- src/vm/peimage.cpp | 2 +- src/vm/readytoruninfo.cpp | 3 +-- src/zap/zapimage.cpp | 5 ++++- tests/src/readytorun/tests/versionbubbles/helper.cs | 2 +- tests/src/readytorun/tests/versionbubbles/helper.csproj | 2 +- tests/src/readytorun/tests/versionbubbles/versionbubbles.cs | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index c85653f180df..30812737add3 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -19907,6 +19907,7 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, inlineResult.NoteFatal(InlineObservation::CALLSITE_IS_CALL_TO_HELPER); return; } + /* Ignore indirect calls */ if (call->gtCallType == CT_INDIRECT) { diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index a37655d640fb..aadeb124b12d 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -106,7 +106,6 @@ void PrintUsageHelper() Output( W("Usage: crossgen [args] \n") W("\n") - // Command-Line switch help W(" /? or /help - Display this screen\n") W(" /nologo - Prevents displaying the logo\n") W(" /silent - Do not display completion message\n") @@ -122,8 +121,6 @@ void PrintUsageHelper() W(" - List of paths containing localized assembly directories\n") W(" /App_Paths \n") W(" - List of paths containing user-application assemblies and resources\n") - W(" /Version_Bubble_Assembly_Paths \n") - W(" - List of paths containing assemblies contained in a single version bubble\n") #ifndef NO_NGENPDB W(" /App_Ni_Paths \n") W(" - List of paths containing user-application native images\n") @@ -474,7 +471,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) dwFlags |= NGENWORKER_FLAGS_READYTORUN; while (argc > 0) { - // Command-line parsing if (MatchParameter(*argv, W("?")) || MatchParameter(*argv, W("help"))) { diff --git a/src/tools/r2rdump/R2RSection.cs b/src/tools/r2rdump/R2RSection.cs index 443d6390b6a1..d33c7f2ab93e 100644 --- a/src/tools/r2rdump/R2RSection.cs +++ b/src/tools/r2rdump/R2RSection.cs @@ -28,7 +28,6 @@ public enum SectionType READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109, READYTORUN_SECTION_INLINING_INFO = 110, READYTORUN_SECTION_PROFILEDATA_INFO = 111, - READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.2 } /// diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 89a0e8897be4..788d6451094c 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2474,6 +2474,8 @@ CORCOMPILE_METHOD_PROFILE_LIST *PEDecoder::GetNativeProfileDataList(COUNT_T * pS RETURN PTR_CORCOMPILE_METHOD_PROFILE_LIST(GetDirectoryData(pDir)); } + + PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const { CONTRACT(PTR_CVOID) diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 4938f762a216..070b0b233cca 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10054,7 +10054,8 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - // Check if Image is even R2R? + + // Check if image is R2R if (GetFile()->IsILImageReadyToRun()) { RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed); diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 11977f961600..6a9bebbe4c9a 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -676,8 +676,7 @@ BOOL CEEInfo::shouldEnforceCallvirtRestriction( // and the impact of the cut was vetted with partners. It would not be appropriate // to increase that unreported set without additional review. -// This needs to be updated to allow cross-assembly inlining -// TODO Undo this once prototyping is finished + bool IsInSameVersionBubble(Assembly * current, Assembly * target) { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index 6653accd68a9..838540844e87 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -467,7 +467,7 @@ IMDInternalImport* PEImage::GetNativeMDImport(BOOL loadAllowed) MODE_ANY; } CONTRACTL_END; - // Does this need to be something else? It might work either way + if (m_pNativeMDImport == NULL) { if (loadAllowed) diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index e82771332ee1..4d47d062bbe9 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -620,8 +620,7 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT } } - // TODO Change to incremented version - if (IsLargeVersionBubbleEnabled() && IsImageVersionAtLeast(2, 2)) + if (IsLargeVersionBubbleEnabled()) { IMAGE_DATA_DIRECTORY * pManifestMetadata = FindSection(READYTORUN_SECTION_MANIFEST_METADATA); if (pManifestMetadata != NULL) diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 7239d53ffb5d..7df61c648941 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1082,7 +1082,10 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) { - OutputManifestMetadata(); + if(IsLargeVersionBubbleEnabled()) + { + OutputManifestMetadata(); + } OutputTables(); diff --git a/tests/src/readytorun/tests/versionbubbles/helper.cs b/tests/src/readytorun/tests/versionbubbles/helper.cs index 8aeb51286326..0fc5aa66ec46 100644 --- a/tests/src/readytorun/tests/versionbubbles/helper.cs +++ b/tests/src/readytorun/tests/versionbubbles/helper.cs @@ -10,4 +10,4 @@ public string GetLastMethodName() StackTrace st = new StackTrace(); return st.GetFrame(0).GetMethod().Name; } -} \ No newline at end of file +} diff --git a/tests/src/readytorun/tests/versionbubbles/helper.csproj b/tests/src/readytorun/tests/versionbubbles/helper.csproj index 45acb5ede084..a11d2b0cf7ca 100644 --- a/tests/src/readytorun/tests/versionbubbles/helper.csproj +++ b/tests/src/readytorun/tests/versionbubbles/helper.csproj @@ -30,4 +30,4 @@ - \ No newline at end of file + diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs index f3af29731da1..eecefe820fb8 100644 --- a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs @@ -43,4 +43,4 @@ public static int RunTest() return 101; } } -} \ No newline at end of file +} From 662fc7e0f764dc1e459e6bbda0d767e3032e401c Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 09:15:22 -0800 Subject: [PATCH 16/28] Revert unnecessary check --- src/utilcode/pedecoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 788d6451094c..d442d34f5d27 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2489,7 +2489,7 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const CONTRACT_END; IMAGE_DATA_DIRECTORY *pDir; - if (HasReadyToRunHeader() && IsLargeVersionBubbleEnabled()) + if (HasReadyToRunHeader()) { READYTORUN_HEADER * pHeader = GetReadyToRunHeader(); From ecaadddd714a808d77d6048747b4b4e406e45732 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 17:58:21 -0800 Subject: [PATCH 17/28] Change EncodeMethod Version Bubble Condition --- src/vm/zapsig.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 88894835ff0e..f1a2e8df5e44 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -1127,7 +1127,11 @@ BOOL ZapSig::EncodeMethod( TypeHandle ownerType; #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && !pMethod->GetModule()->IsInCurrentVersionBubble()) + + // For methods encoded outside of the version bubble, we use pResolvedToken which describes the metadata token from which the method originated + // For tokens inside the version bubble we are not constrained by the contents of pResolvedToken and as such we skip this codepath + // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. + if (IsReadyToRunCompilation() && !IsLargeVersionBubbleEnabled()) { if (pResolvedToken == NULL) { @@ -1186,7 +1190,9 @@ BOOL ZapSig::EncodeMethod( } #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && !pMethod->GetModule()->IsInCurrentVersionBubble()) + + // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. + if (IsReadyToRunCompilation() && !IsLargeVersionBubbleEnabled()) { if (pConstrainedResolvedToken != NULL) { From 7868a56219ddbb9422fa27ec8e59da62ee0628a4 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 17:59:49 -0800 Subject: [PATCH 18/28] Add Large Version Bubble asserts --- src/zap/zapimport.cpp | 2 ++ src/zap/zapinfo.cpp | 1 + src/zap/zapreadytorun.cpp | 1 + 3 files changed, 4 insertions(+) diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index 3a6c79d0c7ee..9d8eec16e2f9 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -329,6 +329,7 @@ ZapGenericSignature * ZapImportTable::GetGenericSignature(PVOID signature, BOOL /*static*/ DWORD ZapImportTable::EncodeModuleHelper( LPVOID compileContext, CORINFO_MODULE_HANDLE referencedModule) { + _ASSERTE(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()); ZapImportTable * pTable = (ZapImportTable *)compileContext; return pTable->GetIndexOfModule(referencedModule); } @@ -952,6 +953,7 @@ void ZapImportTable::EncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODUL { if (module != GetImage()->GetModuleHandle()) { + _ASSERTE(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()); pSigBuilder->AppendByte(kind | ENCODE_MODULE_OVERRIDE); pSigBuilder->AppendData(GetIndexOfModule(module)); } diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 8c2a86e0b8b9..b998fe7e8f91 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -1424,6 +1424,7 @@ CORINFO_MODULE_HANDLE ZapInfo::embedModuleHandle(CORINFO_MODULE_HANDLE handle, void **ppIndirection) { _ASSERTE(ppIndirection != NULL); + _ASSERTE(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()); BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedModuleHandle(handle); if (fHardbound) diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp index 94b8534cd6d7..7e26411cf493 100644 --- a/src/zap/zapreadytorun.cpp +++ b/src/zap/zapreadytorun.cpp @@ -332,6 +332,7 @@ class DebugInfoVertex : public NativeFormat::Vertex /*static*/ DWORD ZapImage::EncodeModuleHelper(LPVOID compileContext, CORINFO_MODULE_HANDLE referencedModule) { + _ASSERTE(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()); ZapImportTable * pTable = (ZapImportTable *)compileContext; return pTable->GetIndexOfModule(referencedModule); } From 50f2bb08bd89749671e52534943dd37953ccc550 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 18:01:25 -0800 Subject: [PATCH 19/28] Cleanup --- src/tools/r2rdump/R2RSection.cs | 2 +- tests/src/readytorun/tests/versionbubbles/versionbubbles.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/r2rdump/R2RSection.cs b/src/tools/r2rdump/R2RSection.cs index d33c7f2ab93e..0c715cc6525a 100644 --- a/src/tools/r2rdump/R2RSection.cs +++ b/src/tools/r2rdump/R2RSection.cs @@ -27,7 +27,7 @@ public enum SectionType READYTORUN_SECTION_AVAILABLE_TYPES = 108, READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109, READYTORUN_SECTION_INLINING_INFO = 110, - READYTORUN_SECTION_PROFILEDATA_INFO = 111, + READYTORUN_SECTION_PROFILEDATA_INFO = 111 } /// diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs index eecefe820fb8..710e64e41833 100644 --- a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs @@ -31,7 +31,7 @@ public static int RunTest() } } - if (lastMethodName != "GetNumber") + if (lastMethodName != "GetLastMethodName") { // method in helper.cs has been inlined Console.WriteLine("PASS"); @@ -43,4 +43,4 @@ public static int RunTest() return 101; } } -} +} \ No newline at end of file From 825421276d5cf20ac559b4d0075d6c1dde161d63 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 18:41:23 -0800 Subject: [PATCH 20/28] Add default argument to runtests.py --- tests/runtest.py | 1 + tests/src/readytorun/tests/versionbubbles/versionbubbles.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/runtest.py b/tests/runtest.py index 61f69abb3f7b..5a38d84fab7f 100755 --- a/tests/runtest.py +++ b/tests/runtest.py @@ -966,6 +966,7 @@ def run_tests(host_os, is_ilasm=False, is_illink=False, run_crossgen_tests=False, + large_version_bubble=False, run_sequential=False, limited_core_dumps=False): """ Run the coreclr tests diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs index 710e64e41833..f7c396986d1c 100644 --- a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs @@ -43,4 +43,4 @@ public static int RunTest() return 101; } } -} \ No newline at end of file +} From 87159c987277525549a7c2661ea4af4ba81f5631 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Wed, 9 Jan 2019 19:13:30 -0800 Subject: [PATCH 21/28] Change test PreCommands --- .../tests/versionbubbles/versionbubbles.csproj | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj b/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj index 08f8ca8620d4..2a6b749c166a 100644 --- a/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.csproj @@ -39,20 +39,19 @@ From 8e1ab01e8721b982f8ef6281615565b97897f3ac Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 10 Jan 2019 09:54:03 -0800 Subject: [PATCH 22/28] Revert whitespace changes --- src/tools/crossgen/crossgen.cpp | 1 + src/vm/inlinetracking.h | 21 ++++++++++----------- src/vm/readytoruninfo.cpp | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index aadeb124b12d..b644f01fe880 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -469,6 +469,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) // By default, Crossgen will generate readytorun images unless /FragileNonVersionable switch is specified dwFlags |= NGENWORKER_FLAGS_READYTORUN; + while (argc > 0) { if (MatchParameter(*argv, W("?")) diff --git a/src/vm/inlinetracking.h b/src/vm/inlinetracking.h index 0d729099e89d..976a0e72db84 100644 --- a/src/vm/inlinetracking.h +++ b/src/vm/inlinetracking.h @@ -166,17 +166,17 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap; // It doesn't require any load time unpacking and serves requests directly from NGEN image. // // It is composed of two arrays: -// m_inlineeIndex - sorted (by ZapInlineeRecord.key i.e. by module then token) array of ZapInlineeRecords, given an inlinee module name hash (8 bits) -// and a method token (24 bits) we use binary search to find if this method has ever been inlined in NGen-ed code of this image. -// Each record has m_offset, which is an offset inside m_inlinersBuffer, it has more data on where the method got inlined. +// m_inlineeIndex - sorted (by ZapInlineeRecord.key i.e. by module then token) array of ZapInlineeRecords, given an inlinee module name hash (8 bits) +// and a method token (24 bits) we use binary search to find if this method has ever been inlined in NGen-ed code of this image. +// Each record has m_offset, which is an offset inside m_inlinersBuffer, it has more data on where the method got inlined. // -// It is totally possible to have more than one ZapInlineeRecords with the same key, not only due hash collision, but also due to -// the fact that we create one record for each (inlinee module / inliner module) pair. -// For example: we have MyModule!MyType that uses mscorlib!List. Let's say List.ctor got inlined into -// MyType.GetAllThinds() and into List.FindAll. In this case we'll have two InlineeRecords for mscorlib!List.ctor -// one for MyModule and another one for mscorlib. -// PersistentInlineTrackingMap.GetInliners() always reads all ZapInlineeRecords as long as they have the same key, few of them filtered out -// as hash collisions others provide legitimate inlining information for methods from different modules. +// It is totally possible to have more than one ZapInlineeRecords with the same key, not only due hash collision, but also due to +// the fact that we create one record for each (inlinee module / inliner module) pair. +// For example: we have MyModule!MyType that uses mscorlib!List. Let's say List.ctor got inlined into +// MyType.GetAllThinds() and into List.FindAll. In this case we'll have two InlineeRecords for mscorlib!List.ctor +// one for MyModule and another one for mscorlib. +// PersistentInlineTrackingMap.GetInliners() always reads all ZapInlineeRecords as long as they have the same key, few of them filtered out +// as hash collisions others provide legitimate inlining information for methods from different modules. // // m_inlinersBuffer - byte array compressed by NibbleWriter. At any valid offset taken from ZapInlineeRecord from m_inlineeIndex, there is a compressed chunk // of this format: @@ -257,7 +257,6 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap; // +-----------------+------------------------+------+------+--------+------+-------------+ // | - - - | SavedInlinersCount (N) | rid1 | rid2 | ...... | ridN | - - - | // +-----------------+------------------------+------+------+--------+------+-------------+ -// Contents above will either likely need changing or some other mechanism will be required to reference methods // diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index 4d47d062bbe9..dcc0b71e7108 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -455,6 +455,7 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker STANDARD_VM_CONTRACT; PEFile * pFile = pModule->GetFile(); + if (!IsReadyToRunEnabled()) { // Log message is ignored in this case. From 70711fda5e1206f892030dd4d848668b8d597f98 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 10 Jan 2019 09:54:29 -0800 Subject: [PATCH 23/28] Change breaking conditional check --- src/zap/zapimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 7df61c648941..3fa607333dbc 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1082,7 +1082,7 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) { - if(IsLargeVersionBubbleEnabled()) + if(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()) { OutputManifestMetadata(); } From 1a423c95d4cac4349bc3ad4f0f0a7389ab8f3d6f Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 10 Jan 2019 10:57:32 -0800 Subject: [PATCH 24/28] Streamline Version Bubble test --- .../tests/versionbubbles/versionbubbles.cs | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs index f7c396986d1c..fd1f596571e4 100644 --- a/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs +++ b/tests/src/readytorun/tests/versionbubbles/versionbubbles.cs @@ -9,28 +9,23 @@ public static int Main() public static int RunTest() { + Helper helper = new Helper(); string lastMethodName = String.Empty; - try - { - lastMethodName = helper.GetLastMethodName(); - } - catch (System.MissingMethodException e) + + lastMethodName = helper.GetLastMethodName(); + + if((System.Environment.GetEnvironmentVariable("LargeVersionBubble") == null)) { - if((System.Environment.GetEnvironmentVariable("LargeVersionBubble") != null)) - { - // Cross-Assembly inlining is only allowed in multi-module version bubbles - Console.WriteLine("FAIL"); - return 101; - } - else - { - // The missing method is expected in the default crossgen case (i.e. no large version bubble) - Console.WriteLine("PASS"); - return 100; - } + // Cross-Assembly inlining is only allowed in multi-module version bubbles + Console.WriteLine("Large Version Bubble is disabled."); + Console.WriteLine("PASS"); + return 100; } - + + Console.WriteLine("Large Version Bubble is enabled."); + // Helper returns the name of the method in the last stack frame + // Check to see if the method has been inlined cross-module if (lastMethodName != "GetLastMethodName") { // method in helper.cs has been inlined From 1dbbcf2854b66e3780d7b02dddcc3e9ae82b4862 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Thu, 10 Jan 2019 13:00:15 -0800 Subject: [PATCH 25/28] Address PR Feedback --- src/vm/zapsig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index f1a2e8df5e44..cacffebd1354 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -1131,7 +1131,7 @@ BOOL ZapSig::EncodeMethod( // For methods encoded outside of the version bubble, we use pResolvedToken which describes the metadata token from which the method originated // For tokens inside the version bubble we are not constrained by the contents of pResolvedToken and as such we skip this codepath // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. - if (IsReadyToRunCompilation() && !IsLargeVersionBubbleEnabled()) + if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble())) { if (pResolvedToken == NULL) { @@ -1192,7 +1192,7 @@ BOOL ZapSig::EncodeMethod( #ifdef FEATURE_READYTORUN_COMPILER // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. - if (IsReadyToRunCompilation() && !IsLargeVersionBubbleEnabled()) + if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble())) { if (pConstrainedResolvedToken != NULL) { From 9d1cb13c34562b952ae2707b35632a8e7948204e Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Fri, 11 Jan 2019 15:53:31 -0800 Subject: [PATCH 26/28] Address PR Feedback #2 --- src/inc/pedecoder.h | 4 ---- src/vm/ceeload.cpp | 29 +++-------------------------- src/vm/zapsig.cpp | 2 +- src/zap/zapinfo.cpp | 7 ++++++- 4 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/inc/pedecoder.h b/src/inc/pedecoder.h index 5344aca75122..4fdbee56ce2a 100644 --- a/src/inc/pedecoder.h +++ b/src/inc/pedecoder.h @@ -341,10 +341,6 @@ class PEDecoder BOOL HasReadyToRunHeader() const; READYTORUN_HEADER *GetReadyToRunHeader() const; -#ifdef FEATURE_READYTORUN_COMPILER - PTR_CVOID GetReadyToRunManifestMetadata() const; -#endif - void GetEXEStackSizes(SIZE_T *PE_SizeOfStackReserve, SIZE_T *PE_SizeOfStackCommit) const; CHECK CheckWillCreateGuardPage() const; diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 070b0b233cca..655bb263788c 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -10051,7 +10051,9 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) if (loadAllowed) INJECT_FAULT(COMPlusThrowOM()); else FORBID_FAULT; MODE_ANY; PRECONDITION(HasNativeOrReadyToRunImage()); - POSTCONDITION(CheckPointer(RETVAL)); + POSTCONDITION(loadAllowed ? + CheckPointer(RETVAL): + CheckPointer(RETVAL, NULL_OK)); } CONTRACT_END; @@ -10066,31 +10068,6 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed) } } -IMDInternalImport *Module::GetNativeAssemblyImportIfLoaded() -{ - CONTRACT(IMDInternalImport *) - { - INSTANCE_CHECK; - GC_NOTRIGGER; - NOTHROW; - FORBID_FAULT; - MODE_ANY; - PRECONDITION(HasNativeOrReadyToRunImage()); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - - CONTRACT_END; - // Check if Image is even R2R? - if (GetFile()->IsILImageReadyToRun()) - { - RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(false); - } - else - { - RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(false); - } -} - /*static*/ void Module::RestoreMethodTablePointerRaw(MethodTable ** ppMT, Module *pContainingModule, diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index cacffebd1354..734491ed668c 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -702,7 +702,7 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, { index -= fromModule->GetAssemblyRefMax(); tkAssemblyRef = RidToToken(index, mdtAssemblyRef); - IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImportIfLoaded(); + IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImport(FALSE); if (pMDImportOverride != NULL) { CHAR szFullName[MAX_CLASS_NAME + 1]; diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index b998fe7e8f91..f34e1146d501 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -1424,7 +1424,12 @@ CORINFO_MODULE_HANDLE ZapInfo::embedModuleHandle(CORINFO_MODULE_HANDLE handle, void **ppIndirection) { _ASSERTE(ppIndirection != NULL); - _ASSERTE(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled()); + + if (IsReadyToRunCompilation()) + { + _ASSERTE(!"embedModuleHandle"); + ThrowHR(E_NOTIMPL); + } BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedModuleHandle(handle); if (fHardbound) From 01a3b821acdb7ec5d1e24f65d3a339da7d7e81db Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Fri, 11 Jan 2019 17:50:24 -0800 Subject: [PATCH 27/28] Remove dead code --- src/vm/readytoruninfo.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index dcc0b71e7108..a67157569d93 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -621,15 +621,6 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT } } - if (IsLargeVersionBubbleEnabled()) - { - IMAGE_DATA_DIRECTORY * pManifestMetadata = FindSection(READYTORUN_SECTION_MANIFEST_METADATA); - if (pManifestMetadata != NULL) - { - NativeParser parser = NativeParser(&m_nativeReader, pManifestMetadata->VirtualAddress); - m_pMetaDataHashtable = NativeHashtable(parser); - } - } } static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pModule) From a1e0594b0b9d77841492ebcc35b4eb7cb23adcc2 Mon Sep 17 00:00:00 2001 From: Andon Andonov Date: Fri, 11 Jan 2019 17:50:38 -0800 Subject: [PATCH 28/28] Add crossgen-time ifdef --- src/inc/corcompile.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h index 52e8b5910645..f8f522c465da 100644 --- a/src/inc/corcompile.h +++ b/src/inc/corcompile.h @@ -1824,13 +1824,11 @@ inline bool IsReadyToRunCompilation() #endif } +#ifdef FEATURE_READYTORUN_COMPILER inline bool IsLargeVersionBubbleEnabled() { -#ifdef FEATURE_READYTORUN_COMPILER return g_fLargeVersionBubble; -#else - return false; -#endif } +#endif #endif /* COR_COMPILE_H_ */