diff options
Diffstat (limited to 'src')
66 files changed, 906 insertions, 471 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h index 671b45b392..e1190d7ab6 100644 --- a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h +++ b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h @@ -57,7 +57,11 @@ public: // When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of // SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation). +#if COR_JIT_EE_VERSION > 460 + unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); /* { return 0; } */ +#else unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags); /* { return 0; } */ +#endif // IL obfuscators sometimes interpose on the EE-JIT interface. This function allows the VM to // tell the JIT to use a particular ICorJitCompiler to implement the methods of this interface, diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index 6eb862c8b8..b847d9bc50 100644 --- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -653,7 +653,7 @@ public: // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // - // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will + // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void getBoundaries( @@ -683,7 +683,7 @@ public: // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // - // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will + // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void getVars( diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 2c46065b48..acf163ebce 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -744,7 +744,7 @@ void MethodContext::recCompileMethod(CORINFO_METHOD_INFO *info, unsigned flags) void MethodContext::dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value) { printf("CompiledMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u " - "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} " + "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} " "locals{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} " "flg-%08X", key, @@ -1098,8 +1098,8 @@ void MethodContext::recGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes, DW } void MethodContext::dmpGetJitFlags(DWORD key, DD value) { - CORJIT_FLAGS *flags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A); - printf("GetJitFlags key %u sizeInBytes-%u corJitFlags-%08X corJitFlags2-%08X", key, value.B, flags->corJitFlags, flags->corJitFlags2); + CORJIT_FLAGS *jitflags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A); + printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX", key, value.B, jitflags->GetFlagsRaw()); GetJitFlags->Unlock(); } DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes) diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp index e3f5ae2764..c5f6d8aac1 100644 --- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp @@ -109,7 +109,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */) original_ICorJitCompiler->getVersionIdentifier(versionIdentifier); } -unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) +unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); } diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index fb9163629d..5706b0ae7b 100644 --- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1173,7 +1173,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getBoundaries( @@ -1214,7 +1214,7 @@ void interceptor_ICJI::setBoundaries( // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getVars( diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp index da766cc51d..2e088d438c 100644 --- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp @@ -55,7 +55,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */) original_ICorJitCompiler->getVersionIdentifier(versionIdentifier); } -unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) +unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { mcs->AddCall("getMaxIntrinsicSIMDVectorLength"); return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 77519caa84..448fb1f686 100644 --- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -961,7 +961,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getBoundaries( @@ -999,7 +999,7 @@ void interceptor_ICJI::setBoundaries( // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getVars( diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp index f6fceb2029..ec266e164f 100644 --- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp @@ -48,7 +48,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */) original_ICorJitCompiler->getVersionIdentifier(versionIdentifier); } -unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) +unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); } diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 89b19d8754..4d145f6a41 100644 --- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -876,7 +876,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getBoundaries( @@ -912,7 +912,7 @@ void interceptor_ICJI::setBoundaries( // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void interceptor_ICJI::getVars( diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 41b0195a6d..b05a284aa5 100644 --- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1018,7 +1018,7 @@ bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void MyICJI::getBoundaries( @@ -1068,7 +1068,7 @@ void MyICJI::setBoundaries( // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // -// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will +// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. void MyICJI::getVars( diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h index 70db9f162b..967a7713aa 100644 --- a/src/inc/corcompile.h +++ b/src/inc/corcompile.h @@ -1164,7 +1164,7 @@ enum CorCompileILRegion class ICorCompilePreloader { public: - typedef void (__stdcall *CORCOMPILE_CompileStubCallback)(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags); + typedef void (__stdcall *CORCOMPILE_CompileStubCallback)(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags); // // Map methods are available after Serialize() is called @@ -1849,7 +1849,7 @@ class ICorCompileInfo // Get the compilation flags that are shared between JIT and NGen virtual HRESULT GetBaseJitFlags( IN CORINFO_METHOD_HANDLE hMethod, - OUT DWORD *pFlags) = 0; + OUT CORJIT_FLAGS *pFlags) = 0; // needed for stubs to obtain the number of bytes to copy into the native image // return the beginning of the stub and the size to copy (in bytes) @@ -1887,16 +1887,16 @@ class ICorCompileInfo /*****************************************************************************/ // This function determines the compile flags to use for a generic intatiation // since only the open instantiation can be verified. -// See the comment associated with CORJIT_FLG_SKIP_VERIFICATION for details. +// See the comment associated with CORJIT_FLAG_SKIP_VERIFICATION for details. // // On return: // if *raiseVerificationException=TRUE, the caller should raise a VerificationException. // if *unverifiableGenericCode=TRUE, the method is a generic instantiation with // unverifiable code -CorJitFlag GetCompileFlagsIfGenericInstantiation( +CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( CORINFO_METHOD_HANDLE method, - CorJitFlag compileFlags, + CORJIT_FLAGS compileFlags, ICorJitInfo * pCorJitInfo, BOOL * raiseVerificationException, BOOL * unverifiableGenericCode); diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index 2cac92e2ed..cb736cdde5 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use #if COR_JIT_EE_VERSION > 460 // Update this one -SELECTANY const GUID JITEEVersionIdentifier = { /* 8d588c98-4cef-4e6d-9792-08e1f5ab88c5 */ - 0x8d588c98, - 0x4cef, - 0x4e6d, - {0x97, 0x92, 0x08, 0xe1, 0xf5, 0xab, 0x88, 0xc5} +SELECTANY const GUID JITEEVersionIdentifier = { /* 4bd06266-8ef7-4172-bec6-d3149fde7859 */ + 0x4bd06266, + 0x8ef7, + 0x4172, + {0xbe, 0xc6, 0xd3, 0x14, 0x9f, 0xde, 0x78, 0x59} }; #else @@ -2635,7 +2635,7 @@ public: // in the code are. The native compiler will ensure that these places // have a corresponding break point in native code. // - // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will + // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. virtual void getBoundaries( @@ -2665,7 +2665,7 @@ public: // under debugging, the JIT needs to keep them live over their // entire scope so that they can be inspected. // - // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will + // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will // be used only as a hint and the native compiler should not change its // code generation. virtual void getVars( diff --git a/src/inc/corjit.h b/src/inc/corjit.h index e4deabd0e1..6d01b9f9d9 100644 --- a/src/inc/corjit.h +++ b/src/inc/corjit.h @@ -73,6 +73,8 @@ enum CorJitResult }; +#if COR_JIT_EE_VERSION <= 460 + /* values for flags in compileMethod */ enum CorJitFlag @@ -133,21 +135,11 @@ enum CorJitFlag CORJIT_FLG_ALIGN_LOOPS = 0x20000000, // add NOPs before loops to align them at 16 byte boundaries CORJIT_FLG_PUBLISH_SECRET_PARAM= 0x40000000, // JIT must place stub secret param into local 0. (used by IL stubs) CORJIT_FLG_GCPOLL_INLINE = 0x80000000, // JIT must inline calls to GCPoll when possible - -#if COR_JIT_EE_VERSION > 460 - CORJIT_FLG_CALL_GETJITFLAGS = 0xffffffff, // Indicates that the JIT should retrieve flags in the form of a - // pointer to a CORJIT_FLAGS value via ICorJitInfo::getJitFlags(). -#endif }; enum CorJitFlag2 { CORJIT_FLG2_SAMPLING_JIT_BACKGROUND = 0x00000001, // JIT is being invoked as a result of stack sampling for hot methods in the background -#if COR_JIT_EE_VERSION > 460 - CORJIT_FLG2_USE_PINVOKE_HELPERS = 0x00000002, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions - CORJIT_FLG2_REVERSE_PINVOKE = 0x00000004, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog - CORJIT_FLG2_DESKTOP_QUIRKS = 0x00000008, // The JIT should generate desktop-quirk-compatible code -#endif }; struct CORJIT_FLAGS @@ -156,11 +148,157 @@ struct CORJIT_FLAGS unsigned corJitFlags2; // Values are from CorJitFlag2 }; +#endif // COR_JIT_EE_VERSION <= 460 + +#if COR_JIT_EE_VERSION > 460 + +class CORJIT_FLAGS +{ +public: + + enum CorJitFlag + { + CORJIT_FLAG_CALL_GETJITFLAGS = 0xffffffff, // Indicates that the JIT should retrieve flags in the form of a + // pointer to a CORJIT_FLAGS value via ICorJitInfo::getJitFlags(). + CORJIT_FLAG_SPEED_OPT = 0, + CORJIT_FLAG_SIZE_OPT = 1, + CORJIT_FLAG_DEBUG_CODE = 2, // generate "debuggable" code (no code-mangling optimizations) + CORJIT_FLAG_DEBUG_EnC = 3, // We are in Edit-n-Continue mode + CORJIT_FLAG_DEBUG_INFO = 4, // generate line and local-var info + CORJIT_FLAG_MIN_OPT = 5, // disable all jit optimizations (not necesarily debuggable code) + CORJIT_FLAG_GCPOLL_CALLS = 6, // Emit calls to JIT_POLLGC for thread suspension. + CORJIT_FLAG_MCJIT_BACKGROUND = 7, // Calling from multicore JIT background thread, do not call JitComplete + + #if defined(_TARGET_X86_) + + CORJIT_FLAG_PINVOKE_RESTORE_ESP = 8, // Restore ESP after returning from inlined PInvoke + CORJIT_FLAG_TARGET_P4 = 9, + CORJIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction + CORJIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction + CORJIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions + + #else // !defined(_TARGET_X86_) + + CORJIT_FLAG_UNUSED1 = 8, + CORJIT_FLAG_UNUSED2 = 9, + CORJIT_FLAG_UNUSED3 = 10, + CORJIT_FLAG_UNUSED4 = 11, + CORJIT_FLAG_UNUSED5 = 12, + + #endif // !defined(_TARGET_X86_) + + #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) + + CORJIT_FLAG_USE_SSE3_4 = 13, + CORJIT_FLAG_USE_AVX = 14, + CORJIT_FLAG_USE_AVX2 = 15, + CORJIT_FLAG_USE_AVX_512 = 16, + CORJIT_FLAG_FEATURE_SIMD = 17, + + #else // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) + + CORJIT_FLAG_UNUSED6 = 13, + CORJIT_FLAG_UNUSED7 = 14, + CORJIT_FLAG_UNUSED8 = 15, + CORJIT_FLAG_UNUSED9 = 16, + CORJIT_FLAG_UNUSED10 = 17, + + #endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) + + CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. + CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation + CORJIT_FLAG_PROF_ENTERLEAVE = 20, // Instrument prologues/epilogues + CORJIT_FLAG_PROF_REJIT_NOPS = 21, // Insert NOPs to ensure code is re-jitable + CORJIT_FLAG_PROF_NO_PINVOKE_INLINE = 22, // Disables PInvoke inlining + CORJIT_FLAG_SKIP_VERIFICATION = 23, // (lazy) skip verification - determined without doing a full resolve. See comment below + CORJIT_FLAG_PREJIT = 24, // jit or prejit is the execution engine. + CORJIT_FLAG_RELOC = 25, // Generate relocatable code + CORJIT_FLAG_IMPORT_ONLY = 26, // Only import the function + CORJIT_FLAG_IL_STUB = 27, // method is an IL stub + CORJIT_FLAG_PROCSPLIT = 28, // JIT should separate code into hot and cold sections + CORJIT_FLAG_BBINSTR = 29, // Collect basic block profile information + CORJIT_FLAG_BBOPT = 30, // Optimize method based on profile information + CORJIT_FLAG_FRAMED = 31, // All methods have an EBP frame + CORJIT_FLAG_ALIGN_LOOPS = 32, // add NOPs before loops to align them at 16 byte boundaries + CORJIT_FLAG_PUBLISH_SECRET_PARAM = 33, // JIT must place stub secret param into local 0. (used by IL stubs) + CORJIT_FLAG_GCPOLL_INLINE = 34, // JIT must inline calls to GCPoll when possible + CORJIT_FLAG_SAMPLING_JIT_BACKGROUND = 35, // JIT is being invoked as a result of stack sampling for hot methods in the background + CORJIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions + CORJIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog + CORJIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code + }; + + CORJIT_FLAGS() + : corJitFlags(0) + { + // empty + } + + // Convenience constructor to set exactly one flag. + CORJIT_FLAGS(CorJitFlag flag) + : corJitFlags(0) + { + Set(flag); + } + + CORJIT_FLAGS(const CORJIT_FLAGS& other) + { + corJitFlags = other.corJitFlags; + } + + void Reset() + { + corJitFlags = 0; + } + + void Set(CorJitFlag flag) + { + corJitFlags |= 1ULL << (unsigned __int64)flag; + } + + void Clear(CorJitFlag flag) + { + corJitFlags &= ~(1ULL << (unsigned __int64)flag); + } + + bool IsSet(CorJitFlag flag) const + { + return (corJitFlags & (1ULL << (unsigned __int64)flag)) != 0; + } + + void Add(const CORJIT_FLAGS& other) + { + corJitFlags |= other.corJitFlags; + } + + void Remove(const CORJIT_FLAGS& other) + { + corJitFlags &= ~other.corJitFlags; + } + + bool IsEmpty() const + { + return corJitFlags == 0; + } + + // DO NOT USE THIS FUNCTION! (except in very restricted special cases) + unsigned __int64 GetFlagsRaw() + { + return corJitFlags; + } + +private: + + unsigned __int64 corJitFlags; +}; + +#endif // COR_JIT_EE_VERSION > 460 + /***************************************************************************** -Here is how CORJIT_FLG_SKIP_VERIFICATION should be interepreted. +Here is how CORJIT_FLAG_SKIP_VERIFICATION should be interepreted. Note that even if any method is inlined, it need not be verified. -if (CORJIT_FLG_SKIP_VERIFICATION is passed in to ICorJitCompiler::compileMethod()) +if (CORJIT_FLAG_SKIP_VERIFICATION is passed in to ICorJitCompiler::compileMethod()) { No verification needs to be done. Just compile the method, generating unverifiable code if necessary @@ -245,7 +383,7 @@ else case INSTVER_GENERIC_PASSED_VERIFICATION: { - This cannot ever happen because the VM would pass in CORJIT_FLG_SKIP_VERIFICATION. + This cannot ever happen because the VM would pass in CORJIT_FLAG_SKIP_VERIFICATION. } case INSTVER_GENERIC_FAILED_VERIFICATION: @@ -260,7 +398,7 @@ else case CORINFO_VERIFICATION_CAN_SKIP: { - This cannot ever happen because the CLR would pass in CORJIT_FLG_SKIP_VERIFICATION. + This cannot ever happen because the CLR would pass in CORJIT_FLAG_SKIP_VERIFICATION. } case CORINFO_VERIFICATION_RUNTIME_CHECK: @@ -377,7 +515,11 @@ public: // When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of // SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation). +#if COR_JIT_EE_VERSION > 460 + virtual unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { return 0; } +#else virtual unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) { return 0; } +#endif // IL obfuscators sometimes interpose on the EE-JIT interface. This function allows the VM to // tell the JIT to use a particular ICorJitCompiler to implement the methods of this interface, diff --git a/src/inc/zapper.h b/src/inc/zapper.h index 2fa94373fa..1018505faa 100644 --- a/src/inc/zapper.h +++ b/src/inc/zapper.h @@ -540,7 +540,7 @@ class ZapperOptions bool m_fNGenLastRetry; // This is retry of the compilation - unsigned m_compilerFlags; + CORJIT_FLAGS m_compilerFlags; bool m_legacyMode; // true if the zapper was invoked using legacy mode diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp index ade2deabb9..6f27f0ceaf 100755..100644 --- a/src/jit/codegencommon.cpp +++ b/src/jit/codegencommon.cpp @@ -3014,7 +3014,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode) #if defined(DEBUG) , (compiler->compCodeOpt() != Compiler::SMALL_CODE) && - !(compiler->opts.eeFlags & CORJIT_FLG_PREJIT) + !compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) #endif #ifdef LEGACY_BACKEND , @@ -7817,7 +7817,7 @@ void CodeGen::genPrologPadForReJit() assert(compiler->compGeneratingProlog); #ifdef _TARGET_XARCH_ - if (!(compiler->opts.eeFlags & CORJIT_FLG_PROF_REJIT_NOPS)) + if (!compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_REJIT_NOPS)) { return; } diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp index 5c1bb0990e..a8d925c2a2 100644 --- a/src/jit/codegenlegacy.cpp +++ b/src/jit/codegenlegacy.cpp @@ -12895,7 +12895,7 @@ void CodeGen::genCodeForBBlist() // harmless "inc" instruction (does not interfere with the exception // object). - if ((compiler->opts.eeFlags & CORJIT_FLG_BBINSTR) && (stmt == block->bbTreeList) && + if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR) && (stmt == block->bbTreeList) && (block->bbCatchTyp && handlerGetsXcptnObj(block->bbCatchTyp))) { nonVarPtrRegs &= ~RBM_EXCEPTION_OBJECT; @@ -19875,7 +19875,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed) #if defined(_TARGET_X86_) if (call->gtFlags & GTF_CALL_UNMANAGED) { - if ((compiler->opts.eeFlags & CORJIT_FLG_PINVOKE_RESTORE_ESP) || + if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PINVOKE_RESTORE_ESP) || compiler->compStressCompile(Compiler::STRESS_PINVOKE_RESTORE_ESP, 50)) { // P/Invoke signature mismatch resilience - restore ESP to pre-call value. We would ideally diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index c6e6e03475..5db37a94ce 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -2269,14 +2269,14 @@ const char* Compiler::compLocalVarName(unsigned varNum, unsigned offs) void Compiler::compSetProcessor() { - unsigned compileFlags = opts.eeFlags; + const JitFlags& jitFlags = *opts.jitFlags; #if defined(_TARGET_ARM_) info.genCPU = CPU_ARM; #elif defined(_TARGET_AMD64_) info.genCPU = CPU_X64; #elif defined(_TARGET_X86_) - if (compileFlags & CORJIT_FLG_TARGET_P4) + if (jitFlags.IsSet(JitFlags::JIT_FLAG_TARGET_P4)) info.genCPU = CPU_X86_PENTIUM_4; else info.genCPU = CPU_X86; @@ -2296,7 +2296,7 @@ void Compiler::compSetProcessor() // COMPlus_EnableAVX can be used to disable using AVX if available on a target machine. // Note that FEATURE_AVX_SUPPORT is not enabled for ctpjit opts.compCanUseAVX = false; - if (((compileFlags & CORJIT_FLG_PREJIT) == 0) && ((compileFlags & CORJIT_FLG_USE_AVX2) != 0)) + if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2)) { if (JitConfig.EnableAVX() != 0) { @@ -2311,9 +2311,9 @@ void Compiler::compSetProcessor() #endif //_TARGET_AMD64_ #ifdef _TARGET_X86_ - opts.compUseFCOMI = ((opts.eeFlags & CORJIT_FLG_USE_FCOMI) != 0); - opts.compUseCMOV = ((opts.eeFlags & CORJIT_FLG_USE_CMOV) != 0); - opts.compCanUseSSE2 = ((opts.eeFlags & CORJIT_FLG_USE_SSE2) != 0); + opts.compUseFCOMI = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_FCOMI); + opts.compUseCMOV = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_CMOV); + opts.compCanUseSSE2 = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE2); #ifdef DEBUG if (opts.compUseFCOMI) @@ -2403,31 +2403,36 @@ unsigned ReinterpretHexAsDecimal(unsigned in) return result; } -void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) +void Compiler::compInitOptions(JitFlags* jitFlags) { #ifdef UNIX_AMD64_ABI opts.compNeedToAlignFrame = false; #endif // UNIX_AMD64_ABI memset(&opts, 0, sizeof(opts)); - unsigned compileFlags = jitFlags->corJitFlags; - if (compIsForInlining()) { - assert((compileFlags & CORJIT_FLG_LOST_WHEN_INLINING) == 0); - assert(compileFlags & CORJIT_FLG_SKIP_VERIFICATION); + // The following flags are lost when inlining. (They are removed in + // Compiler::fgInvokeInlineeCompiler().) + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT)); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR)); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_ENTERLEAVE)); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_EnC)); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_INFO)); + + assert(jitFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION)); } opts.jitFlags = jitFlags; - opts.eeFlags = compileFlags; opts.compFlags = CLFLG_MAXOPT; // Default value is for full optimization - if (opts.eeFlags & (CORJIT_FLG_DEBUG_CODE | CORJIT_FLG_MIN_OPT)) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT)) { opts.compFlags = CLFLG_MINOPT; } // Don't optimize .cctors (except prejit) or if we're an inlinee - else if (!(opts.eeFlags & CORJIT_FLG_PREJIT) && ((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && !compIsForInlining()) + else if (!jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && ((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && + !compIsForInlining()) { opts.compFlags = CLFLG_MINOPT; } @@ -2439,24 +2444,25 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // If the EE sets SIZE_OPT or if we are compiling a Class constructor // we will optimize for code size at the expense of speed // - if ((opts.eeFlags & CORJIT_FLG_SIZE_OPT) || ((info.compFlags & FLG_CCTOR) == FLG_CCTOR)) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT) || ((info.compFlags & FLG_CCTOR) == FLG_CCTOR)) { opts.compCodeOpt = SMALL_CODE; } // // If the EE sets SPEED_OPT we will optimize for speed at the expense of code size // - else if (opts.eeFlags & CORJIT_FLG_SPEED_OPT) + else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT)) { opts.compCodeOpt = FAST_CODE; - assert((opts.eeFlags & CORJIT_FLG_SIZE_OPT) == 0); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT)); } //------------------------------------------------------------------------- - opts.compDbgCode = (opts.eeFlags & CORJIT_FLG_DEBUG_CODE) != 0; - opts.compDbgInfo = (opts.eeFlags & CORJIT_FLG_DEBUG_INFO) != 0; - opts.compDbgEnC = (opts.eeFlags & CORJIT_FLG_DEBUG_EnC) != 0; + opts.compDbgCode = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE); + opts.compDbgInfo = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_INFO); + opts.compDbgEnC = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_EnC); + #if REGEN_SHORTCUTS || REGEN_CALLPAT // We never want to have debugging enabled when regenerating GC encoding patterns opts.compDbgCode = false; @@ -2496,7 +2502,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #ifdef DEBUG const JitConfigValues::MethodSet* pfAltJit; - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { pfAltJit = &JitConfig.AltJitNgen(); } @@ -2521,7 +2527,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #else // !DEBUG const char* altJitVal; - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { altJitVal = JitConfig.AltJitNgen().list(); } @@ -2625,7 +2631,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // if (!compIsForInlining()) { - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { if (JitConfig.NgenDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) { @@ -2977,7 +2983,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #ifdef FEATURE_SIMD #ifdef _TARGET_AMD64_ // Minimum bar for availing SIMD benefits is SSE2 on AMD64. - featureSIMD = ((opts.eeFlags & CORJIT_FLG_FEATURE_SIMD) != 0); + featureSIMD = jitFlags->IsSet(JitFlags::JIT_FLAG_FEATURE_SIMD); #endif // _TARGET_AMD64_ #endif // FEATURE_SIMD @@ -3032,7 +3038,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // if (!altJitConfig || opts.altJit) { - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { if ((JitConfig.NgenOrder() & 1) == 1) { @@ -3197,10 +3203,10 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #endif #ifdef PROFILING_SUPPORTED - opts.compNoPInvokeInlineCB = (opts.eeFlags & CORJIT_FLG_PROF_NO_PINVOKE_INLINE) ? true : false; + opts.compNoPInvokeInlineCB = jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_NO_PINVOKE_INLINE); // Cache the profiler handle - if (opts.eeFlags & CORJIT_FLG_PROF_ENTERLEAVE) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_ENTERLEAVE)) { BOOL hookNeeded; BOOL indirected; @@ -3245,7 +3251,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) } #endif - opts.compMustInlinePInvokeCalli = (opts.eeFlags & CORJIT_FLG_IL_STUB) ? true : false; + opts.compMustInlinePInvokeCalli = jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB); opts.compScopeInfo = opts.compDbgInfo; @@ -3257,7 +3263,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) //------------------------------------------------------------------------- #if RELOC_SUPPORT - opts.compReloc = (opts.eeFlags & CORJIT_FLG_RELOC) ? true : false; + opts.compReloc = jitFlags->IsSet(JitFlags::JIT_FLAG_RELOC); #endif #ifdef DEBUG @@ -3267,7 +3273,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #endif #endif // DEBUG - opts.compProcedureSplitting = (opts.eeFlags & CORJIT_FLG_PROCSPLIT) ? true : false; + opts.compProcedureSplitting = jitFlags->IsSet(JitFlags::JIT_FLAG_PROCSPLIT); #ifdef _TARGET_ARM64_ // TODO-ARM64-NYI: enable hot/cold splitting @@ -3312,7 +3318,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) fgProfileBuffer = nullptr; fgProfileData_ILSizeMismatch = false; fgNumProfileRuns = 0; - if (opts.eeFlags & CORJIT_FLG_BBOPT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT)) { assert(!compIsForInlining()); HRESULT hr; @@ -3383,7 +3389,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) printf("OPTIONS: compProcedureSplitting = %s\n", dspBool(opts.compProcedureSplitting)); printf("OPTIONS: compProcedureSplittingEH = %s\n", dspBool(opts.compProcedureSplittingEH)); - if ((opts.eeFlags & CORJIT_FLG_BBOPT) && fgHaveProfileData()) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && fgHaveProfileData()) { printf("OPTIONS: using real profile data\n"); } @@ -3393,7 +3399,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) printf("OPTIONS: discarded IBC profile data due to mismatch in ILSize\n"); } - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { printf("OPTIONS: Jit invoked for ngen\n"); } @@ -3402,11 +3408,11 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #endif opts.compGCPollType = GCPOLL_NONE; - if (opts.eeFlags & CORJIT_FLG_GCPOLL_CALLS) + if (jitFlags->IsSet(JitFlags::JIT_FLAG_GCPOLL_CALLS)) { opts.compGCPollType = GCPOLL_CALL; } - else if (opts.eeFlags & CORJIT_FLG_GCPOLL_INLINE) + else if (jitFlags->IsSet(JitFlags::JIT_FLAG_GCPOLL_INLINE)) { // make sure that the EE didn't set both flags. assert(opts.compGCPollType == GCPOLL_NONE); @@ -3673,12 +3679,9 @@ void Compiler::compInitDebuggingInfo() void Compiler::compSetOptimizationLevel() { - unsigned compileFlags; bool theMinOptsValue; unsigned jitMinOpts; - compileFlags = opts.eeFlags; - if (compIsForInlining()) { theMinOptsValue = impInlineInfo->InlinerCompiler->opts.MinOpts(); @@ -3775,7 +3778,7 @@ void Compiler::compSetOptimizationLevel() } // For PREJIT we never drop down to MinOpts // unless unless CLFLG_MINOPT is set - else if (!(compileFlags & CORJIT_FLG_PREJIT)) + else if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { if ((unsigned)JitConfig.JitMinOptsCodeSize() < info.compILCodeSize) { @@ -3817,7 +3820,7 @@ void Compiler::compSetOptimizationLevel() // Retail check if we should force Minopts due to the complexity of the method // For PREJIT we never drop down to MinOpts // unless unless CLFLG_MINOPT is set - if (!theMinOptsValue && !(compileFlags & CORJIT_FLG_PREJIT) && + if (!theMinOptsValue && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && ((DEFAULT_MIN_OPTS_CODE_SIZE < info.compILCodeSize) || (DEFAULT_MIN_OPTS_INSTR_COUNT < opts.instrCount) || (DEFAULT_MIN_OPTS_BB_COUNT < fgBBcount) || (DEFAULT_MIN_OPTS_LV_NUM_COUNT < lvaCount) || (DEFAULT_MIN_OPTS_LV_REF_COUNT < opts.lvRefCount))) @@ -3895,27 +3898,27 @@ _SetMinOpts: } #if !defined(_TARGET_AMD64_) - // The VM sets CORJIT_FLG_FRAMED for two reasons: (1) the COMPlus_JitFramed variable is set, or + // The VM sets JitFlags::JIT_FLAG_FRAMED for two reasons: (1) the COMPlus_JitFramed variable is set, or // (2) the function is marked "noinline". The reason for #2 is that people mark functions // noinline to ensure the show up on in a stack walk. But for AMD64, we don't need a frame // pointer for the frame to show up in stack walk. - if (compileFlags & CORJIT_FLG_FRAMED) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FRAMED)) codeGen->setFrameRequired(true); #endif - if (compileFlags & CORJIT_FLG_RELOC) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELOC)) { codeGen->genAlignLoops = false; // loop alignment not supported for prejitted code - // The zapper doesn't set CORJIT_FLG_ALIGN_LOOPS, and there is + // The zapper doesn't set JitFlags::JIT_FLAG_ALIGN_LOOPS, and there is // no reason for it to set it as the JIT doesn't currently support loop alignment // for prejitted images. (The JIT doesn't know the final address of the code, hence // it can't align code based on unknown addresses.) - assert((compileFlags & CORJIT_FLG_ALIGN_LOOPS) == 0); + assert(!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALIGN_LOOPS)); } else { - codeGen->genAlignLoops = (compileFlags & CORJIT_FLG_ALIGN_LOOPS) != 0; + codeGen->genAlignLoops = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALIGN_LOOPS); } } @@ -4087,7 +4090,7 @@ void Compiler::compFunctionTraceEnd(void* methodCodePtr, ULONG methodCodeSize, b // For an overview of the structure of the JIT, see: // https://github.com/dotnet/coreclr/blob/master/Documentation/botr/ryujit-overview.md // -void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_FLAGS* compileFlags) +void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags) { if (compIsForInlining()) { @@ -4167,7 +4170,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F fgRemoveEH(); #endif // !FEATURE_EH - if (compileFlags->corJitFlags & CORJIT_FLG_BBINSTR) + if (compileFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR)) { fgInstrumentMethod(); } @@ -4723,7 +4726,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags) + JitFlags* compileFlags) { #ifdef FEATURE_JIT_METHOD_PERF static bool checkedForJitTimeLog = false; @@ -4887,7 +4890,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, // Set this before the first 'BADCODE' // Skip verification where possible - tiVerificationNeeded = (compileFlags->corJitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0; + tiVerificationNeeded = !compileFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION); assert(!compIsForInlining() || !tiVerificationNeeded); // Inlinees must have been verified. @@ -4918,8 +4921,8 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, case CORINFO_VERIFICATION_CAN_SKIP: // The VM should first verify the open instantiation. If unverifiable code - // is detected, it should pass in CORJIT_FLG_SKIP_VERIFICATION. - assert(!"The VM should have used CORJIT_FLG_SKIP_VERIFICATION"); + // is detected, it should pass in JitFlags::JIT_FLAG_SKIP_VERIFICATION. + assert(!"The VM should have used JitFlags::JIT_FLAG_SKIP_VERIFICATION"); tiVerificationNeeded = false; break; @@ -4958,7 +4961,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, CORINFO_METHOD_INFO* methodInfo; void** methodCodePtr; ULONG* methodCodeSize; - CORJIT_FLAGS* compileFlags; + JitFlags* compileFlags; CorInfoInstantiationVerification instVerInfo; int result; @@ -5098,7 +5101,7 @@ void Compiler::compCompileFinish() mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd); unsigned profCallCount = 0; - if (((opts.eeFlags & CORJIT_FLG_BBOPT) != 0) && fgHaveProfileData()) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && fgHaveProfileData()) { assert(fgProfileBuffer[0].ILOffset == 0); profCallCount = fgProfileBuffer[0].ExecutionCount; @@ -5235,7 +5238,7 @@ void Compiler::compCompileFinish() // For ngen the int3 or breakpoint instruction will be right at the // start of the ngen method and we will stop when we execute it. // - if ((opts.eeFlags & CORJIT_FLG_PREJIT) == 0) + if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { if (compJitHaltMethod()) { @@ -5323,7 +5326,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags, + JitFlags* compileFlags, CorInfoInstantiationVerification instVerInfo) { CORINFO_METHOD_HANDLE methodHnd = info.compMethodHnd; @@ -5465,7 +5468,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, info.compIsContextful = (info.compClassAttr & CORINFO_FLG_CONTEXTFUL) != 0; - info.compPublishStubParam = (opts.eeFlags & CORJIT_FLG_PUBLISH_SECRET_PARAM) != 0; + info.compPublishStubParam = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM); switch (methodInfo->args.getCallConv()) { @@ -5503,7 +5506,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, const bool forceInline = !!(info.compFlags & CORINFO_FLG_FORCEINLINE); - if (!compIsForInlining() && (opts.eeFlags & CORJIT_FLG_PREJIT)) + if (!compIsForInlining() && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { // We're prejitting the root method. We also will analyze it as // a potential inline candidate. @@ -6152,7 +6155,7 @@ int jitNativeCode(CORINFO_METHOD_HANDLE methodHnd, CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags, + JitFlags* compileFlags, void* inlineInfoPtr) { // @@ -6206,7 +6209,7 @@ START: CORINFO_METHOD_INFO* methodInfo; void** methodCodePtr; ULONG* methodCodeSize; - CORJIT_FLAGS* compileFlags; + JitFlags* compileFlags; InlineInfo* inlineInfo; #if MEASURE_CLRAPI_CALLS WrapICorJitInfo* wrapCLR; @@ -6326,8 +6329,9 @@ START: jitFallbackCompile = true; // Update the flags for 'safer' code generation. - compileFlags->corJitFlags |= CORJIT_FLG_MIN_OPT; - compileFlags->corJitFlags &= ~(CORJIT_FLG_SIZE_OPT | CORJIT_FLG_SPEED_OPT); + compileFlags->Set(JitFlags::JIT_FLAG_MIN_OPT); + compileFlags->Clear(JitFlags::JIT_FLAG_SIZE_OPT); + compileFlags->Clear(JitFlags::JIT_FLAG_SPEED_OPT); goto START; } diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 2f51c01fe5..b8a6f11f54 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -7434,9 +7434,8 @@ public: struct Options { - CORJIT_FLAGS* jitFlags; // all flags passed from the EE - unsigned eeFlags; // CorJitFlag flags passed from the EE - unsigned compFlags; // method attributes + JitFlags* jitFlags; // all flags passed from the EE + unsigned compFlags; // method attributes codeOptimize compCodeOpt; // what type of code optimizations @@ -7505,7 +7504,7 @@ public: #ifdef FEATURE_READYTORUN_COMPILER inline bool IsReadyToRun() { - return (eeFlags & CORJIT_FLG_READYTORUN) != 0; + return jitFlags->IsSet(JitFlags::JIT_FLAG_READYTORUN); } #else inline bool IsReadyToRun() @@ -7519,7 +7518,7 @@ public: inline bool ShouldUsePInvokeHelpers() { #if COR_JIT_EE_VERSION > 460 - return (jitFlags->corJitFlags2 & CORJIT_FLG2_USE_PINVOKE_HELPERS) != 0; + return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS); #else return false; #endif @@ -7530,7 +7529,7 @@ public: inline bool IsReversePInvoke() { #if COR_JIT_EE_VERSION > 460 - return (jitFlags->corJitFlags2 & CORJIT_FLG2_REVERSE_PINVOKE) != 0; + return jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE); #else return false; #endif @@ -7540,7 +7539,7 @@ public: inline bool IsJit32Compat() { #if defined(_TARGET_X86_) && COR_JIT_EE_VERSION > 460 - return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0; + return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS); #else return false; #endif @@ -7550,7 +7549,7 @@ public: inline bool IsJit64Compat() { #if defined(_TARGET_AMD64_) && COR_JIT_EE_VERSION > 460 - return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0; + return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS); #elif defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) return true; #else @@ -8095,14 +8094,14 @@ public: CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags); + JitFlags* compileFlags); void compCompileFinish(); int compCompileHelper(CORINFO_MODULE_HANDLE classPtr, COMP_HANDLE compHnd, CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags, + JitFlags* compileFlags, CorInfoInstantiationVerification instVerInfo); ArenaAllocator* compGetAllocator(); @@ -8335,7 +8334,7 @@ public: protected: size_t compMaxUncheckedOffsetForNullObject; - void compInitOptions(CORJIT_FLAGS* compileFlags); + void compInitOptions(JitFlags* compileFlags); void compSetProcessor(); void compInitDebuggingInfo(); @@ -8343,7 +8342,7 @@ protected: #ifdef _TARGET_ARMARCH_ bool compRsvdRegCheck(FrameLayoutState curState); #endif - void compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_FLAGS* compileFlags); + void compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags); #ifdef PROFILING_SUPPORTED // Data required for generating profiler Enter/Leave/TailCall hooks diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp index d06e31986b..704cf18125 100644 --- a/src/jit/compiler.hpp +++ b/src/jit/compiler.hpp @@ -4108,7 +4108,7 @@ inline bool Compiler::compIsProfilerHookNeeded() return compProfilerHookNeeded // IL stubs are excluded by VM and we need to do the same even running // under a complus env hook to generate profiler hooks - || (opts.compJitELTHookEnabled && !(opts.eeFlags & CORJIT_FLG_IL_STUB)); + || (opts.compJitELTHookEnabled && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)); #else // !PROFILING_SUPPORTED return false; #endif // !PROFILING_SUPPORTED @@ -4200,7 +4200,7 @@ inline bool Compiler::impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart, inline bool Compiler::compIsForImportOnly() { - return ((opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0); + return opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY); } /***************************************************************************** diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp index 59f9a954cd..1b46974141 100755..100644 --- a/src/jit/ee_il_dll.cpp +++ b/src/jit/ee_il_dll.cpp @@ -284,21 +284,17 @@ CorJitResult CILJit::compileMethod( return g_realJitCompiler->compileMethod(compHnd, methodInfo, flags, entryAddress, nativeSizeOfCode); } - CORJIT_FLAGS jitFlags = {0}; + JitFlags jitFlags; - DWORD jitFlagsSize = 0; #if COR_JIT_EE_VERSION > 460 - if (flags == CORJIT_FLG_CALL_GETJITFLAGS) - { - jitFlagsSize = compHnd->getJitFlags(&jitFlags, sizeof(jitFlags)); - } -#endif - - assert(jitFlagsSize <= sizeof(jitFlags)); - if (jitFlagsSize == 0) - { - jitFlags.corJitFlags = flags; - } + assert(flags == CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS); + CORJIT_FLAGS corJitFlags; + DWORD jitFlagsSize = compHnd->getJitFlags(&corJitFlags, sizeof(corJitFlags)); + assert(jitFlagsSize == sizeof(corJitFlags)); + jitFlags.SetFromFlags(corJitFlags); +#else // COR_JIT_EE_VERSION <= 460 + jitFlags.SetFromOldFlags(flags, 0); +#endif // COR_JIT_EE_VERSION <= 460 int result; void* methodCodePtr = nullptr; @@ -385,17 +381,30 @@ void CILJit::getVersionIdentifier(GUID* versionIdentifier) /***************************************************************************** * Determine the maximum length of SIMD vector supported by this JIT. */ + +#if COR_JIT_EE_VERSION > 460 +unsigned CILJit::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) +#else unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) +#endif { if (g_realJitCompiler != nullptr) { return g_realJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); } + JitFlags jitFlags; + +#if COR_JIT_EE_VERSION > 460 + jitFlags.SetFromFlags(cpuCompileFlags); +#else // COR_JIT_EE_VERSION <= 460 + jitFlags.SetFromOldFlags(cpuCompileFlags, 0); +#endif // COR_JIT_EE_VERSION <= 460 + #ifdef _TARGET_AMD64_ #ifdef FEATURE_AVX_SUPPORT - if (((cpuCompileFlags & CORJIT_FLG_PREJIT) == 0) && ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) && - ((cpuCompileFlags & CORJIT_FLG_USE_AVX2) != 0)) + if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_FEATURE_SIMD) && + jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2)) { if (JitConfig.EnableAVX() != 0) { diff --git a/src/jit/ee_il_dll.hpp b/src/jit/ee_il_dll.hpp index d9bf95fde8..3899d92192 100644 --- a/src/jit/ee_il_dll.hpp +++ b/src/jit/ee_il_dll.hpp @@ -21,7 +21,11 @@ class CILJit : public ICorJitCompiler void getVersionIdentifier(GUID* versionIdentifier /* OUT */ ); +#if COR_JIT_EE_VERSION > 460 + unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); +#else unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags); +#endif void setRealJit(ICorJitCompiler* realJitCompiler); }; diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp index 5d58d1a108..d93f505d96 100644 --- a/src/jit/emit.cpp +++ b/src/jit/emit.cpp @@ -1264,9 +1264,9 @@ void* emitter::emitAllocInstr(size_t sz, emitAttr opsz) // ARM - This is currently broken on _TARGET_ARM_ // When nopSize is odd we misalign emitCurIGsize // - if (!(emitComp->opts.eeFlags & CORJIT_FLG_PREJIT) && !emitInInstrumentation && - !emitIGisInProlog(emitCurIG) // don't do this in prolog or epilog - && !emitIGisInEpilog(emitCurIG) && + if (!emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && !emitInInstrumentation && + !emitIGisInProlog(emitCurIG) && // don't do this in prolog or epilog + !emitIGisInEpilog(emitCurIG) && emitRandomNops // sometimes we turn off where exact codegen is needed (pinvoke inline) ) { diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index b8a46a7ca8..2d5b9756db 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -6654,7 +6654,7 @@ void Compiler::fgImport() impImport(fgFirstBB); - if (!(opts.eeFlags & CORJIT_FLG_SKIP_VERIFICATION)) + if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION)) { CorInfoMethodRuntimeFlags verFlag; verFlag = tiIsVerifiableCode ? CORINFO_FLG_VERIFIABLE : CORINFO_FLG_UNVERIFIABLE; @@ -8289,7 +8289,7 @@ void Compiler::fgAddInternal() CORINFO_JUST_MY_CODE_HANDLE* pDbgHandle = nullptr; CORINFO_JUST_MY_CODE_HANDLE dbgHandle = nullptr; - if (opts.compDbgCode && !(opts.eeFlags & CORJIT_FLG_IL_STUB)) + if (opts.compDbgCode && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)) { dbgHandle = info.compCompHnd->getJustMyCodeHandle(info.compMethodHnd, &pDbgHandle); } @@ -14019,7 +14019,7 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump) // we are willing to have more code expansion since we // won't be running code from this page // - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { if (rareJump) { @@ -18661,7 +18661,7 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas bool createDuplicateFgxFiles = true; #ifdef DEBUG - if (opts.eeFlags & CORJIT_FLG_PREJIT) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { pattern = JitConfig.NgenDumpFg(); filename = JitConfig.NgenDumpFgFile(); @@ -21504,10 +21504,17 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, pParam->pThis->eeGetMethodFullName(pParam->fncHandle), pParam->pThis->dspPtr(pParam->inlineInfo->tokenLookupContextHandle))); - CORJIT_FLAGS compileFlagsForInlinee; - memcpy(&compileFlagsForInlinee, pParam->pThis->opts.jitFlags, sizeof(compileFlagsForInlinee)); - compileFlagsForInlinee.corJitFlags &= ~CORJIT_FLG_LOST_WHEN_INLINING; - compileFlagsForInlinee.corJitFlags |= CORJIT_FLG_SKIP_VERIFICATION; + JitFlags compileFlagsForInlinee = *pParam->pThis->opts.jitFlags; + + // The following flags are lost when inlining. + // (This is checked in Compiler::compInitOptions().) + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_BBOPT); + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_BBINSTR); + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_PROF_ENTERLEAVE); + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_EnC); + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_INFO); + + compileFlagsForInlinee.Set(JitFlags::JIT_FLAG_SKIP_VERIFICATION); #ifdef DEBUG if (pParam->pThis->verbose) diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index ed75bc35d1..d1e48f0e80 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -5488,7 +5488,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) costSz += 2; } } - else if ((opts.eeFlags & CORJIT_FLG_PREJIT) == 0) + else if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) { costEx += 2; costSz += 6; diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 742d998f3a..a6e6735fc8 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -3910,7 +3910,7 @@ void Compiler::verHandleVerificationFailure(BasicBlock* block DEBUGARG(bool logM #endif // DEBUG // Add the non verifiable flag to the compiler - if ((opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0) + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY)) { tiIsVerifiableCode = FALSE; } @@ -16527,7 +16527,7 @@ void Compiler::impImport(BasicBlock* method) // coupled with the JIT64 IL Verification logic. Look inside verHandleVerificationFailure // method for further explanation on why we raise this exception instead of making the jitted // code throw the verification exception during execution. - if (tiVerificationNeeded && (opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0) + if (tiVerificationNeeded && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY)) { BADCODE("Basic block marked as not verifiable"); } diff --git a/src/jit/inline.cpp b/src/jit/inline.cpp index deccc0e84b..7bba50c669 100644 --- a/src/jit/inline.cpp +++ b/src/jit/inline.cpp @@ -1354,7 +1354,7 @@ void InlineStrategy::DumpDataEnsurePolicyIsSet() // successful policy, so fake one up. if (m_LastSuccessfulPolicy == nullptr) { - const bool isPrejitRoot = (opts.eeFlags & CORJIT_FLG_PREJIT) != 0; + const bool isPrejitRoot = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT); m_LastSuccessfulPolicy = InlinePolicy::GetPolicy(m_Compiler, isPrejitRoot); // Add in a bit of data.... @@ -1484,7 +1484,7 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent) const Compiler::Info& info = m_Compiler->info; const Compiler::Options& opts = m_Compiler->opts; - const bool isPrejitRoot = (opts.eeFlags & CORJIT_FLG_PREJIT) != 0; + const bool isPrejitRoot = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT); const bool isForceInline = (info.compFlags & CORINFO_FLG_FORCEINLINE) != 0; // We'd really like the method identifier to be unique and diff --git a/src/jit/inline.h b/src/jit/inline.h index e3d5750754..9d625c729c 100644 --- a/src/jit/inline.h +++ b/src/jit/inline.h @@ -85,11 +85,6 @@ const unsigned int MAX_INL_ARGS = 10; // does not include obj pointer const unsigned int MAX_INL_LCLS = 8; #endif // LEGACY_BACKEND -// Flags lost during inlining. - -#define CORJIT_FLG_LOST_WHEN_INLINING \ - (CORJIT_FLG_BBOPT | CORJIT_FLG_BBINSTR | CORJIT_FLG_PROF_ENTERLEAVE | CORJIT_FLG_DEBUG_EnC | CORJIT_FLG_DEBUG_INFO) - // Forward declarations class InlineStrategy; diff --git a/src/jit/instr.cpp b/src/jit/instr.cpp index d516e0dea4..1b75e81172 100644 --- a/src/jit/instr.cpp +++ b/src/jit/instr.cpp @@ -3054,7 +3054,7 @@ bool CodeGenInterface::validImmForBL(ssize_t addr) return // If we are running the altjit for NGEN, then assume we can use the "BL" instruction. // This matches the usual behavior for NGEN, since we normally do generate "BL". - (!compiler->info.compMatchedVM && (compiler->opts.eeFlags & CORJIT_FLG_PREJIT)) || + (!compiler->info.compMatchedVM && compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) || (compiler->eeGetRelocTypeHint((void*)addr) == IMAGE_REL_BASED_THUMB_BRANCH24); } bool CodeGen::arm_Valid_Imm_For_BL(ssize_t addr) diff --git a/src/jit/jit.h b/src/jit/jit.h index 5775e4fa3a..220294f825 100644 --- a/src/jit/jit.h +++ b/src/jit/jit.h @@ -210,6 +210,7 @@ #include "corhdr.h" #include "corjit.h" +#include "jitee.h" #define __OPERATOR_NEW_INLINE 1 // indicate that I will define these #define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake @@ -829,7 +830,7 @@ extern int jitNativeCode(CORINFO_METHOD_HANDLE methodHnd, CORINFO_METHOD_INFO* methodInfo, void** methodCodePtr, ULONG* methodCodeSize, - CORJIT_FLAGS* compileFlags, + JitFlags* compileFlags, void* inlineInfoPtr); #ifdef _HOST_64BIT_ diff --git a/src/jit/jitee.h b/src/jit/jitee.h new file mode 100644 index 0000000000..772813f083 --- /dev/null +++ b/src/jit/jitee.h @@ -0,0 +1,264 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// This class wraps the CORJIT_FLAGS type in the JIT-EE interface (in corjit.h) such that the JIT can +// build with either the old flags (COR_JIT_EE_VERSION <= 460) or the new flags (COR_JIT_EE_VERSION > 460). +// It actually is exactly the same as the new definition, and must be kept up-to-date with the new definition. +// When built against an old JIT-EE interface, the old flags are converted into this structure. +class JitFlags +{ +public: + // clang-format off + enum JitFlag + { + JIT_FLAG_SPEED_OPT = 0, + JIT_FLAG_SIZE_OPT = 1, + JIT_FLAG_DEBUG_CODE = 2, // generate "debuggable" code (no code-mangling optimizations) + JIT_FLAG_DEBUG_EnC = 3, // We are in Edit-n-Continue mode + JIT_FLAG_DEBUG_INFO = 4, // generate line and local-var info + JIT_FLAG_MIN_OPT = 5, // disable all jit optimizations (not necesarily debuggable code) + JIT_FLAG_GCPOLL_CALLS = 6, // Emit calls to JIT_POLLGC for thread suspension. + JIT_FLAG_MCJIT_BACKGROUND = 7, // Calling from multicore JIT background thread, do not call JitComplete + + #if defined(_TARGET_X86_) + + JIT_FLAG_PINVOKE_RESTORE_ESP = 8, // Restore ESP after returning from inlined PInvoke + JIT_FLAG_TARGET_P4 = 9, + JIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction + JIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction + JIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions + + #else // !defined(_TARGET_X86_) + + JIT_FLAG_UNUSED1 = 8, + JIT_FLAG_UNUSED2 = 9, + JIT_FLAG_UNUSED3 = 10, + JIT_FLAG_UNUSED4 = 11, + JIT_FLAG_UNUSED5 = 12, + + #endif // !defined(_TARGET_X86_) + + #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) + + JIT_FLAG_USE_SSE3_4 = 13, + JIT_FLAG_USE_AVX = 14, + JIT_FLAG_USE_AVX2 = 15, + JIT_FLAG_USE_AVX_512 = 16, + JIT_FLAG_FEATURE_SIMD = 17, + + #else // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) + + JIT_FLAG_UNUSED6 = 13, + JIT_FLAG_UNUSED7 = 14, + JIT_FLAG_UNUSED8 = 15, + JIT_FLAG_UNUSED9 = 16, + JIT_FLAG_UNUSED10 = 17, + + #endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) + + JIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. + JIT_FLAG_READYTORUN = 19, // Use version-resilient code generation + JIT_FLAG_PROF_ENTERLEAVE = 20, // Instrument prologues/epilogues + JIT_FLAG_PROF_REJIT_NOPS = 21, // Insert NOPs to ensure code is re-jitable + JIT_FLAG_PROF_NO_PINVOKE_INLINE = 22, // Disables PInvoke inlining + JIT_FLAG_SKIP_VERIFICATION = 23, // (lazy) skip verification - determined without doing a full resolve. See comment below + JIT_FLAG_PREJIT = 24, // jit or prejit is the execution engine. + JIT_FLAG_RELOC = 25, // Generate relocatable code + JIT_FLAG_IMPORT_ONLY = 26, // Only import the function + JIT_FLAG_IL_STUB = 27, // method is an IL stub + JIT_FLAG_PROCSPLIT = 28, // JIT should separate code into hot and cold sections + JIT_FLAG_BBINSTR = 29, // Collect basic block profile information + JIT_FLAG_BBOPT = 30, // Optimize method based on profile information + JIT_FLAG_FRAMED = 31, // All methods have an EBP frame + JIT_FLAG_ALIGN_LOOPS = 32, // add NOPs before loops to align them at 16 byte boundaries + JIT_FLAG_PUBLISH_SECRET_PARAM = 33, // JIT must place stub secret param into local 0. (used by IL stubs) + JIT_FLAG_GCPOLL_INLINE = 34, // JIT must inline calls to GCPoll when possible + JIT_FLAG_SAMPLING_JIT_BACKGROUND = 35, // JIT is being invoked as a result of stack sampling for hot methods in the background + JIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions + JIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog + JIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code + }; + // clang-format on + + JitFlags() : m_jitFlags(0) + { + // empty + } + + // Convenience constructor to set exactly one flags. + JitFlags(JitFlag flag) : m_jitFlags(0) + { + Set(flag); + } + + void Reset() + { + m_jitFlags = 0; + } + + void Set(JitFlag flag) + { + m_jitFlags |= 1ULL << (unsigned __int64)flag; + } + + void Clear(JitFlag flag) + { + m_jitFlags &= ~(1ULL << (unsigned __int64)flag); + } + + bool IsSet(JitFlag flag) const + { + return (m_jitFlags & (1ULL << (unsigned __int64)flag)) != 0; + } + + void Add(const JitFlags& other) + { + m_jitFlags |= other.m_jitFlags; + } + + void Remove(const JitFlags& other) + { + m_jitFlags &= ~other.m_jitFlags; + } + + bool IsEmpty() const + { + return m_jitFlags == 0; + } + +#if COR_JIT_EE_VERSION <= 460 + + void SetFromOldFlags(unsigned corJitFlags, unsigned corJitFlags2) + { + Reset(); + +#define CONVERT_OLD_FLAG(oldf, newf) \ + if ((corJitFlags & (oldf)) != 0) \ + this->Set(JitFlags::newf); +#define CONVERT_OLD_FLAG2(oldf, newf) \ + if ((corJitFlags & (oldf)) != 0) \ + this->Set(JitFlags::newf); + + CONVERT_OLD_FLAG(CORJIT_FLG_SPEED_OPT, JIT_FLAG_SPEED_OPT) + CONVERT_OLD_FLAG(CORJIT_FLG_SIZE_OPT, JIT_FLAG_SIZE_OPT) + CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_CODE, JIT_FLAG_DEBUG_CODE) + CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_EnC, JIT_FLAG_DEBUG_EnC) + CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_INFO, JIT_FLAG_DEBUG_INFO) + CONVERT_OLD_FLAG(CORJIT_FLG_MIN_OPT, JIT_FLAG_MIN_OPT) + CONVERT_OLD_FLAG(CORJIT_FLG_GCPOLL_CALLS, JIT_FLAG_GCPOLL_CALLS) + CONVERT_OLD_FLAG(CORJIT_FLG_MCJIT_BACKGROUND, JIT_FLAG_MCJIT_BACKGROUND) + +#if defined(_TARGET_X86_) + + CONVERT_OLD_FLAG(CORJIT_FLG_PINVOKE_RESTORE_ESP, JIT_FLAG_PINVOKE_RESTORE_ESP) + CONVERT_OLD_FLAG(CORJIT_FLG_TARGET_P4, JIT_FLAG_TARGET_P4) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_FCOMI, JIT_FLAG_USE_FCOMI) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_CMOV, JIT_FLAG_USE_CMOV) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_SSE2, JIT_FLAG_USE_SSE2) + +#elif defined(_TARGET_AMD64_) + + CONVERT_OLD_FLAG(CORJIT_FLG_USE_SSE3_4, JIT_FLAG_USE_SSE3_4) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX, JIT_FLAG_USE_AVX) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX2, JIT_FLAG_USE_AVX2) + CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX_512, JIT_FLAG_USE_AVX_512) + CONVERT_OLD_FLAG(CORJIT_FLG_FEATURE_SIMD, JIT_FLAG_FEATURE_SIMD) + +#endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) + + CONVERT_OLD_FLAG(CORJIT_FLG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE) + CONVERT_OLD_FLAG(CORJIT_FLG_READYTORUN, JIT_FLAG_READYTORUN) + CONVERT_OLD_FLAG(CORJIT_FLG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE) + CONVERT_OLD_FLAG(CORJIT_FLG_PROF_REJIT_NOPS, JIT_FLAG_PROF_REJIT_NOPS) + CONVERT_OLD_FLAG(CORJIT_FLG_PROF_NO_PINVOKE_INLINE, JIT_FLAG_PROF_NO_PINVOKE_INLINE) + CONVERT_OLD_FLAG(CORJIT_FLG_SKIP_VERIFICATION, JIT_FLAG_SKIP_VERIFICATION) + CONVERT_OLD_FLAG(CORJIT_FLG_PREJIT, JIT_FLAG_PREJIT) + CONVERT_OLD_FLAG(CORJIT_FLG_RELOC, JIT_FLAG_RELOC) + CONVERT_OLD_FLAG(CORJIT_FLG_IMPORT_ONLY, JIT_FLAG_IMPORT_ONLY) + CONVERT_OLD_FLAG(CORJIT_FLG_IL_STUB, JIT_FLAG_IL_STUB) + CONVERT_OLD_FLAG(CORJIT_FLG_PROCSPLIT, JIT_FLAG_PROCSPLIT) + CONVERT_OLD_FLAG(CORJIT_FLG_BBINSTR, JIT_FLAG_BBINSTR) + CONVERT_OLD_FLAG(CORJIT_FLG_BBOPT, JIT_FLAG_BBOPT) + CONVERT_OLD_FLAG(CORJIT_FLG_FRAMED, JIT_FLAG_FRAMED) + CONVERT_OLD_FLAG(CORJIT_FLG_ALIGN_LOOPS, JIT_FLAG_ALIGN_LOOPS) + CONVERT_OLD_FLAG(CORJIT_FLG_PUBLISH_SECRET_PARAM, JIT_FLAG_PUBLISH_SECRET_PARAM) + CONVERT_OLD_FLAG(CORJIT_FLG_GCPOLL_INLINE, JIT_FLAG_GCPOLL_INLINE) + + CONVERT_OLD_FLAG2(CORJIT_FLG2_SAMPLING_JIT_BACKGROUND, JIT_FLAG_SAMPLING_JIT_BACKGROUND) + +#undef CONVERT_OLD_FLAG +#undef CONVERT_OLD_FLAG2 + } + +#else // COR_JIT_EE_VERSION > 460 + + void SetFromFlags(CORJIT_FLAGS flags) + { + // We don't want to have to check every one, so we assume it is exactly the same values as the JitFlag + // values defined in this type. + m_jitFlags = flags.GetFlagsRaw(); + + C_ASSERT(sizeof(m_jitFlags) == sizeof(CORJIT_FLAGS)); + +#define FLAGS_EQUAL(a, b) C_ASSERT((unsigned)(a) == (unsigned)(b)) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT, JIT_FLAG_SPEED_OPT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT, JIT_FLAG_SIZE_OPT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE, JIT_FLAG_DEBUG_CODE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC, JIT_FLAG_DEBUG_EnC); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO, JIT_FLAG_DEBUG_INFO); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT, JIT_FLAG_MIN_OPT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS, JIT_FLAG_GCPOLL_CALLS); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND, JIT_FLAG_MCJIT_BACKGROUND); + +#if defined(_TARGET_X86_) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PINVOKE_RESTORE_ESP, JIT_FLAG_PINVOKE_RESTORE_ESP); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4, JIT_FLAG_TARGET_P4); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI, JIT_FLAG_USE_FCOMI); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV, JIT_FLAG_USE_CMOV); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2, JIT_FLAG_USE_SSE2); + +#endif + +#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3_4, JIT_FLAG_USE_SSE3_4); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX, JIT_FLAG_USE_AVX); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2, JIT_FLAG_USE_AVX2); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX_512, JIT_FLAG_USE_AVX_512); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD, JIT_FLAG_FEATURE_SIMD); + +#endif + + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN, JIT_FLAG_READYTORUN); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS, JIT_FLAG_PROF_REJIT_NOPS); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE, JIT_FLAG_PROF_NO_PINVOKE_INLINE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION, JIT_FLAG_SKIP_VERIFICATION); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PREJIT, JIT_FLAG_PREJIT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_RELOC, JIT_FLAG_RELOC); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY, JIT_FLAG_IMPORT_ONLY); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB, JIT_FLAG_IL_STUB); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT, JIT_FLAG_PROCSPLIT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR, JIT_FLAG_BBINSTR); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_BBOPT, JIT_FLAG_BBOPT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FRAMED, JIT_FLAG_FRAMED); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALIGN_LOOPS, JIT_FLAG_ALIGN_LOOPS); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM, JIT_FLAG_PUBLISH_SECRET_PARAM); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE, JIT_FLAG_GCPOLL_INLINE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND, JIT_FLAG_SAMPLING_JIT_BACKGROUND); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_PINVOKE_HELPERS, JIT_FLAG_USE_PINVOKE_HELPERS); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE, JIT_FLAG_REVERSE_PINVOKE); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS, JIT_FLAG_DESKTOP_QUIRKS); + +#undef FLAGS_EQUAL + } + +#endif // COR_JIT_EE_VERSION > 460 + +private: + unsigned __int64 m_jitFlags; +}; diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index dbe4b5de80..f5a7e2c089 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -2638,7 +2638,7 @@ void Lowering::InsertPInvokeMethodProlog() CLANG_FORMAT_COMMENT_ANCHOR; #ifdef _TARGET_64BIT_ - if (comp->opts.eeFlags & CORJIT_FLG_IL_STUB) + if (comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)) { // Push a frame - if we are NOT in an IL stub, this is done right before the call // The init routine sets InlinedCallFrame's m_pNext, so we just set the thead's top-of-stack @@ -2714,7 +2714,7 @@ void Lowering::InsertPInvokeMethodEpilog(BasicBlock* returnBB DEBUGARG(GenTreePt CLANG_FORMAT_COMMENT_ANCHOR; #ifdef _TARGET_64BIT_ - if (comp->opts.eeFlags & CORJIT_FLG_IL_STUB) + if (comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)) #endif // _TARGET_64BIT_ { GenTree* frameUpd = CreateFrameLinkUpdate(PopFrame); @@ -2857,7 +2857,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call) CLANG_FORMAT_COMMENT_ANCHOR; #ifdef _TARGET_64BIT_ - if (!(comp->opts.eeFlags & CORJIT_FLG_IL_STUB)) + if (!comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)) { // Set the TCB's frame to be the one we just created. // Note the init routine for the InlinedCallFrame (CORINFO_HELP_INIT_PINVOKE_FRAME) @@ -2925,7 +2925,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call) CLANG_FORMAT_COMMENT_ANCHOR; #ifdef _TARGET_64BIT_ - if (!(comp->opts.eeFlags & CORJIT_FLG_IL_STUB)) + if (!comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB)) { tree = CreateFrameLinkUpdate(PopFrame); BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree)); @@ -2945,7 +2945,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call) GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call) { // PInvoke lowering varies depending on the flags passed in by the EE. By default, - // GC transitions are generated inline; if CORJIT_FLG2_USE_PINVOKE_HELPERS is specified, + // GC transitions are generated inline; if CORJIT_FLAG_USE_PINVOKE_HELPERS is specified, // GC transitions are instead performed using helper calls. Examples of each case are given // below. Note that the data structure that is used to store information about a call frame // containing any P/Invoke calls is initialized in the method prolog (see diff --git a/src/jit/simdcodegenxarch.cpp b/src/jit/simdcodegenxarch.cpp index 94e6d4595c..08de93d837 100644 --- a/src/jit/simdcodegenxarch.cpp +++ b/src/jit/simdcodegenxarch.cpp @@ -62,7 +62,7 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type // AVX supports broadcast instructions to populate YMM reg with a single float/double value from memory. // AVX2 supports broadcast instructions to populate YMM reg with a single value from memory or mm reg. // If we decide to use AVX2 only, we can remove this assert. - if ((compiler->opts.eeFlags & CORJIT_FLG_USE_AVX2) == 0) + if (!compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_USE_AVX2)) { assert(baseType == TYP_FLOAT || baseType == TYP_DOUBLE); } diff --git a/src/jit/target.h b/src/jit/target.h index 867dc25cde..d95962b0be 100644 --- a/src/jit/target.h +++ b/src/jit/target.h @@ -584,7 +584,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits #define REG_PINVOKE_TARGET_PARAM REG_EAX #define RBM_PINVOKE_TARGET_PARAM RBM_EAX - // IL stub's secret parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM) + // IL stub's secret parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM) #define REG_SECRET_STUB_PARAM REG_EAX #define RBM_SECRET_STUB_PARAM RBM_EAX @@ -977,7 +977,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits #define RBM_PINVOKE_TARGET_PARAM RBM_R10 #define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R10 - // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM) + // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM) #define REG_SECRET_STUB_PARAM REG_R10 #define RBM_SECRET_STUB_PARAM RBM_R10 @@ -1349,7 +1349,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits #define RBM_PINVOKE_TARGET_PARAM RBM_R12 #define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R12 - // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM) + // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM) #define REG_SECRET_STUB_PARAM REG_R12 #define RBM_SECRET_STUB_PARAM RBM_R12 @@ -1630,7 +1630,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits #define RBM_PINVOKE_TARGET_PARAM RBM_R14 #define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R14 - // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM) + // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM) #define REG_SECRET_STUB_PARAM REG_R12 #define RBM_SECRET_STUB_PARAM RBM_R12 diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 80fc617d0e..feb9f85607 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -15911,9 +15911,9 @@ void Module::ExpandAll() pMD->GetMDImport(), &ignored)); #ifdef FEATURE_INTERPRETER - pMD->MakeJitWorker(pHeader, CORJIT_FLG_MAKEFINALCODE, 0); + pMD->MakeJitWorker(pHeader, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)); #else - pMD->MakeJitWorker(pHeader, 0, 0); + pMD->MakeJitWorker(pHeader, CORJIT_FLAGS()); #endif } } diff --git a/src/vm/cgensys.h b/src/vm/cgensys.h index 205d8a223e..fb5c087c5c 100644 --- a/src/vm/cgensys.h +++ b/src/vm/cgensys.h @@ -103,21 +103,21 @@ inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo) #endif // !_TARGET_X86_ -#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) +#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); -#endif // defined(_TARGET_AMD64_) +#endif inline bool TargetHasAVXSupport() { -#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) +#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) unsigned char buffer[16]; - // All AMD64 targets support cpuid. + // All x86/AMD64 targets support cpuid. (void) getcpuid(1, buffer); // getcpuid executes cpuid with eax set to its first argument, and ecx cleared. // It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[]. // The AVX feature is ECX bit 28. return ((buffer[11] & 0x10) != 0); -#endif // defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) +#endif // (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) return false; } diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index 444dcf4fef..9d7d8d0e1b 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -1187,6 +1187,7 @@ EEJitManager::EEJitManager() // CRST_TAKEN_DURING_SHUTDOWN - We take this lock during shutdown if ETW is on (to do rundown) m_CodeHeapCritSec( CrstSingleUseLock, CrstFlags(CRST_UNSAFE_ANYMODE|CRST_DEBUGGER_THREAD|CRST_TAKEN_DURING_SHUTDOWN)), + m_CPUCompileFlags(), m_EHClauseCritSec( CrstSingleUseLock ) { CONTRACTL { @@ -1211,17 +1212,17 @@ EEJitManager::EEJitManager() m_AltJITRequired = false; #endif - m_dwCPUCompileFlags = 0; - m_cleanupList = NULL; } -#if defined(_TARGET_AMD64_) +#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); extern "C" DWORD __stdcall xmmYmmStateSupport(); bool DoesOSSupportAVX() { + LIMITED_METHOD_CONTRACT; + #ifndef FEATURE_PAL // On Windows we have an api(GetEnabledXStateFeatures) to check if AVX is supported typedef DWORD64 (WINAPI *PGETENABLEDXSTATEFEATURES)(); @@ -1255,7 +1256,7 @@ bool DoesOSSupportAVX() return TRUE; } -#endif // defined(_TARGET_AMD64_) +#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_) void EEJitManager::SetCpuInfo() { @@ -1265,7 +1266,7 @@ void EEJitManager::SetCpuInfo() // NOTE: This function needs to be kept in sync with Zapper::CompileAssembly() // - DWORD dwCPUCompileFlags = 0; + CORJIT_FLAGS CPUCompileFlags; #if defined(_TARGET_X86_) // NOTE: if you're adding any flags here, you probably should also be doing it @@ -1276,7 +1277,7 @@ void EEJitManager::SetCpuInfo() switch (CPU_X86_FAMILY(cpuInfo.dwCPUType)) { case CPU_X86_PENTIUM_4: - dwCPUCompileFlags |= CORJIT_FLG_TARGET_P4; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4); break; default: break; @@ -1284,15 +1285,17 @@ void EEJitManager::SetCpuInfo() if (CPU_X86_USE_CMOV(cpuInfo.dwFeatures)) { - dwCPUCompileFlags |= CORJIT_FLG_USE_CMOV | - CORJIT_FLG_USE_FCOMI; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV); + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI); } if (CPU_X86_USE_SSE2(cpuInfo.dwFeatures)) { - dwCPUCompileFlags |= CORJIT_FLG_USE_SSE2; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2); } -#elif defined(_TARGET_AMD64_) +#endif // _TARGET_X86_ + +#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) unsigned char buffer[16]; DWORD maxCpuId = getcpuid(0, buffer); if (maxCpuId >= 0) @@ -1301,17 +1304,17 @@ void EEJitManager::SetCpuInfo() // It returns the resulting eax in buffer[0-3], ebx in buffer[4-7], ecx in buffer[8-11], // and edx in buffer[12-15]. // We will set the following flags: - // CORJIT_FLG_USE_SSE3_4 if the following feature bits are set (input EAX of 1) + // CORJIT_FLAG_USE_SSE3_4 if the following feature bits are set (input EAX of 1) // SSE3 - ECX bit 0 (buffer[8] & 0x01) // SSSE3 - ECX bit 9 (buffer[9] & 0x02) // SSE4.1 - ECX bit 19 (buffer[10] & 0x08) // SSE4.2 - ECX bit 20 (buffer[10] & 0x10) - // CORJIT_FLG_USE_AVX if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1: + // CORJIT_FLAG_USE_AVX if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1: // OSXSAVE - ECX bit 27 (buffer[11] & 0x08) // AVX - ECX bit 28 (buffer[11] & 0x10) - // CORJIT_FLG_USE_AVX2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): + // CORJIT_FLAG_USE_AVX2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0): // AVX2 - EBX bit 5 (buffer[4] & 0x20) - // CORJIT_FLG_USE_AVX_512 is not currently set, but defined so that it can be used in future without + // CORJIT_FLAG_USE_AVX_512 is not currently set, but defined so that it can be used in future without // synchronously updating VM and JIT. (void) getcpuid(1, buffer); // If SSE2 is not enabled, there is no point in checking the rest. @@ -1324,7 +1327,7 @@ void EEJitManager::SetCpuInfo() ((buffer[10] & 0x08) != 0) && // SSE4.1 ((buffer[10] & 0x10) != 0)) // SSE4.2 { - dwCPUCompileFlags |= CORJIT_FLG_USE_SSE3_4; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3_4); } if ((buffer[11] & 0x18) == 0x18) { @@ -1332,13 +1335,13 @@ void EEJitManager::SetCpuInfo() { if (xmmYmmStateSupport() == 1) { - dwCPUCompileFlags |= CORJIT_FLG_USE_AVX; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX); if (maxCpuId >= 0x07) { (void) getcpuid(0x07, buffer); if ((buffer[4] & 0x20) != 0) { - dwCPUCompileFlags |= CORJIT_FLG_USE_AVX2; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2); } } } @@ -1347,13 +1350,13 @@ void EEJitManager::SetCpuInfo() static ConfigDWORD fFeatureSIMD; if (fFeatureSIMD.val(CLRConfig::EXTERNAL_FeatureSIMD) != 0) { - dwCPUCompileFlags |= CORJIT_FLG_FEATURE_SIMD; + CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD); } } } -#endif // defined(_TARGET_AMD64_) +#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_) - m_dwCPUCompileFlags = dwCPUCompileFlags; + m_CPUCompileFlags = CPUCompileFlags; } // Define some data that we can use to get a better idea of what happened when we get a Watson dump that indicates the JIT failed to load. diff --git a/src/vm/codeman.h b/src/vm/codeman.h index f4e04b8c67..0fe261a92f 100644 --- a/src/vm/codeman.h +++ b/src/vm/codeman.h @@ -1146,17 +1146,17 @@ public: #endif // !DACCESS_COMPILE private: - DWORD m_dwCPUCompileFlags; + CORJIT_FLAGS m_CPUCompileFlags; #if !defined CROSSGEN_COMPILE && !defined DACCESS_COMPILE void SetCpuInfo(); #endif public: - inline DWORD GetCPUCompileFlags() + inline CORJIT_FLAGS GetCPUCompileFlags() { LIMITED_METHOD_CONTRACT; - return m_dwCPUCompileFlags; + return m_CPUCompileFlags; } private : diff --git a/src/vm/commethodrental.cpp b/src/vm/commethodrental.cpp index 0faf470a2a..0a5c011270 100644 --- a/src/vm/commethodrental.cpp +++ b/src/vm/commethodrental.cpp @@ -102,9 +102,9 @@ void QCALLTYPE COMMethodRental::SwapMethodBody(EnregisteredTypeHandle cls, INT32 COMPlusThrowHR(VLDTR_E_MD_BADHEADER); #ifdef FEATURE_INTERPRETER - pMethodDesc->MakeJitWorker(&header, CORJIT_FLG_MAKEFINALCODE, 0); + pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)); #else // !FEATURE_INTERPRETER - pMethodDesc->MakeJitWorker(&header, 0, 0); + pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS()); #endif // !FEATURE_INTERPRETER } diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp index 50a2412904..bbd52f7932 100644 --- a/src/vm/compile.cpp +++ b/src/vm/compile.cpp @@ -1487,7 +1487,7 @@ void CEECompileInfo::CompressDebugInfo( HRESULT CEECompileInfo::GetBaseJitFlags( IN CORINFO_METHOD_HANDLE hMethod, - OUT DWORD *pFlags) + OUT CORJIT_FLAGS *pFlags) { STANDARD_VM_CONTRACT; @@ -6680,9 +6680,9 @@ MethodDesc * CEEPreloader::CompileMethodStubIfNeeded( { if (!pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->IsCompiled()) { - DWORD dwJitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags(); + CORJIT_FLAGS jitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags(); - pfnCallback(pCallbackContext, (CORINFO_METHOD_HANDLE)pStubMD, dwJitFlags); + pfnCallback(pCallbackContext, (CORINFO_METHOD_HANDLE)pStubMD, jitFlags); } #ifndef FEATURE_FULL_NGEN // Deduplication diff --git a/src/vm/compile.h b/src/vm/compile.h index 19bbac3228..8ee66dbec8 100644 --- a/src/vm/compile.h +++ b/src/vm/compile.h @@ -377,7 +377,7 @@ class CEECompileInfo : public ICorCompileInfo HRESULT GetBaseJitFlags( IN CORINFO_METHOD_HANDLE hMethod, - OUT DWORD *pFlags); + OUT CORJIT_FLAGS *pFlags); #ifdef _WIN64 SIZE_T getPersonalityValue(); diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp index 65e6871f73..5d63b1de87 100644 --- a/src/vm/dllimport.cpp +++ b/src/vm/dllimport.cpp @@ -1024,7 +1024,7 @@ public: pcsUnmarshal->EmitRET(); } - DWORD dwJitFlags = CORJIT_FLG_IL_STUB; + CORJIT_FLAGS jitFlags(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB); if (m_slIL.HasInteropParamExceptionInfo()) { @@ -1049,7 +1049,7 @@ public: else { // All other IL stubs will need to use the secret parameter. - dwJitFlags |= CORJIT_FLG_PUBLISH_SECRET_PARAM; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM); } if (SF_IsReverseStub(m_dwStubFlags)) @@ -1114,7 +1114,7 @@ public: m_slIL.GenerateCode(pbBuffer, cbCode); m_slIL.GetLocalSig(pbLocalSig, cbSig); - pResolver->SetJitFlags(dwJitFlags); + pResolver->SetJitFlags(jitFlags); #ifdef LOGGING LOG((LF_STUBS, LL_INFO1000, "---------------------------------------------------------------------\n")); @@ -1153,7 +1153,7 @@ public: LogILStubFlags(LF_STUBS, LL_INFO1000, m_dwStubFlags); - m_slIL.LogILStub(dwJitFlags); + m_slIL.LogILStub(jitFlags); } LOG((LF_STUBS, LL_INFO1000, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n")); #endif // LOGGING @@ -1170,7 +1170,7 @@ public: pStubMD, pbLocalSig, cbSig, - dwJitFlags, + jitFlags, &convertToHRTryCatch, &cleanupTryFinally, maxStack, @@ -1188,7 +1188,7 @@ public: MethodDesc * pStubMD, PCCOR_SIGNATURE pbLocalSig, DWORD cbSig, - DWORD dwJitFlags, + CORJIT_FLAGS jitFlags, ILStubEHClause * pConvertToHRTryCatchBounds, ILStubEHClause * pCleanupTryFinallyBounds, DWORD maxStack, @@ -1256,7 +1256,7 @@ public: strILStubCode.AppendPrintf(W(".maxstack %d \n"), maxStack); strILStubCode.AppendPrintf(W(".locals %s\n"), strLocalSig.GetUnicode()); - m_slIL.LogILStub(dwJitFlags, &strILStubCode); + m_slIL.LogILStub(jitFlags, &strILStubCode); if (pConvertToHRTryCatchBounds->cbTryLength != 0 && pConvertToHRTryCatchBounds->cbHandlerLength != 0) { @@ -5947,8 +5947,8 @@ PCODE JitILStub(MethodDesc* pStubMD) // A dynamically generated IL stub // - DWORD dwFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags(); - pCode = pStubMD->MakeJitWorker(NULL, dwFlags, 0); + CORJIT_FLAGS jitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags(); + pCode = pStubMD->MakeJitWorker(NULL, jitFlags); _ASSERTE(pCode == pStubMD->GetNativeCode()); } diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp index 198a00795f..8db5a4fd48 100644 --- a/src/vm/dllimportcallback.cpp +++ b/src/vm/dllimportcallback.cpp @@ -1320,7 +1320,7 @@ MethodDesc* UMThunkMarshInfo::GetILStubMethodDesc(MethodDesc* pInvokeMD, PInvoke dwStubFlags |= NDIRECTSTUB_FL_REVERSE_INTEROP; // could be either delegate interop or not--that info is passed in from the caller #if defined(DEBUGGING_SUPPORTED) - if (GetDebuggerCompileFlags(pSigInfo->GetModule(), 0) & CORJIT_FLG_DEBUG_CODE) + if (GetDebuggerCompileFlags(pSigInfo->GetModule(), CORJIT_FLAGS()).IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)) { dwStubFlags |= NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL; } @@ -1394,7 +1394,7 @@ VOID UMThunkMarshInfo::RunTimeInit() DWORD dwStubFlags = NDIRECTSTUB_FL_NGENEDSTUB | NDIRECTSTUB_FL_REVERSE_INTEROP | NDIRECTSTUB_FL_DELEGATE; #if defined(DEBUGGING_SUPPORTED) - if (GetDebuggerCompileFlags(GetModule(), 0) & CORJIT_FLG_DEBUG_CODE) + if (GetDebuggerCompileFlags(GetModule(), CORJIT_FLAGS()).IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)) { dwStubFlags |= NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL; } diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp index ff2f2df5a3..e200c19f65 100644 --- a/src/vm/i386/cgenx86.cpp +++ b/src/vm/i386/cgenx86.cpp @@ -1682,7 +1682,7 @@ void ResumeAtJit(PCONTEXT pContext, LPVOID oldESP) #pragma warning(push) #pragma warning(disable: 4035) -DWORD getcpuid(DWORD arg, unsigned char result[16]) +extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]) { LIMITED_METHOD_CONTRACT @@ -1709,7 +1709,7 @@ DWORD getcpuid(DWORD arg, unsigned char result[16]) // Arg3 is a pointer to the return buffer // No need to check whether or not CPUID is supported because we have already called CPUID with success to come here. -DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) +extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) { LIMITED_METHOD_CONTRACT @@ -1730,6 +1730,27 @@ DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) } } +extern "C" DWORD __stdcall xmmYmmStateSupport() +{ + // No CONTRACT + STATIC_CONTRACT_NOTHROW; + STATIC_CONTRACT_GC_NOTRIGGER; + + __asm + { + mov ecx, 0 ; Specify xcr0 + xgetbv ; result in EDX:EAX + and eax, 06H + cmp eax, 06H ; check OS has enabled both XMM and YMM state support + jne not_supported + mov eax, 1 + jmp done + not_supported: + mov eax, 0 + done: + } +} + #pragma warning(pop) diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp index 4343ba819f..9cd904aec7 100644 --- a/src/vm/ilstubcache.cpp +++ b/src/vm/ilstubcache.cpp @@ -128,7 +128,7 @@ MethodDesc* ILStubCache::CreateAndLinkNewILStubMethodDesc(LoaderAllocator* pAllo pStubLinker->GenerateCode(pbBuffer, cbCode); pStubLinker->GetLocalSig(pbLocalSig, cbSig); - pResolver->SetJitFlags(CORJIT_FLG_IL_STUB); + pResolver->SetJitFlags(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)); } pResolver->SetTokenLookupMap(pStubLinker->GetTokenLookupMap()); diff --git a/src/vm/ilstubresolver.cpp b/src/vm/ilstubresolver.cpp index 64ff99f67e..5ba6c8a3b0 100644 --- a/src/vm/ilstubresolver.cpp +++ b/src/vm/ilstubresolver.cpp @@ -299,7 +299,7 @@ ILStubResolver::ILStubResolver() : m_pStubMD(dac_cast<PTR_MethodDesc>(nullptr)), m_pStubTargetMD(dac_cast<PTR_MethodDesc>(nullptr)), m_type(Unassigned), - m_dwJitFlags(0) + m_jitFlags() { LIMITED_METHOD_CONTRACT; @@ -488,16 +488,16 @@ bool ILStubResolver::IsILGenerated() return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated); } -void ILStubResolver::SetJitFlags(DWORD dwFlags) +void ILStubResolver::SetJitFlags(CORJIT_FLAGS jitFlags) { LIMITED_METHOD_CONTRACT; - m_dwJitFlags = dwFlags; + m_jitFlags = jitFlags; } -DWORD ILStubResolver::GetJitFlags() +CORJIT_FLAGS ILStubResolver::GetJitFlags() { LIMITED_METHOD_CONTRACT; - return m_dwJitFlags; + return m_jitFlags; } // static diff --git a/src/vm/ilstubresolver.h b/src/vm/ilstubresolver.h index b100931107..47181c8a94 100644 --- a/src/vm/ilstubresolver.h +++ b/src/vm/ilstubresolver.h @@ -64,8 +64,8 @@ public: void SetTokenLookupMap(TokenLookupMap* pMap); - void SetJitFlags(DWORD dwJitFlags); - DWORD GetJitFlags(); + void SetJitFlags(CORJIT_FLAGS jitFlags); + CORJIT_FLAGS GetJitFlags(); static void StubGenFailed(ILStubResolver* pResolver); @@ -116,7 +116,7 @@ protected: PTR_MethodDesc m_pStubMD; PTR_MethodDesc m_pStubTargetMD; ILStubType m_type; - DWORD m_dwJitFlags; + CORJIT_FLAGS m_jitFlags; }; typedef Holder<ILStubResolver*, DoNothing<ILStubResolver*>, ILStubResolver::StubGenFailed, NULL> ILStubGenHolder; diff --git a/src/vm/interpreter.cpp b/src/vm/interpreter.cpp index ed289cb3cc..d92bf16ace 100644 --- a/src/vm/interpreter.cpp +++ b/src/vm/interpreter.cpp @@ -1736,13 +1736,13 @@ void Interpreter::JitMethodIfAppropriate(InterpreterMethodInfo* interpMethInfo, fprintf(GetLogFile(), "JITting method %s:%s.\n", md->m_pszDebugClassName, md->m_pszDebugMethodName); } #endif // _DEBUG - DWORD dwFlags = CORJIT_FLG_MAKEFINALCODE; + CORJIT_FLAGS jitFlags(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE); NewHolder<COR_ILMETHOD_DECODER> pDecoder(NULL); // Dynamic methods (e.g., IL stubs) do not have an IL decoder but may // require additional flags. Ordinary methods require the opposite. if (md->IsDynamicMethod()) { - dwFlags |= md->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags(); + jitFlags.Add(md->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags()); } else { @@ -1751,7 +1751,7 @@ void Interpreter::JitMethodIfAppropriate(InterpreterMethodInfo* interpMethInfo, md->GetMDImport(), &status); } - PCODE res = md->MakeJitWorker(pDecoder, dwFlags, 0); + PCODE res = md->MakeJitWorker(pDecoder, jitFlags); interpMethInfo->m_jittedCode = res; } } diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index a2485a4417..0ac9bd9373 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -7394,7 +7394,7 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, // If the callee wants debuggable code, don't allow it to be inlined - if (GetDebuggerCompileFlags(pCallee->GetModule(), 0) & CORJIT_FLG_DEBUG_CODE) + if (GetDebuggerCompileFlags(pCallee->GetModule(), CORJIT_FLAGS()).IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)) { result = INLINE_NEVER; szFailReason = "Inlinee is debuggable"; @@ -9112,7 +9112,7 @@ CorInfoTypeWithMod CEEInfo::getArgType ( CorElementType normType = typeHnd.GetInternalCorElementType(); // if we are looking up a value class, don't morph it to a refernece type - // (This can only happen in illegal IL + // (This can only happen in illegal IL) if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE) { type = normType; @@ -11686,8 +11686,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr, CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, CEEInfo *comp, struct CORINFO_METHOD_INFO *info, - unsigned flags, - unsigned flags2, + CORJIT_FLAGS jitFlags, BYTE **nativeEntry, ULONG *nativeSizeOfCode) { @@ -11698,13 +11697,9 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code - CORJIT_FLAGS jitFlags = { 0 }; - jitFlags.corJitFlags = flags; - jitFlags.corJitFlags2 = flags2; - #if !defined(FEATURE_CORECLR) // Ask the JIT to generate desktop-quirk-compatible code. - jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS); #endif comp->setJitFlags(jitFlags); @@ -11720,7 +11715,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR) ret = getJit()->compileMethod( comp, info, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); @@ -11729,18 +11724,18 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #if defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE) if (FAILED(ret) && jitMgr->m_alternateJit #ifdef FEATURE_STACK_SAMPLING - && (!samplingEnabled || (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND)) + && (!samplingEnabled || (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND))) #endif ) { ret = jitMgr->m_alternateJit->compileMethod( comp, info, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode ); #ifdef FEATURE_STACK_SAMPLING - if (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) + if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND)) { // Don't bother with failures if we couldn't collect a trace. ret = CORJIT_OK; @@ -11767,7 +11762,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { // If we're doing an "import_only" compilation, it's for verification, so don't interpret. // (We assume that importation is completely architecture-independent, or at least nearly so.) - if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) + if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)) { ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); } @@ -11778,7 +11773,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, ret = CompileMethodWithEtwWrapper(jitMgr, comp, info, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); } @@ -11787,7 +11782,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { // If we're doing an "import_only" compilation, it's for verification, so don't interpret. // (We assume that importation is completely architecture-independent, or at least nearly so.) - if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) + if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)) { ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); } @@ -11797,7 +11792,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { ret = jitMgr->m_jit->compileMethod( comp, info, - CORJIT_FLG_CALL_GETJITFLAGS, + CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); } @@ -11809,7 +11804,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, // If the JIT fails we keep the IL around and will // try reJIT the same IL. VSW 525059 // - if (SUCCEEDED(ret) && !(jitFlags.corJitFlags & CORJIT_FLG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain()) + if (SUCCEEDED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain()) { ((CEEJitInfo*)comp)->CompressDebugInfo(); @@ -11842,8 +11837,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, CorJitResult invokeCompileMethod(EEJitManager *jitMgr, CEEInfo *comp, struct CORINFO_METHOD_INFO *info, - unsigned flags, - unsigned flags2, + CORJIT_FLAGS jitFlags, BYTE **nativeEntry, ULONG *nativeSizeOfCode) { @@ -11858,7 +11852,7 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr, GCX_PREEMP(); - CorJitResult ret = invokeCompileMethodHelper(jitMgr, comp, info, flags, flags2, nativeEntry, nativeSizeOfCode); + CorJitResult ret = invokeCompileMethodHelper(jitMgr, comp, info, jitFlags, nativeEntry, nativeSizeOfCode); // // Verify that we are still in preemptive mode when we return @@ -11870,9 +11864,9 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr, return ret; } -CorJitFlag GetCompileFlagsIfGenericInstantiation( +CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( CORINFO_METHOD_HANDLE method, - CorJitFlag compileFlags, + CORJIT_FLAGS compileFlags, ICorJitInfo * pCorJitInfo, BOOL * raiseVerificationException, BOOL * unverifiableGenericCode); @@ -11880,8 +11874,7 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation( CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, CEEInfo *comp, struct CORINFO_METHOD_INFO *info, - unsigned flags, - unsigned flags2, + CORJIT_FLAGS flags, BYTE **nativeEntry, ULONG *nativeSizeOfCode, MethodDesc *ftn) @@ -11897,8 +11890,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, EEJitManager *jitMgr; CEEInfo *comp; struct CORINFO_METHOD_INFO *info; - unsigned flags; - unsigned flags2; + CORJIT_FLAGS flags; BYTE **nativeEntry; ULONG *nativeSizeOfCode; MethodDesc *ftn; @@ -11908,7 +11900,6 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, param.comp = comp; param.info = info; param.flags = flags; - param.flags2 = flags2; param.nativeEntry = nativeEntry; param.nativeSizeOfCode = nativeSizeOfCode; param.ftn = ftn; @@ -11924,16 +11915,16 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, pParam->comp, pParam->info, pParam->flags, - pParam->flags2, pParam->nativeEntry, pParam->nativeSizeOfCode); } PAL_FINALLY { #if defined(DEBUGGING_SUPPORTED) && !defined(CROSSGEN_COMPILE) - if (!(flags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MCJIT_BACKGROUND)) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && + !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND) #ifdef FEATURE_STACK_SAMPLING - && !(flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) + && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND) #endif // FEATURE_STACK_SAMPLING ) { @@ -11971,7 +11962,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, /*********************************************************************/ // Figures out the compile flags that are used by both JIT and NGen -/* static */ DWORD CEEInfo::GetBaseCompileFlags(MethodDesc * ftn) +/* static */ CORJIT_FLAGS CEEInfo::GetBaseCompileFlags(MethodDesc * ftn) { CONTRACTL { THROWS; @@ -11982,16 +11973,16 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, // Figure out the code quality flags // - DWORD flags = 0; + CORJIT_FLAGS flags; if (g_pConfig->JitFramed()) - flags |= CORJIT_FLG_FRAMED; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED); if (g_pConfig->JitAlignLoops()) - flags |= CORJIT_FLG_ALIGN_LOOPS; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_ALIGN_LOOPS); if (ReJitManager::IsReJITEnabled() || g_pConfig->AddRejitNops()) - flags |= CORJIT_FLG_PROF_REJIT_NOPS; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS); #ifdef _TARGET_X86_ if (g_pConfig->PInvokeRestoreEsp(ftn->GetModule()->IsPreV4Assembly())) - flags |= CORJIT_FLG_PINVOKE_RESTORE_ESP; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PINVOKE_RESTORE_ESP); #endif // _TARGET_X86_ //See if we should instruct the JIT to emit calls to JIT_PollGC for thread suspension. If we have a @@ -11999,9 +11990,9 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, #ifdef FEATURE_ENABLE_GCPOLL EEConfig::GCPollType pollType = g_pConfig->GetGCPollType(); if (EEConfig::GCPOLL_TYPE_POLL == pollType) - flags |= CORJIT_FLG_GCPOLL_CALLS; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS); else if (EEConfig::GCPOLL_TYPE_INLINE == pollType) - flags |= CORJIT_FLG_GCPOLL_INLINE; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE); #endif //FEATURE_ENABLE_GCPOLL // Set flags based on method's ImplFlags. @@ -12012,13 +12003,13 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, if (IsMiNoOptimization(dwImplFlags)) { - flags |= CORJIT_FLG_MIN_OPT; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT); } // Always emit frames for methods marked no-inline (see #define ETW_EBP_FRAMED in the JIT) if (IsMiNoInlining(dwImplFlags)) { - flags |= CORJIT_FLG_FRAMED; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED); } } @@ -12029,7 +12020,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, // Figures out (some of) the flags to use to compile the method // Returns the new set to use -DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags) +CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags) { STANDARD_VM_CONTRACT; @@ -12044,36 +12035,37 @@ DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags) #ifdef _DEBUG if (g_pConfig->GenDebuggableCode()) - flags |= CORJIT_FLG_DEBUG_CODE; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); #endif // _DEBUG #ifdef EnC_SUPPORTED if (pModule->IsEditAndContinueEnabled()) { - flags |= CORJIT_FLG_DEBUG_EnC; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC); } #endif // EnC_SUPPORTED // Debug info is always tracked - flags |= CORJIT_FLG_DEBUG_INFO; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); #endif // DEBUGGING_SUPPORTED if (CORDisableJITOptimizations(pModule->GetDebuggerInfoBits())) { - flags |= CORJIT_FLG_DEBUG_CODE; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); } - if (flags & CORJIT_FLG_IMPORT_ONLY) + if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { // If we are only verifying the method, dont need any debug info and this // prevents getVars()/getBoundaries() from being called unnecessarily. - flags &= ~(CORJIT_FLG_DEBUG_INFO|CORJIT_FLG_DEBUG_CODE); + flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); + flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); } return flags; } -CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * methodInfo) +CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHOD_INFO * methodInfo) { STANDARD_VM_CONTRACT; @@ -12082,14 +12074,14 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * // // Get the compile flags that are shared between JIT and NGen // - flags |= CEEInfo::GetBaseCompileFlags(ftn); + flags.Add(CEEInfo::GetBaseCompileFlags(ftn)); // // Get CPU specific flags // - if ((flags & CORJIT_FLG_IMPORT_ONLY) == 0) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { - flags |= ExecutionManager::GetEEJitManager()->GetCPUCompileFlags(); + flags.Add(ExecutionManager::GetEEJitManager()->GetCPUCompileFlags()); } // @@ -12097,21 +12089,19 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * // #ifdef DEBUGGING_SUPPORTED - flags |= GetDebuggerCompileFlags(ftn->GetModule(), flags); + flags.Add(GetDebuggerCompileFlags(ftn->GetModule(), flags)); #endif #ifdef PROFILING_SUPPORTED - if (CORProfilerTrackEnterLeave() - && !ftn->IsNoMetadata() - ) - flags |= CORJIT_FLG_PROF_ENTERLEAVE; + if (CORProfilerTrackEnterLeave() && !ftn->IsNoMetadata()) + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE); if (CORProfilerTrackTransitions()) - flags |= CORJIT_FLG_PROF_NO_PINVOKE_INLINE; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE); #endif // PROFILING_SUPPORTED // Set optimization flags - if (0 == (flags & CORJIT_FLG_MIN_OPT)) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT)) { unsigned optType = g_pConfig->GenOptimizeType(); _ASSERTE(optType <= OPT_RANDOM); @@ -12120,18 +12110,16 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * optType = methodInfo->ILCodeSize % OPT_RANDOM; if (g_pConfig->JitMinOpts()) - flags |= CORJIT_FLG_MIN_OPT; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT); - const static unsigned optTypeFlags[] = + if (optType == OPT_SIZE) { - 0, // OPT_BLENDED - CORJIT_FLG_SIZE_OPT, // OPT_CODE_SIZE - CORJIT_FLG_SPEED_OPT // OPT_CODE_SPEED - }; - - _ASSERTE(optType < OPT_RANDOM); - _ASSERTE((sizeof(optTypeFlags)/sizeof(optTypeFlags[0])) == OPT_RANDOM); - flags |= optTypeFlags[optType]; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT); + } + else if (optType == OPT_SPEED) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT); + } } // @@ -12140,22 +12128,21 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * #ifdef _DEBUG if (g_pConfig->IsJitVerificationDisabled()) - flags |= CORJIT_FLG_SKIP_VERIFICATION; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); #endif // _DEBUG - if ((flags & CORJIT_FLG_IMPORT_ONLY) == 0 && - Security::CanSkipVerification(ftn)) - flags |= CORJIT_FLG_SKIP_VERIFICATION; + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && Security::CanSkipVerification(ftn)) + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); if (ftn->IsILStub()) { - flags |= CORJIT_FLG_SKIP_VERIFICATION; + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); // no debug info available for IL stubs - flags &= ~CORJIT_FLG_DEBUG_INFO; + flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); } - return (CorJitFlag)flags; + return flags; } #if defined(_WIN64) @@ -12165,12 +12152,12 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * // //This only works for real methods. If the method isn't IsIL, then IsVerifiable will AV. That would be a //bad thing (TM). -BOOL IsTransparentMethodSafeToSkipVerification(CorJitFlag flags, MethodDesc * ftn) +BOOL IsTransparentMethodSafeToSkipVerification(CORJIT_FLAGS flags, MethodDesc * ftn) { STANDARD_VM_CONTRACT; BOOL ret = FALSE; - if (!(flags & CORJIT_FLG_IMPORT_ONLY) && !(flags & CORJIT_FLG_SKIP_VERIFICATION) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION) && Security::IsMethodTransparent(ftn) && ((ftn->IsIL() && !ftn->IsUnboxingStub()) || (ftn->IsDynamicMethod() && !ftn->IsILStub()))) @@ -12200,9 +12187,9 @@ BOOL IsTransparentMethodSafeToSkipVerification(CorJitFlag flags, MethodDesc * ft // failed, then we need to throw an exception whenever we try // to compile a real instantiation -CorJitFlag GetCompileFlagsIfGenericInstantiation( +CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( CORINFO_METHOD_HANDLE method, - CorJitFlag compileFlags, + CORJIT_FLAGS compileFlags, ICorJitInfo * pCorJitInfo, BOOL * raiseVerificationException, BOOL * unverifiableGenericCode) @@ -12213,7 +12200,7 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation( *unverifiableGenericCode = FALSE; // If we have already decided to skip verification, keep on going. - if (compileFlags & CORJIT_FLG_SKIP_VERIFICATION) + if (compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)) return compileFlags; CorInfoInstantiationVerification ver = pCorJitInfo->isInstantiationOfVerifiedGeneric(method); @@ -12223,13 +12210,14 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation( case INSTVER_NOT_INSTANTIATION: // Non-generic, or open instantiation of a generic type/method if (IsTransparentMethodSafeToSkipVerification(compileFlags, (MethodDesc*)method)) - compileFlags = (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION); + compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); return compileFlags; case INSTVER_GENERIC_PASSED_VERIFICATION: // If the typical instantiation is verifiable, there is no need // to verify the concrete instantiations - return (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION); + compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); + return compileFlags; case INSTVER_GENERIC_FAILED_VERIFICATION: @@ -12255,9 +12243,9 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation( // hits unverifiable code. Since we've already hit unverifiable code, // there's no point in starting the JIT, just to have it give up, so we // give up here. - _ASSERTE(compileFlags & CORJIT_FLG_PREJIT); + _ASSERTE(compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PREJIT)); *raiseVerificationException = TRUE; - return (CorJitFlag)-1; // This value will not be used + return CORJIT_FLAGS(); // This value will not be used } #else // FEATURE_PREJIT // Need to have this case here to keep the MAC build happy @@ -12276,17 +12264,18 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation( // branches while compiling the concrete instantiation. Instead, // just throw a VerificationException right away. *raiseVerificationException = TRUE; - return (CorJitFlag)-1; // This value will not be used + return CORJIT_FLAGS(); // This value will not be used } case CORINFO_VERIFICATION_CAN_SKIP: { - return (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION); + compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); + return compileFlags; } case CORINFO_VERIFICATION_RUNTIME_CHECK: { - // Compile the method without CORJIT_FLG_SKIP_VERIFICATION. + // Compile the method without CORJIT_FLAG_SKIP_VERIFICATION. // The compiler will know to add a call to // CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, and then to skip verification. return compileFlags; @@ -12361,8 +12350,8 @@ BOOL g_fAllowRel32 = TRUE; // Calls to this method that occur to check if inlining can occur on x86, // are OK since they discard the return value of this method. -PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, - DWORD flags, DWORD flags2, ULONG * pSizeOfCode) +PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags, + ULONG * pSizeOfCode) { STANDARD_VM_CONTRACT; @@ -12376,9 +12365,9 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, ftn->GetModule()->GetDomainFile()->IsZapRequired() && PartialNGenStressPercentage() == 0 && #ifdef FEATURE_STACK_SAMPLING - !(flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) && + !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND) && #endif - !(flags & CORJIT_FLG_IMPORT_ONLY)) + !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { StackSString ss(SString::Ascii, "ZapRequire: JIT compiler invoked for "); TypeString::AppendMethodInternal(ss, ftn); @@ -12468,10 +12457,10 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, getMethodInfoHelper(ftn, ftnHnd, ILHeader, &methodInfo); // If it's generic then we can only enter through an instantiated md (unless we're just verifying it) - _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0 || !ftn->IsGenericMethodDefinition()); + _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) || !ftn->IsGenericMethodDefinition()); // If it's an instance method then it must not be entered from a generic class - _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0 || ftn->IsStatic() || + _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) || ftn->IsStatic() || ftn->GetNumGenericClassArgs() == 0 || ftn->HasClassInstantiation()); // method attributes and signature are consistant @@ -12480,7 +12469,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, flags = GetCompileFlags(ftn, flags, &methodInfo); #ifdef _DEBUG - if (!(flags & CORJIT_FLG_SKIP_VERIFICATION)) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)) { SString methodString; if (LoggingOn(LF_VERIFIER, LL_INFO100)) @@ -12512,10 +12501,10 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, for (;;) { #ifndef CROSSGEN_COMPILE - CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, (flags & CORJIT_FLG_IMPORT_ONLY) != 0); + CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)); #else // This path should be only ever used for verification in crossgen and so we should not need EEJitManager - _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0); + _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)); CEEInfo jitInfo(ftn, true); EEJitManager *jitMgr = NULL; #endif @@ -12574,7 +12563,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, flags = GetCompileFlagsIfGenericInstantiation( ftnHnd, - (CorJitFlag)flags, + flags, &jitInfo, &raiseVerificationException, &unverifiableGenericCode); @@ -12595,7 +12584,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, #ifdef PERF_TRACK_METHOD_JITTIMES //Because we're not calling QPC enough. I'm not going to track times if we're just importing. LARGE_INTEGER methodJitTimeStart = {0}; - if (!(flags & CORJIT_FLG_IMPORT_ONLY)) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) QueryPerformanceCounter (&methodJitTimeStart); #endif @@ -12615,7 +12604,6 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, &jitInfo, &methodInfo, flags, - flags2, &nativeEntry, &sizeOfCode, (MethodDesc*)ftn); @@ -12646,7 +12634,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, #ifdef PERF_TRACK_METHOD_JITTIMES //store the time in the string buffer. Module name and token are unique enough. Also, do not //capture importing time, just actual compilation time. - if (!(flags & CORJIT_FLG_IMPORT_ONLY)) + if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { LARGE_INTEGER methodJitTimeStop; QueryPerformanceCounter(&methodJitTimeStop); @@ -12677,7 +12665,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, ThrowExceptionForJit(res); } - if (flags & CORJIT_FLG_IMPORT_ONLY) + if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { // The method must been processed by the verifier. Note that it may // either have been marked as verifiable or unverifiable. diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h index 41d0f6221d..1a7f643381 100644 --- a/src/vm/jitinterface.h +++ b/src/vm/jitinterface.h @@ -54,7 +54,7 @@ void InitJITHelpers1(); void InitJITHelpers2(); PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header, - DWORD flags, DWORD flags2, ULONG* sizeOfCode = NULL); + CORJIT_FLAGS flags, ULONG* sizeOfCode = NULL); void getMethodInfoHelper(MethodDesc * ftn, CORINFO_METHOD_HANDLE ftnHnd, @@ -647,7 +647,7 @@ public: ); // Returns that compilation flags that are shared between JIT and NGen - static DWORD GetBaseCompileFlags(MethodDesc * ftn); + static CORJIT_FLAGS GetBaseCompileFlags(MethodDesc * ftn); // Resolve metadata token into runtime method handles. void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken); @@ -1691,7 +1691,7 @@ public: static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object); }; -DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags); +CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags); bool TrackAllocationsEnabled(); diff --git a/src/vm/method.cpp b/src/vm/method.cpp index 70714b710d..14651239a7 100644 --- a/src/vm/method.cpp +++ b/src/vm/method.cpp @@ -1078,7 +1078,7 @@ BOOL MethodDesc::IsVerifiable() #endif // _VER_EE_VERIFICATION_ENABLED } - UnsafeJitFunction(this, pHeader, CORJIT_FLG_IMPORT_ONLY, 0); + UnsafeJitFunction(this, pHeader, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)); _ASSERTE(IsVerified()); return (IsVerified() && (m_wFlags & mdcVerifiable)); diff --git a/src/vm/method.hpp b/src/vm/method.hpp index d96cddc315..499112d149 100644 --- a/src/vm/method.hpp +++ b/src/vm/method.hpp @@ -1649,7 +1649,7 @@ public: PCODE DoPrestub(MethodTable *pDispatchingMT); - PCODE MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWORD flags2); + PCODE MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags); VOID GetMethodInfo(SString &namespaceOrClassName, SString &methodName, SString &methodSignature); VOID GetMethodInfoWithNewSig(SString &namespaceOrClassName, SString &methodName, SString &methodSignature); diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 70c0e3b8cb..bb8717780d 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -1245,8 +1245,8 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize() EEJitManager *jitMgr = ExecutionManager::GetEEJitManager(); if (jitMgr->LoadJIT()) { - DWORD cpuCompileFlags = jitMgr->GetCPUCompileFlags(); - if ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) + CORJIT_FLAGS cpuCompileFlags = jitMgr->GetCPUCompileFlags(); + if (cpuCompileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD)) { unsigned intrinsicSIMDVectorLength = jitMgr->m_jit->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags); if (intrinsicSIMDVectorLength != 0) diff --git a/src/vm/multicorejitplayer.cpp b/src/vm/multicorejitplayer.cpp index 0c69fdcf94..7d13bbc462 100644 --- a/src/vm/multicorejitplayer.cpp +++ b/src/vm/multicorejitplayer.cpp @@ -556,7 +556,7 @@ bool MulticoreJitProfilePlayer::CompileMethodDesc(Module * pModule, MethodDesc * #endif // MakeJitWorker calls back to MulticoreJitCodeStorage::StoreMethodCode under MethodDesc lock - pMD->MakeJitWorker(& header, CORJIT_FLG_MCJIT_BACKGROUND, 0); + pMD->MakeJitWorker(& header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND)); return true; } diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index 572065ce4c..f75ef1411c 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -256,7 +256,7 @@ void DACNotifyCompilationFinished(MethodDesc *methodDesc) // which prevents us from trying to JIT the same method more that once. -PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWORD flags2) +PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags) { STANDARD_VM_CONTRACT; @@ -280,7 +280,7 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWO #ifdef FEATURE_MULTICOREJIT MulticoreJitManager & mcJitManager = GetAppDomain()->GetMulticoreJitManager(); - bool fBackgroundThread = (flags & CORJIT_FLG_MCJIT_BACKGROUND) != 0; + bool fBackgroundThread = flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND); #endif { @@ -461,13 +461,13 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWO if (!fBackgroundThread) #endif // FEATURE_MULTICOREJIT { - StackSampler::RecordJittingInfo(this, flags, flags2); + StackSampler::RecordJittingInfo(this, flags); } #endif // FEATURE_STACK_SAMPLING EX_TRY { - pCode = UnsafeJitFunction(this, ILHeader, flags, flags2, &sizeOfCode); + pCode = UnsafeJitFunction(this, ILHeader, flags, &sizeOfCode); } EX_CATCH { @@ -1463,7 +1463,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT) // Mark the code as hot in case the method ends up in the native image g_IBCLogger.LogMethodCodeAccess(this); - pCode = MakeJitWorker(pHeader, 0, 0); + pCode = MakeJitWorker(pHeader, CORJIT_FLAGS()); #ifdef FEATURE_INTERPRETER if ((pCode != NULL) && !HasStableEntryPoint()) diff --git a/src/vm/rejit.cpp b/src/vm/rejit.cpp index 6b3caa9091..0b6e922831 100644 --- a/src/vm/rejit.cpp +++ b/src/vm/rejit.cpp @@ -178,22 +178,22 @@ CrstStatic ReJitManager::s_csGlobalRequest; //--------------------------------------------------------------------------------------- // Helpers -inline DWORD JitFlagsFromProfCodegenFlags(DWORD dwCodegenFlags) +inline CORJIT_FLAGS JitFlagsFromProfCodegenFlags(DWORD dwCodegenFlags) { LIMITED_METHOD_DAC_CONTRACT; - DWORD jitFlags = 0; + CORJIT_FLAGS jitFlags; // Note: COR_PRF_CODEGEN_DISABLE_INLINING is checked in // code:CEEInfo::canInline#rejit (it has no equivalent CORJIT flag). if ((dwCodegenFlags & COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS) != 0) { - jitFlags |= CORJIT_FLG_DEBUG_CODE; + jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE); } // In the future more flags may be added that need to be converted here (e.g., - // COR_PRF_CODEGEN_ENTERLEAVE / CORJIT_FLG_PROF_ENTERLEAVE) + // COR_PRF_CODEGEN_ENTERLEAVE / CORJIT_FLAG_PROF_ENTERLEAVE) return jitFlags; } @@ -2170,8 +2170,7 @@ PCODE ReJitManager::DoReJit(ReJitInfo * pInfo) pCodeOfRejittedCode = UnsafeJitFunction( pInfo->GetMethodDesc(), &ILHeader, - JitFlagsFromProfCodegenFlags(pInfo->m_pShared->m_dwCodegenFlags), - 0); + JitFlagsFromProfCodegenFlags(pInfo->m_pShared->m_dwCodegenFlags)); _ASSERTE(pCodeOfRejittedCode != NULL); diff --git a/src/vm/stacksampler.cpp b/src/vm/stacksampler.cpp index 270d278b66..d95adb1f63 100644 --- a/src/vm/stacksampler.cpp +++ b/src/vm/stacksampler.cpp @@ -154,7 +154,7 @@ bool IsGoodMethodDesc(MethodDesc* pMD) // // An opportunity to record the parameters passed to the JIT at the time of JITting this method. /* static */ -void StackSampler::RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFlags2) +void StackSampler::RecordJittingInfo(MethodDesc* pMD, CORJIT_FLAGS flags) { WRAPPER_NO_CONTRACT; if (g_pStackSampler == nullptr) @@ -167,10 +167,10 @@ void StackSampler::RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFla return; } // Record in the hash map. - g_pStackSampler->RecordJittingInfoInternal(pMD, dwFlags); + g_pStackSampler->RecordJittingInfoInternal(pMD, flags); } -void StackSampler::RecordJittingInfoInternal(MethodDesc* pMD, DWORD dwFlags) +void StackSampler::RecordJittingInfoInternal(MethodDesc* pMD, CORJIT_FLAGS flags) { ADID dwDomainId = GetThread()->GetDomain()->GetId(); JitInfoHashEntry entry(pMD, dwDomainId); @@ -426,7 +426,7 @@ void StackSampler::JitAndCollectTrace(MethodDesc* pMD, const ADID& adId) // Indicate to the JIT or the JIT interface that we are JITting // in the background for stack sampling. - DWORD dwFlags2 = CORJIT_FLG2_SAMPLING_JIT_BACKGROUND; + CORJIT_FLAGS flags(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND); _ASSERTE(pMD->IsIL()); @@ -447,7 +447,7 @@ void StackSampler::JitAndCollectTrace(MethodDesc* pMD, const ADID& adId) LOG((LF_JIT, LL_INFO100000, "%s:%s\n", pMD->GetMethodTable()->GetClass()->GetDebugClassName(), pMD->GetName())); #endif - PCODE pCode = UnsafeJitFunction(pMD, pDecoder, 0, dwFlags2); + PCODE pCode = UnsafeJitFunction(pMD, pDecoder, flags); } END_DOMAIN_TRANSITION; diff --git a/src/vm/stacksampler.h b/src/vm/stacksampler.h index 33fc6b93ce..0b9add1713 100644 --- a/src/vm/stacksampler.h +++ b/src/vm/stacksampler.h @@ -21,7 +21,7 @@ class StackSampler public: // Interface static void Init(); - static void RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFlags2); + static void RecordJittingInfo(MethodDesc* pMD, CORJIT_FLAGS flags); private: @@ -41,7 +41,7 @@ private: void JitAndCollectTrace(MethodDesc* pMD, const ADID& adId); - void RecordJittingInfoInternal(MethodDesc* pMD, DWORD flags); + void RecordJittingInfoInternal(MethodDesc* pMD, CORJIT_FLAGS flags); ADID GetDomainId(MethodDesc* pMD, const ADID& defaultId); diff --git a/src/vm/stubgen.cpp b/src/vm/stubgen.cpp index fffa52a366..18a6c19480 100644 --- a/src/vm/stubgen.cpp +++ b/src/vm/stubgen.cpp @@ -631,15 +631,7 @@ ILStubLinker::LogILStubWorker( } } -static inline void LogOneFlag(DWORD flags, DWORD flag, LPCSTR str, DWORD facility, DWORD level) -{ - if (flags & flag) - { - LOG((facility, level, str)); - } -} - -static void LogJitFlags(DWORD facility, DWORD level, DWORD dwJitFlags) +static void LogJitFlags(DWORD facility, DWORD level, CORJIT_FLAGS jitFlags) { CONTRACTL { @@ -647,29 +639,28 @@ static void LogJitFlags(DWORD facility, DWORD level, DWORD dwJitFlags) } CONTRACTL_END; - LOG((facility, level, "dwJitFlags: 0x%08x\n", dwJitFlags)); + LOG((facility, level, "jitFlags:\n")); -#define LOG_FLAG(name) LogOneFlag(dwJitFlags, name, " " #name "\n", facility, level); +#define LOG_FLAG(name) \ + if (jitFlags.IsSet(name)) \ + { \ + LOG((facility, level, " " #name "\n")); \ + jitFlags.Clear(name); \ + } // these are all we care about at the moment - LOG_FLAG(CORJIT_FLG_IL_STUB); - LOG_FLAG(CORJIT_FLG_PUBLISH_SECRET_PARAM); + LOG_FLAG(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB); + LOG_FLAG(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM); #undef LOG_FLAGS - DWORD dwKnownMask = - CORJIT_FLG_IL_STUB | - CORJIT_FLG_PUBLISH_SECRET_PARAM | - NULL; - - DWORD dwUnknownFlags = dwJitFlags & ~dwKnownMask; - if (0 != dwUnknownFlags) + if (!jitFlags.IsEmpty()) { - LOG((facility, level, "UNKNOWN FLAGS: 0x%08x\n", dwUnknownFlags)); + LOG((facility, level, "UNKNOWN FLAGS also set\n")); } } -void ILStubLinker::LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode) +void ILStubLinker::LogILStub(CORJIT_FLAGS jitFlags, SString *pDumpILStubCode) { CONTRACTL { @@ -683,7 +674,7 @@ void ILStubLinker::LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode) INT iCurStack = 0; if (pDumpILStubCode == NULL) - LogJitFlags(LF_STUBS, LL_INFO1000, dwJitFlags); + LogJitFlags(LF_STUBS, LL_INFO1000, jitFlags); while (pCurrentStream) { @@ -841,7 +832,7 @@ size_t ILStubLinker::Link(UINT* puMaxStack) #ifdef _DEBUG if (fStackUnderflow) { - LogILStub(NULL); + LogILStub(CORJIT_FLAGS()); CONSISTENCY_CHECK_MSG(false, "IL stack underflow! -- see logging output"); } #endif // _DEBUG diff --git a/src/vm/stubgen.h b/src/vm/stubgen.h index e6d3f9ec4d..7bebfa7610 100644 --- a/src/vm/stubgen.h +++ b/src/vm/stubgen.h @@ -431,7 +431,7 @@ public: void ClearCodeStreams(); - void LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode = NULL); + void LogILStub(CORJIT_FLAGS jitFlags, SString *pDumpILStubCode = NULL); protected: void LogILStubWorker(ILInstruction* pInstrBuffer, UINT numInstr, size_t* pcbCode, INT* piCurStack, SString *pDumpILStubCode = NULL); void LogILInstruction(size_t curOffset, bool isLabeled, INT iCurStack, ILInstruction* pInstruction, SString *pDumpILStubCode = NULL); diff --git a/src/vm/util.cpp b/src/vm/util.cpp index 2cb3460122..a7c264fb67 100644 --- a/src/vm/util.cpp +++ b/src/vm/util.cpp @@ -2069,16 +2069,9 @@ lDone: #define CACHE_PARTITION_BITS 0x003FF000 // number of cache Physical Partitions is returned in EBX[21:12] (10 bits) using cpuid function 4 #define CACHE_LINESIZE_BITS 0x00000FFF // Linesize returned in EBX[11:0] (12 bits) using cpuid function 4 -#if defined(_TARGET_X86_) - // these are defined in cgenx86.cpp - extern DWORD getcpuid(DWORD arg1, unsigned char result[16]); - extern DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]); -#elif defined(_TARGET_AMD64_) - // these are defined in src\VM\AMD64\asmhelpers.asm - extern "C" DWORD __stdcall getcpuid(DWORD arg1, unsigned char result[16]); - extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]); -#endif - +// these are defined in src\VM\AMD64\asmhelpers.asm / cgenx86.cpp +extern "C" DWORD __stdcall getcpuid(DWORD arg1, unsigned char result[16]); +extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]); // The following function uses a deterministic mechanism for enumerating/calculating the details of the cache hierarychy at runtime // by using deterministic cache parameter leafs on Prescott and higher processors. diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 8f2bc78f5b..a6f80d2540 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -395,7 +395,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)); } @@ -1943,23 +1943,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; @@ -2199,7 +2200,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; @@ -2213,7 +2214,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); @@ -2271,7 +2272,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++; @@ -2504,7 +2505,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 @@ -3481,7 +3482,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 b375709942..71f3436391 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; @@ -2041,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); @@ -3332,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_) @@ -3362,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: @@ -3371,20 +3378,20 @@ 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 (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); } #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 |