diff options
Diffstat (limited to 'src/zap')
-rw-r--r-- | src/zap/zapcode.cpp | 2 | ||||
-rw-r--r-- | src/zap/zapheaders.cpp | 136 | ||||
-rw-r--r-- | src/zap/zapheaders.h | 34 | ||||
-rw-r--r-- | src/zap/zapimage.cpp | 51 | ||||
-rw-r--r-- | src/zap/zapimage.h | 2 | ||||
-rw-r--r-- | src/zap/zapinfo.cpp | 71 | ||||
-rw-r--r-- | src/zap/zapinfo.h | 2 | ||||
-rw-r--r-- | src/zap/zapmetadata.cpp | 4 | ||||
-rw-r--r-- | src/zap/zapper.cpp | 69 | ||||
-rw-r--r-- | src/zap/zapreadytorun.cpp | 3 |
10 files changed, 241 insertions, 133 deletions
diff --git a/src/zap/zapcode.cpp b/src/zap/zapcode.cpp index adad361de0..167c0ed912 100644 --- a/src/zap/zapcode.cpp +++ b/src/zap/zapcode.cpp @@ -1130,7 +1130,7 @@ void ZapUnwindInfo::Save(ZapWriter * pZapWriter) pZapWriter->Write(&runtimeFunction, sizeof(runtimeFunction)); } -#ifdef WIN64EXCEPTIONS +#if defined(WIN64EXCEPTIONS) && !defined(_TARGET_X86_) // Compare the unwind infos by their offset int __cdecl ZapUnwindInfo::CompareUnwindInfo(const void* a_, const void* b_) { diff --git a/src/zap/zapheaders.cpp b/src/zap/zapheaders.cpp index d8cd6fa7f9..2422c98a0b 100644 --- a/src/zap/zapheaders.cpp +++ b/src/zap/zapheaders.cpp @@ -249,19 +249,32 @@ void ZapImage::CopyWin32VersionResource() void ZapDebugDirectory::SaveOriginalDebugDirectoryEntry(ZapWriter *pZapWriter) { - if (m_pDebugData != NULL) + if (m_ppDebugData != nullptr) { - m_debugDirectory.SizeOfData = m_pDebugData->GetSize(); - m_debugDirectory.AddressOfRawData = m_pDebugData->GetRVA(); + for (DWORD i = 0; i < m_nDebugDirectory; i++) + { + if (m_ppDebugData[i] != nullptr) + { + m_pDebugDirectory[i].SizeOfData = m_ppDebugData[i]->GetSize(); + m_pDebugDirectory[i].AddressOfRawData = m_ppDebugData[i]->GetRVA(); - // Compute the absolute file (seek) pointer. We need to reach to the matching physical section to do that. - ZapPhysicalSection * pPhysicalSection = ZapImage::GetImage(pZapWriter)->m_pTextSection; + // Compute the absolute file (seek) pointer. We need to reach to the matching physical section to do that. + ZapPhysicalSection * pPhysicalSection = ZapImage::GetImage(pZapWriter)->m_pTextSection; - DWORD dwOffset = m_pDebugData->GetRVA() - pPhysicalSection->GetRVA(); - _ASSERTE(dwOffset < pPhysicalSection->GetSize()); - - m_debugDirectory.PointerToRawData = pPhysicalSection->GetFilePos() + dwOffset; - pZapWriter->Write(&m_debugDirectory, sizeof(m_debugDirectory)); + DWORD dwOffset = m_ppDebugData[i]->GetRVA() - pPhysicalSection->GetRVA(); + _ASSERTE(dwOffset < pPhysicalSection->GetSize()); + + m_pDebugDirectory[i].PointerToRawData = pPhysicalSection->GetFilePos() + dwOffset; + } + else + { + m_pDebugDirectory[i].SizeOfData = 0; + m_pDebugDirectory[i].AddressOfRawData = 0; + m_pDebugDirectory[i].PointerToRawData = 0; + } + } + + pZapWriter->Write(m_pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY) * m_nDebugDirectory); } } @@ -270,7 +283,10 @@ void ZapDebugDirectory::SaveNGenDebugDirectoryEntry(ZapWriter *pZapWriter) _ASSERTE(pZapWriter); IMAGE_DEBUG_DIRECTORY debugDirectory = {0}; - memcpy(&debugDirectory, &m_debugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY)); + if (m_nDebugDirectory > 0) + { + memcpy(&debugDirectory, m_pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY)); + } debugDirectory.Type = IMAGE_DEBUG_TYPE_CODEVIEW; debugDirectory.SizeOfData = m_pNGenPdbDebugData->GetSize(); debugDirectory.AddressOfRawData = m_pNGenPdbDebugData->GetRVA(); @@ -288,18 +304,49 @@ void ZapDebugDirectory::Save(ZapWriter * pZapWriter) _ASSERTE(pZapWriter); if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_NGenEnableCreatePdb)) { - SaveOriginalDebugDirectoryEntry(pZapWriter); SaveNGenDebugDirectoryEntry(pZapWriter); - } else { - SaveNGenDebugDirectoryEntry(pZapWriter); SaveOriginalDebugDirectoryEntry(pZapWriter); - } } +ZapPEExports::ZapPEExports(LPCWSTR dllPath) +{ + m_dllFileName = wcsrchr(dllPath, DIRECTORY_SEPARATOR_CHAR_W); + if (m_dllFileName != NULL) + m_dllFileName++; + else + m_dllFileName = dllPath; +} + +DWORD ZapPEExports::GetSize() +{ + return DWORD(sizeof(IMAGE_EXPORT_DIRECTORY) + wcslen(m_dllFileName) + 1); +} + +void ZapPEExports::Save(ZapWriter * pZapWriter) +{ + _ASSERTE(pZapWriter); + + IMAGE_EXPORT_DIRECTORY exports; + ZeroMemory(&exports, sizeof(exports)); + + exports.Name = pZapWriter->GetCurrentRVA() + sizeof(exports); + + // Write out exports header + pZapWriter->Write(&exports, sizeof(exports)); + + // Write out string that exports.Name points at. + for (LPCWSTR ptr = m_dllFileName; ; ptr++) + { + pZapWriter->Write((PVOID) ptr, 1); + if (*ptr == 0) + break; + } +} + // If the IL image has IMAGE_DIRECTORY_ENTRY_DEBUG with information about the PDB, // copy that information over to the ngen image. // This lets the debugger find out information about the PDB without loading @@ -321,8 +368,9 @@ void ZapImage::CopyDebugDirEntry() // IL PDB entry: copy of the (first of possibly many) IMAGE_DEBUG_DIRECTORY entry // in the IL image + DWORD nDebugEntry = 0; PIMAGE_DEBUG_DIRECTORY pDebugDir = NULL; - ZapBlob *pDebugData = NULL; + ZapNode **ppDebugData = NULL; if (m_ModuleDecoder.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG)) { COUNT_T debugEntrySize; @@ -339,40 +387,48 @@ void ZapImage::CopyDebugDirEntry() // should be a multiple of sizeof(IMAGE_DEBUG_DIRECTORY). _ASSERTE(0 == (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY))); - // @TODO: pDebugEntry is an array of IMAGE_DEBUG_DIRECTORYs. Some tools - // (like ibcmerge) add an extra dummy IMAGE_DEBUG_DIRECTORY to indicate - // that the image was modified post-link. - // We need to copy all the IMAGE_DEBUG_DIRECTORYs. For now, we only copy - // the first one as it holds the relevant debug information. - - pDebugDir = PIMAGE_DEBUG_DIRECTORY(pDebugEntry); - - // Some compilers set PointerToRawData but not AddressOfRawData as they put the - // data at the end of the file in an unmapped part of the file + nDebugEntry = DWORD(debugEntrySize / sizeof(IMAGE_DEBUG_DIRECTORY)); + pDebugDir = new (GetHeap()) IMAGE_DEBUG_DIRECTORY[nDebugEntry]; + memcpy(pDebugDir, (const void *)pDebugEntry, sizeof(IMAGE_DEBUG_DIRECTORY) * nDebugEntry); + ppDebugData = new (GetHeap()) ZapNode*[nDebugEntry]; + memset(ppDebugData, 0, nDebugEntry * sizeof(ZapNode*)); - RVA rvaOfRawData = (pDebugDir->AddressOfRawData != NULL) - ? pDebugDir->AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir->PointerToRawData); - - ULONG cbDebugData = pDebugDir->SizeOfData; - - if (cbDebugData != 0) { - if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData)) - m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n")); - else - pDebugData = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData); + for (DWORD i = 0; i < nDebugEntry; i++) + { + // Some compilers set PointerToRawData but not AddressOfRawData as they put the + // data at the end of the file in an unmapped part of the file + + RVA rvaOfRawData = (pDebugDir[i].AddressOfRawData != NULL) + ? pDebugDir[i].AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir[i].PointerToRawData); + + ULONG cbDebugData = pDebugDir[i].SizeOfData; + + if (cbDebugData != 0) { + if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData)) + m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n")); + else + ppDebugData[i] = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData); + } } } } } ZapDebugDirectory * pDebugDirectory = new (GetHeap()) ZapDebugDirectory(m_pNGenPdbDebugData, - pDebugData ? pDebugDir : NULL, - pDebugData); + nDebugEntry, + pDebugDir, + ppDebugData); m_pDebugSection->Place(pDebugDirectory); m_pDebugSection->Place(m_pNGenPdbDebugData); - if (pDebugData) - m_pDebugSection->Place(pDebugData); + if (ppDebugData) + { + for (DWORD i = 0; i < nDebugEntry; i++) + { + if (ppDebugData[i] != nullptr) + m_pDebugSection->Place(ppDebugData[i]); + } + } SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG, pDebugDirectory); } diff --git a/src/zap/zapheaders.h b/src/zap/zapheaders.h index 12b0a18a3d..0755c0ed2d 100644 --- a/src/zap/zapheaders.h +++ b/src/zap/zapheaders.h @@ -234,23 +234,22 @@ public: class ZapDebugDirectory : public ZapNode { ZapNode * m_pNGenPdbDebugData; - IMAGE_DEBUG_DIRECTORY m_debugDirectory; - ZapNode * m_pDebugData; + DWORD m_nDebugDirectory; + IMAGE_DEBUG_DIRECTORY * m_pDebugDirectory; + ZapNode ** m_ppDebugData; public: - ZapDebugDirectory(ZapNode *pNGenPdbDebugData, PIMAGE_DEBUG_DIRECTORY pDebugDirectory, ZapNode * pDebugData) + ZapDebugDirectory(ZapNode *pNGenPdbDebugData, DWORD nDebugDirectory, PIMAGE_DEBUG_DIRECTORY pDebugDirectory, ZapNode ** ppDebugData) : m_pNGenPdbDebugData(pNGenPdbDebugData), - m_pDebugData(pDebugData) + m_nDebugDirectory(nDebugDirectory), + m_pDebugDirectory(pDebugDirectory), + m_ppDebugData(ppDebugData) { - if (pDebugDirectory == NULL) - memset(&m_debugDirectory, 0, sizeof(IMAGE_DEBUG_DIRECTORY)); - else - memcpy(&m_debugDirectory, pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY)); } virtual DWORD GetSize() { - return m_pDebugData ? sizeof(IMAGE_DEBUG_DIRECTORY) * 2 : sizeof(IMAGE_DEBUG_DIRECTORY); + return sizeof(IMAGE_DEBUG_DIRECTORY) * (m_nDebugDirectory + 1); } virtual UINT GetAlignment() @@ -269,6 +268,23 @@ public: }; // +// PE Style exports. Currently can only save an empty list of exports +// but this is useful because it avoids the DLL being seen as Resource Only +// (which then causes SymServer to avoid copying its PDB to the cloud). +// + +class ZapPEExports : public ZapNode +{ + LPCWSTR m_dllFileName; // Just he DLL name without the path. + +public: + ZapPEExports(LPCWSTR dllPath); + virtual DWORD GetSize(); + virtual UINT GetAlignment() { return sizeof(DWORD); } + virtual void Save(ZapWriter * pZapWriter); +}; + +// // List of all sections for diagnostic purposes class ZapVirtualSectionsTable : public ZapNode diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index a435d6a44d..f39b8f8f54 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -291,6 +291,12 @@ void ZapImage::InitializeSectionsForReadyToRun() // Always allocate slot for module - it is used to determine that the image is used // m_pImportTable->GetPlacedHelperImport(READYTORUN_HELPER_Module); + + // + // Make sure the import sections table is in the image, so we can find the slot for module + // + _ASSERTE(m_pImportSectionsTable->GetSize() != 0); + GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_IMPORT_SECTIONS, m_pImportSectionsTable); } #endif // FEATURE_READYTORUN_COMPILER @@ -395,7 +401,7 @@ void ZapImage::AllocateVirtualSections() // // If we're instrumenting allocate a section for writing profile data // - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR)) { m_pInstrumentSection = NewVirtualSection(pDataSection, IBCUnProfiledSection | ColdRange | InstrumentSection, sizeof(TADDR)); } @@ -1163,6 +1169,14 @@ HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE OutputTables(); + // Create a empty export table. This makes tools like symchk not think + // that native images are resoure-only DLLs. It is important to NOT + // be a resource-only DLL because those DLL's PDBS are not put up on the + // symbol server and we want NEN PDBS to be placed there. + ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName); + m_pDebugSection->Place(exports); + SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports); + ComputeRVAs(); if (!IsReadyToRunCompilation()) @@ -1697,16 +1711,16 @@ void ZapImage::OutputTables() SetSizeOfStackCommit(m_ModuleDecoder.GetSizeOfStackCommit()); } -#if defined(_TARGET_ARM_) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM) +#if defined(FEATURE_PAL) + // PAL library requires native image sections to align to page bounaries. + SetFileAlignment(0x1000); +#elif defined(_TARGET_ARM_) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM) if (!IsReadyToRunCompilation()) { // On ARM CoreSys builds, crossgen will use 4k file alignment, as requested by Phone perf team // to improve perf on phones with compressed system partitions. SetFileAlignment(0x1000); } -#elif defined(FEATURE_PAL) - // PAL library requires native image sections to align to page bounaries. - SetFileAlignment(0x1000); #endif } @@ -1935,23 +1949,24 @@ struct CompileMethodStubContext //----------------------------------------------------------------------------- // static void __stdcall -void ZapImage::TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags) +void ZapImage::TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags) { STANDARD_VM_CONTRACT; // The caller must always set the IL_STUB flag - _ASSERTE((dwJitFlags & CORJIT_FLG_IL_STUB) != 0); + _ASSERTE(jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)); CompileMethodStubContext *pCompileContext = reinterpret_cast<CompileMethodStubContext *>(pContext); ZapImage *pImage = pCompileContext->pImage; - unsigned oldFlags = pImage->m_zapper->m_pOpt->m_compilerFlags; + CORJIT_FLAGS oldFlags = pImage->m_zapper->m_pOpt->m_compilerFlags; - pImage->m_zapper->m_pOpt->m_compilerFlags |= dwJitFlags; - pImage->m_zapper->m_pOpt->m_compilerFlags &= ~(CORJIT_FLG_PROF_ENTERLEAVE | - CORJIT_FLG_DEBUG_CODE | - CORJIT_FLG_DEBUG_EnC | - CORJIT_FLG_DEBUG_INFO); + CORJIT_FLAGS* pCompilerFlags = &pImage->m_zapper->m_pOpt->m_compilerFlags; + pCompilerFlags->Add(jitFlags); + pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); + pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); + pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC); + pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); mdMethodDef md = mdMethodDefNil; @@ -2191,7 +2206,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h if (GetCompiledMethod(handle) != NULL) return ALREADY_COMPILED; - _ASSERTE((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) || IsNilToken(md) || handle == m_pPreloader->LookupMethodDef(md)); + _ASSERTE(m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB) || IsNilToken(md) || handle == m_pPreloader->LookupMethodDef(md)); CompileStatus result = NOT_COMPILED; @@ -2205,7 +2220,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h CORINFO_MODULE_HANDLE module; // We only compile IL_STUBs from the current assembly - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) module = m_hModule; else module = m_zapper->m_pEEJitInfo->getMethodModule(handle); @@ -2263,7 +2278,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h if (m_stats != NULL) { - if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) == 0) + if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) m_stats->m_failedMethods++; else m_stats->m_failedILStubs++; @@ -2496,7 +2511,7 @@ HRESULT ZapImage::LocateProfileData() // the final image. // #if 0 - if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) != 0) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR)) return S_FALSE; #endif @@ -3473,7 +3488,7 @@ bool ZapImage::canIntraModuleDirectCall( // No direct calls at all under some circumstances - if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE) && !m_pPreloader->IsDynamicMethod(callerFtn)) { *pReason = CORINFO_INDIRECT_CALL_PROFILING; diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h index 842791805d..02985f5d12 100644 --- a/src/zap/zapimage.h +++ b/src/zap/zapimage.h @@ -656,7 +656,7 @@ public: NOT_COMPILED = 0, COMPILE_EXCLUDED = 1, // Info COMPILE_SUCCEED = 10, ALREADY_COMPILED = 11}; // Success - static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags); + static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags); BOOL IsVTableGapMethod(mdMethodDef md); diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 232570f09d..d2362d4b90 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -141,13 +141,13 @@ void ZapInfo::InitMethodName() m_currentMethodName.AppendUTF8(szMethodName); } -int ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle) +CORJIT_FLAGS ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle) { - int jitFlags = m_zapper->m_pOpt->m_compilerFlags; + CORJIT_FLAGS jitFlags = m_zapper->m_pOpt->m_compilerFlags; - DWORD flags = 0; + CORJIT_FLAGS flags; IfFailThrow(m_pEECompileInfo->GetBaseJitFlags(handle, &flags)); - jitFlags |= flags; + jitFlags.Add(flags); // COMPlus_JitFramed specifies the default fpo setting for jitted and NGened code. // You can override the behavior for NGened code using COMPlus_NGenFramed. @@ -156,52 +156,56 @@ int ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle) if (dwNGenFramed == 0) { // NGened code should enable fpo - jitFlags &= ~CORJIT_FLG_FRAMED; + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_FRAMED); } else if (dwNGenFramed == 1) { // NGened code should disable fpo - jitFlags |= CORJIT_FLG_FRAMED; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED); } if (canSkipMethodVerification(m_currentMethodHandle) == CORINFO_VERIFICATION_CAN_SKIP) { - jitFlags |= CORJIT_FLG_SKIP_VERIFICATION; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); } if (m_pImage->m_profileDataSections[MethodBlockCounts].pData && !m_zapper->m_pOpt->m_ignoreProfileData) { - jitFlags |= CORJIT_FLG_BBOPT; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT); } // // By default we always enable Hot/Cold procedure splitting // - jitFlags |= CORJIT_FLG_PROCSPLIT; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT); if (m_zapper->m_pOpt->m_noProcedureSplitting) - jitFlags &= ~CORJIT_FLG_PROCSPLIT; + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT); //never emit inlined polls for NGen'd code. The extra indirection is not optimal. - if (jitFlags & CORJIT_FLG_GCPOLL_INLINE) + if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE)) { - jitFlags &= ~CORJIT_FLG_GCPOLL_INLINE; - jitFlags |= CORJIT_FLG_GCPOLL_CALLS; + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE); + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS); } // If the method is specified for min-opts then turn everything off - if (jitFlags & CORJIT_FLG_MIN_OPT) - jitFlags &= ~(CORJIT_FLG_BBINSTR | CORJIT_FLG_BBOPT | CORJIT_FLG_PROCSPLIT); + if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT)) + { + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBOPT); + jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT); + } // Rejit is now enabled by default for NGEN'ed code. This costs us // some size in exchange for diagnostic functionality, but we've got // further work planned that should mitigate the size increase. - jitFlags |= CORJIT_FLG_PROF_REJIT_NOPS; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS); #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) - jitFlags |= CORJIT_FLG_READYTORUN; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN); #endif return jitFlags; @@ -427,14 +431,13 @@ void ZapInfo::CompileMethod() // this they can add the hint and reduce the perf cost at runtime. m_pImage->m_pPreloader->PrePrepareMethodIfNecessary(m_currentMethodHandle); - m_jitFlags = { 0 }; - m_jitFlags.corJitFlags = ComputeJitFlags(m_currentMethodHandle); + m_jitFlags = ComputeJitFlags(m_currentMethodHandle); #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) { // READYTORUN: FUTURE: Producedure spliting - m_jitFlags.corJitFlags &= ~CORJIT_FLG_PROCSPLIT; + m_jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT); DWORD methodAttribs = getMethodAttribs(m_currentMethodHandle); if (!(methodAttribs & CORINFO_FLG_NOSECURITYWRAP) || (methodAttribs & CORINFO_FLG_SECURITYCHECK)) @@ -445,13 +448,13 @@ void ZapInfo::CompileMethod() } #endif - if ((m_jitFlags.corJitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0) + if (!m_jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)) { BOOL raiseVerificationException, unverifiableGenericCode; - m_jitFlags.corJitFlags = GetCompileFlagsIfGenericInstantiation( + m_jitFlags = GetCompileFlagsIfGenericInstantiation( m_currentMethodHandle, - (CorJitFlag)m_jitFlags.corJitFlags, + m_jitFlags, this, &raiseVerificationException, &unverifiableGenericCode); @@ -465,7 +468,7 @@ void ZapInfo::CompileMethod() #if !defined(FEATURE_CORECLR) // Ask the JIT to generate desktop-quirk-compatible code. - m_jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS; + m_jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS); #endif if (m_pImage->m_stats) @@ -486,7 +489,7 @@ void ZapInfo::CompileMethod() res = m_zapper->m_alternateJit->compileMethod( this, &m_currentMethodInfo, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, &pCode, &cCode ); if (FAILED(res)) @@ -504,7 +507,7 @@ void ZapInfo::CompileMethod() ICorJitCompiler * pCompiler = m_zapper->m_pJitCompiler; res = pCompiler->compileMethod(this, &m_currentMethodInfo, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, &pCode, &cCode); @@ -813,7 +816,7 @@ void ZapInfo::PublishCompiledMethod() // // For now, the only methods eligible for de-duplication are IL stubs // - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) { ZapMethodHeader * pDuplicateMethod = m_pImage->m_CodeDeduplicator.Lookup(pMethod); if (pDuplicateMethod != NULL) @@ -830,7 +833,7 @@ void ZapInfo::PublishCompiledMethod() // Stubs that have no metadata token cannot be tracked by IBC data. if (m_currentMethodProfilingDataFlags & (1 << ReadMethodCode)) { - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) m_pImage->m_PrioritizedGCInfo.Append(pMethod->m_pGCInfo); } @@ -888,7 +891,7 @@ HRESULT ZapInfo::allocBBProfileBuffer ( { HRESULT hr; - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) { *ppBlock = NULL; return E_NOTIMPL; @@ -965,7 +968,7 @@ HRESULT ZapInfo::getBBProfileData ( // the profile data is in that module // @TODO: Fetch the profile data from the other module. if ((m_currentMethodModule != m_pImage->m_hModule) || - (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)) + m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) { return E_FAIL; } @@ -1054,7 +1057,7 @@ void ZapInfo::allocMem( void ** roDataBlock /* OUT */ ) { - bool optForSize = ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_SIZE_OPT) == CORJIT_FLG_SIZE_OPT); + bool optForSize = m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT); UINT align = DEFAULT_CODE_ALIGN; @@ -1194,7 +1197,7 @@ void ZapInfo::setEHinfo(unsigned EHnumber, { ilClause->ClassToken = clause->ClassToken; - if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) && (clause->ClassToken != 0)) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB) && (clause->ClassToken != 0)) { // IL stub tokens are 'private' and do not resolve correctly in their parent module's metadata. @@ -2298,7 +2301,7 @@ unsigned ZapInfo::getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirecti m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(cls); - if(!(m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_CODE)) + if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)) { if (isRIDClassDomainID(cls)) { @@ -3706,7 +3709,7 @@ CorInfoCanSkipVerificationResult ZapInfo::canSkipMethodVerification ( { // ILStubs are generated internally by the CLR. There is no need to // verify it, or any of its callees. - if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) + if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) return CORINFO_VERIFICATION_CAN_SKIP; CorInfoCanSkipVerificationResult canSkipVer = diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h index 3d8736f067..97ecfb6715 100644 --- a/src/zap/zapinfo.h +++ b/src/zap/zapinfo.h @@ -231,7 +231,7 @@ class ZapInfo void InitMethodName(); - int ComputeJitFlags(CORINFO_METHOD_HANDLE handle); + CORJIT_FLAGS ComputeJitFlags(CORINFO_METHOD_HANDLE handle); ZapDebugInfo * EmitDebugInfo(); ZapGCInfo * EmitGCInfo(); diff --git a/src/zap/zapmetadata.cpp b/src/zap/zapmetadata.cpp index e77dbb837f..a3a9e2d9d6 100644 --- a/src/zap/zapmetadata.cpp +++ b/src/zap/zapmetadata.cpp @@ -299,7 +299,7 @@ void ZapILMetaData::CopyMetaData() // unless we're producing an instrumented version - the IBC logging for meta data doesn't // work for the hot/cold split version. - if (m_pImage->m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) + if (m_pImage->m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR)) IfFailThrow(pIMetaDataCorProfileData->SetCorProfileData(NULL)); else IfFailThrow(pIMetaDataCorProfileData->SetCorProfileData(m_pImage->GetProfileData())); @@ -308,7 +308,7 @@ void ZapILMetaData::CopyMetaData() // If we are ngening with the tuning option, the IBC data that is // generated gets reordered and may be inconsistent with the // metadata in the original IL image. Let's just skip that case. - if (!(m_pImage->m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR)) + if (!m_pImage->m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR)) { // Communicate the reordering option for saving NonVMComHolder<IMDInternalMetadataReorderingOptions> pIMDInternalMetadataReorderingOptions; diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index bcb1b0edca..2c7023a400 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -425,12 +425,15 @@ ZapperOptions::ZapperOptions() : m_fPartialNGen(false), m_fPartialNGenSet(false), m_fNGenLastRetry(false), - m_compilerFlags(CORJIT_FLG_RELOC | CORJIT_FLG_PREJIT), + m_compilerFlags(), m_legacyMode(false) #ifdef FEATURE_CORECLR ,m_fNoMetaData(s_fNGenNoMetaData) #endif { + m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_RELOC); + m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PREJIT); + m_zapSet = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ZapSet); if (m_zapSet != NULL && wcslen(m_zapSet) > 3) { @@ -519,18 +522,21 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost) pOptions = ¤tVersionOptions; - zo->m_compilerFlags = CORJIT_FLG_RELOC | CORJIT_FLG_PREJIT; + zo->m_compilerFlags.Reset(); + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_RELOC); + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PREJIT); zo->m_autodebug = true; if (pOptions->fDebug) { - zo->m_compilerFlags |= CORJIT_FLG_DEBUG_INFO|CORJIT_FLG_DEBUG_CODE; + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); zo->m_autodebug = false; } if (pOptions->fProf) { - zo->m_compilerFlags |= CORJIT_FLG_PROF_ENTERLEAVE; + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); } #ifdef FEATURE_FUSION @@ -576,7 +582,7 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost) #endif //FEATURE_FUSION if (pOptions->fInstrument) - zo->m_compilerFlags |= CORJIT_FLG_BBINSTR; + zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); zo->m_verbose = pOptions->fVerbose; zo->m_statOptions = pOptions->uStats; @@ -1017,6 +1023,15 @@ void Zapper::DestroyDomain() CleanupAssembly(); // + // Shut down JIT compiler. + // + + if (m_pJitCompiler != NULL) + { + m_pJitCompiler->ProcessShutdownWork(NULL); + } + + // // Get rid of domain. // @@ -2032,10 +2047,10 @@ void Zapper::CreateCompilationDomain() BOOL fForceDebug = FALSE; if (!m_pOpt->m_autodebug) - fForceDebug = (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_INFO) != 0; + fForceDebug = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); - BOOL fForceProfile = (m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE) != 0; - BOOL fForceInstrument = (m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) != 0; + BOOL fForceProfile = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); + BOOL fForceInstrument = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); InitEE(fForceDebug, fForceProfile, fForceInstrument); @@ -3323,28 +3338,29 @@ IMetaDataAssemblyEmit * Zapper::CreateAssemblyEmitter() void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) { - m_pOpt->m_compilerFlags &= ~(CORJIT_FLG_DEBUG_INFO - | CORJIT_FLG_DEBUG_CODE - | CORJIT_FLG_PROF_ENTERLEAVE - | CORJIT_FLG_PROF_NO_PINVOKE_INLINE); + m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); + m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); + m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); + m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE); // We track debug info all the time in the ngen image - m_pOpt->m_compilerFlags |= CORJIT_FLG_DEBUG_INFO; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING) { - m_pOpt->m_compilerFlags |= (CORJIT_FLG_DEBUG_INFO| - CORJIT_FLG_DEBUG_CODE); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); } if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROFILING) { - m_pOpt->m_compilerFlags |= CORJIT_FLG_PROF_ENTERLEAVE | CORJIT_FLG_PROF_NO_PINVOKE_INLINE; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE); m_pOpt->m_ngenProfileImage = true; } if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROF_INSTRUMENTING) - m_pOpt->m_compilerFlags |= CORJIT_FLG_BBINSTR; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); #if defined(_TARGET_X86_) @@ -3353,7 +3369,7 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) switch (CPU_X86_FAMILY(pVersionInfo->cpuInfo.dwCPUType)) { case CPU_X86_PENTIUM_4: - m_pOpt->m_compilerFlags |= CORJIT_FLG_TARGET_P4; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4); break; default: @@ -3362,20 +3378,25 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) if (CPU_X86_USE_CMOV(pVersionInfo->cpuInfo.dwFeatures)) { - m_pOpt->m_compilerFlags |= CORJIT_FLG_USE_CMOV | - CORJIT_FLG_USE_FCOMI; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV); + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI); } +#if !defined(FEATURE_CORECLR) if (CPU_X86_USE_SSE2(pVersionInfo->cpuInfo.dwFeatures)) { - m_pOpt->m_compilerFlags |= CORJIT_FLG_USE_SSE2; + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2); } +#else + // .NET Core requires SSE2. + m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2); +#endif // !defined(FEATURE_CORECLR) #endif // _TARGET_X86_ - if ( (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_INFO) - && (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_CODE) - && (m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE)) + if ( m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO) + && m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE) + && m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE)) { // // We've decided not to support debugging + optimizations disabled + profiling to diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp index ea42a25b8d..30ad296f95 100644 --- a/src/zap/zapreadytorun.cpp +++ b/src/zap/zapreadytorun.cpp @@ -291,9 +291,6 @@ void ZapImage::OutputEntrypointsTableForReadyToRun() pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS, pHashtableBlob); pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_RUNTIME_FUNCTIONS, m_pRuntimeFunctionSection); - if (m_pImportSectionsTable->GetSize() != 0) - pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_IMPORT_SECTIONS, m_pImportSectionsTable); - if (m_pLazyMethodCallHelperSection->GetNodeCount() != 0) pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_DELAYLOAD_METHODCALL_THUNKS, m_pLazyMethodCallHelperSection); |