summaryrefslogtreecommitdiff
path: root/src/zap
diff options
context:
space:
mode:
Diffstat (limited to 'src/zap')
-rw-r--r--src/zap/zapcode.cpp2
-rw-r--r--src/zap/zapheaders.cpp136
-rw-r--r--src/zap/zapheaders.h34
-rw-r--r--src/zap/zapimage.cpp51
-rw-r--r--src/zap/zapimage.h2
-rw-r--r--src/zap/zapinfo.cpp71
-rw-r--r--src/zap/zapinfo.h2
-rw-r--r--src/zap/zapmetadata.cpp4
-rw-r--r--src/zap/zapper.cpp69
-rw-r--r--src/zap/zapreadytorun.cpp3
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 = &currentVersionOptions;
- 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);