diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp index 216b017054836d..86013f7a964d28 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp @@ -463,6 +463,32 @@ EXTERN_C VOID __cdecl RtlRestoreContextFallback(PCONTEXT ContextRecord, struct _ typedef BOOL(WINAPI* PINITIALIZECONTEXT2)(PVOID Buffer, DWORD ContextFlags, PCONTEXT* Context, PDWORD ContextLength, ULONG64 XStateCompactionMask); PINITIALIZECONTEXT2 pfnInitializeContext2 = NULL; +#ifdef TARGET_ARM64 +// Mirror the XSTATE_ARM64_SVE flags from winnt.h + +#ifndef XSTATE_ARM64_SVE +#define XSTATE_ARM64_SVE (2) +#endif // XSTATE_ARM64_SVE + +#ifndef XSTATE_MASK_ARM64_SVE +#define XSTATE_MASK_ARM64_SVE (1ui64 << (XSTATE_ARM64_SVE)) +#endif // XSTATE_MASK_ARM64_SVE + +#ifndef CONTEXT_ARM64_XSTATE +#define CONTEXT_ARM64_XSTATE (CONTEXT_ARM64 | 0x20L) +#endif // CONTEXT_ARM64_XSTATE + +#ifndef CONTEXT_XSTATE +#define CONTEXT_XSTATE CONTEXT_ARM64_XSTATE +#endif // CONTEXT_XSTATE + +typedef DWORD64(WINAPI* PGETENABLEDXSTATEFEATURES)(); +PGETENABLEDXSTATEFEATURES pfnGetEnabledXStateFeatures = NULL; + +typedef BOOL(WINAPI* PSETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask); +PSETXSTATEFEATURESMASK pfnSetXStateFeaturesMask = NULL; +#endif // TARGET_ARM64 + #ifdef TARGET_X86 EXTERN_C VOID __cdecl RtlRestoreContextFallback(PCONTEXT ContextRecord, struct _EXCEPTION_RECORD* ExceptionRecord); typedef VOID(__cdecl* PRTLRESTORECONTEXT)(PCONTEXT ContextRecord, struct _EXCEPTION_RECORD* ExceptionRecord); @@ -478,7 +504,7 @@ REDHAWK_PALEXPORT CONTEXT* PalAllocateCompleteOSContext(_Out_ uint8_t** contextB { CONTEXT* pOSContext = NULL; -#if (defined(TARGET_X86) || defined(TARGET_AMD64)) +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) DWORD context = CONTEXT_COMPLETE; if (pfnInitializeContext2 == NULL) @@ -490,6 +516,17 @@ REDHAWK_PALEXPORT CONTEXT* PalAllocateCompleteOSContext(_Out_ uint8_t** contextB } } +#if defined(TARGET_ARM64) + if (pfnGetEnabledXStateFeatures == NULL) + { + HMODULE hm = GetModuleHandleW(_T("kernel32.dll")); + if (hm != NULL) + { + pfnGetEnabledXStateFeatures = (PGETENABLEDXSTATEFEATURES)GetProcAddress(hm, "GetEnabledXStateFeatures"); + } + } +#endif // TARGET_ARM64 + #ifdef TARGET_X86 if (pfnRtlRestoreContext == NULL) { @@ -503,10 +540,27 @@ REDHAWK_PALEXPORT CONTEXT* PalAllocateCompleteOSContext(_Out_ uint8_t** contextB } #endif //TARGET_X86 - // Determine if the processor supports AVX or AVX512 so we could - // retrieve extended registers - DWORD64 FeatureMask = GetEnabledXStateFeatures(); - if ((FeatureMask & (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)) != 0) +#if defined(TARGET_X86) || defined(TARGET_AMD64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_AVX | XSTATE_MASK_AVX512; + const ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | XSTATE_MASK_MPX | xStateFeatureMask; +#elif defined(TARGET_ARM64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_ARM64_SVE; + const ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | xStateFeatureMask; +#endif + + // Determine if the processor supports extended features so we could retrieve those registers + DWORD64 FeatureMask = 0; + +#if defined(TARGET_X86) || defined(TARGET_AMD64) + FeatureMask = GetEnabledXStateFeatures(); +#elif defined(TARGET_ARM64) + if (pfnGetEnabledXStateFeatures != NULL) + { + FeatureMask = pfnGetEnabledXStateFeatures(); + } +#endif + + if ((FeatureMask & xStateFeatureMask) != 0) { context = context | CONTEXT_XSTATE; } @@ -517,7 +571,6 @@ REDHAWK_PALEXPORT CONTEXT* PalAllocateCompleteOSContext(_Out_ uint8_t** contextB // Retrieve contextSize by passing NULL for Buffer DWORD contextSize = 0; - ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | XSTATE_MASK_AVX | XSTATE_MASK_MPX | XSTATE_MASK_AVX512; // The initialize call should fail but return contextSize BOOL success = pfnInitializeContext2 ? pfnInitializeContext2(NULL, context, NULL, &contextSize, xStateCompactionMask) : @@ -565,15 +618,32 @@ REDHAWK_PALEXPORT _Success_(return) bool REDHAWK_PALAPI PalGetCompleteThreadCont { _ASSERTE((pCtx->ContextFlags & CONTEXT_COMPLETE) == CONTEXT_COMPLETE); -#if defined(TARGET_X86) || defined(TARGET_AMD64) - // Make sure that AVX feature mask is set, if supported. This should not normally fail. +#if defined(TARGET_ARM64) + if (pfnSetXStateFeaturesMask == NULL) + { + HMODULE hm = GetModuleHandleW(_T("kernel32.dll")); + if (hm != NULL) + { + pfnSetXStateFeaturesMask = (PSETXSTATEFEATURESMASK)GetProcAddress(hm, "SetXStateFeaturesMask"); + } + } +#endif // TARGET_ARM64 + + // This should not normally fail. // The system silently ignores any feature specified in the FeatureMask which is not enabled on the processor. +#if defined(TARGET_X86) || defined(TARGET_AMD64) if (!SetXStateFeaturesMask(pCtx, XSTATE_MASK_AVX | XSTATE_MASK_AVX512)) { _ASSERTE(!"Could not apply XSTATE_MASK_AVX | XSTATE_MASK_AVX512"); return FALSE; } -#endif //defined(TARGET_X86) || defined(TARGET_AMD64) +#elif defined(TARGET_ARM64) + if ((pfnSetXStateFeaturesMask != NULL) && !pfnSetXStateFeaturesMask(pCtx, XSTATE_MASK_ARM64_SVE)) + { + _ASSERTE(!"Could not apply XSTATE_MASK_ARM64_SVE"); + return FALSE; + } +#endif return GetThreadContext(hThread, pCtx); } @@ -902,7 +972,7 @@ REDHAWK_PALEXPORT HANDLE PalLoadLibrary(const char* moduleName) return 0; } moduleNameWide[len] = '\0'; - + HANDLE result = LoadLibraryExW(moduleNameWide, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); delete[] moduleNameWide; return result; diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 741a019ed3afe7..77b641a5059232 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -1844,11 +1844,11 @@ typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY { #define CONTEXT_EXCEPTION_REQUEST 0x40000000L #define CONTEXT_EXCEPTION_REPORTING 0x80000000L -#define CONTEXT_XSTATE (CONTEXT_ARM64 | 0x40L) +#define CONTEXT_ARM64_XSTATE (CONTEXT_ARM64 | 0x20L) +#define CONTEXT_XSTATE CONTEXT_ARM64_XSTATE -#define XSTATE_SVE (0) - -#define XSTATE_MASK_SVE (UI64(1) << (XSTATE_SVE)) +#define XSTATE_ARM64_SVE (2) +#define XSTATE_MASK_ARM64_SVE (UI64(1) << (XSTATE_ARM64_SVE)) // // This flag is set by the unwinder if it has unwound to a call diff --git a/src/coreclr/pal/src/arch/arm64/asmconstants.h b/src/coreclr/pal/src/arch/arm64/asmconstants.h index d6379a28ce8013..c99cb4bed9cdc4 100644 --- a/src/coreclr/pal/src/arch/arm64/asmconstants.h +++ b/src/coreclr/pal/src/arch/arm64/asmconstants.h @@ -18,13 +18,14 @@ #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) -#define CONTEXT_XSTATE_BIT (6) -#define CONTEXT_XSTATE (1 << CONTEXT_XSTATE_BIT) +#define CONTEXT_ARM64_XSTATE_BIT (5) +#define CONTEXT_ARM64_XSTATE (1 << CONTEXT_XSTATE_BIT) -#define XSTATE_SVE_BIT (0) - -#define XSTATE_MASK_SVE (UI64(1) << (XSTATE_SVE)) +#define CONTEXT_XSTATE_BIT CONTEXT_ARM64_XSTATE_BIT +#define CONTEXT_XSTATE CONTEXT_ARM64_XSTATE +#define XSTATE_ARM64_SVE_BIT (2) +#define XSTATE_MASK_ARM64_SVE (UI64(1) << (XSTATE_ARM64_SVE_BIT)) #define CONTEXT_ContextFlags 0 #define CONTEXT_Cpsr CONTEXT_ContextFlags+4 diff --git a/src/coreclr/pal/src/arch/arm64/context2.S b/src/coreclr/pal/src/arch/arm64/context2.S index 4bfde2f19fbcb4..5cc537ab84bca9 100644 --- a/src/coreclr/pal/src/arch/arm64/context2.S +++ b/src/coreclr/pal/src/arch/arm64/context2.S @@ -114,7 +114,7 @@ LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT): b.ne LOCAL_LABEL(Done_CONTEXT_SVE) ldr x1, [x0, CONTEXT_XSTATEFEATURESMASK_OFFSET] - tbz x1, #XSTATE_SVE_BIT, LOCAL_LABEL(Done_CONTEXT_SVE) + tbz x1, #XSTATE_ARM64_SVE_BIT, LOCAL_LABEL(Done_CONTEXT_SVE) add x0, x0, CONTEXT_SVE_OFFSET str p0, [x0, CONTEXT_P0_VL, MUL VL] @@ -195,7 +195,7 @@ LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): tbz w17, #CONTEXT_XSTATE_BIT, LOCAL_LABEL(No_Restore_CONTEXT_SVE) ldr w17, [x16, CONTEXT_XSTATEFEATURESMASK_OFFSET] - tbz w17, #XSTATE_SVE_BIT, LOCAL_LABEL(No_Restore_CONTEXT_SVE) + tbz w17, #XSTATE_ARM64_SVE_BIT, LOCAL_LABEL(No_Restore_CONTEXT_SVE) add x16, x16, CONTEXT_SVE_OFFSET ldr p0, [x16, CONTEXT_FFR_VL, MUL VL] diff --git a/src/coreclr/pal/src/exception/machexception.cpp b/src/coreclr/pal/src/exception/machexception.cpp index e3fd0de760ddbc..5f1bf97605784b 100644 --- a/src/coreclr/pal/src/exception/machexception.cpp +++ b/src/coreclr/pal/src/exception/machexception.cpp @@ -689,7 +689,7 @@ HijackFaultingThread( void **targetSP = (void **)threadContext.Rsp; #elif defined(HOST_ARM64) - threadContext.ContextFlags = CONTEXT_FLOATING_POINT; + threadContext.ContextFlags = CONTEXT_FLOATING_POINT | CONTEXT_XSTATE; CONTEXT_GetThreadContextFromThreadState(ARM_NEON_STATE64, (thread_state_t)&exceptionInfo.FloatState, &threadContext); threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER; diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp index 5112d8469b0984..2abec3970f1e02 100644 --- a/src/coreclr/pal/src/thread/context.cpp +++ b/src/coreclr/pal/src/thread/context.cpp @@ -817,7 +817,7 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native) //TODO-SVE: This only handles vector lengths of 128bits. if (CONTEXT_GetSveLengthFromOS() == 16) { - _ASSERT((lpContext->XStateFeaturesMask & XSTATE_MASK_SVE) == XSTATE_MASK_SVE); + _ASSERT((lpContext->XStateFeaturesMask & XSTATE_MASK_ARM64_SVE) == XSTATE_MASK_ARM64_SVE); uint16_t vq = sve_vq_from_vl(lpContext->Vl); @@ -1169,7 +1169,7 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex uint16_t vq = sve_vq_from_vl(sve->vl); - lpContext->XStateFeaturesMask |= XSTATE_MASK_SVE; + lpContext->XStateFeaturesMask |= XSTATE_MASK_ARM64_SVE; //Note: Size of ffr register is SVE_SIG_FFR_SIZE(vq) bytes. lpContext->Ffr = *(WORD*) (((uint8_t*)sve) + SVE_SIG_FFR_OFFSET(vq)); diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index c7f19158bdbdb5..3a1ab790f4753f 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -396,6 +396,17 @@ BOOL g_singleVersionHosting; typedef BOOL(WINAPI* PINITIALIZECONTEXT2)(PVOID Buffer, DWORD ContextFlags, PCONTEXT* Context, PDWORD ContextLength, ULONG64 XStateCompactionMask); PINITIALIZECONTEXT2 g_pfnInitializeContext2 = NULL; +#ifdef TARGET_ARM64 +typedef DWORD64(WINAPI* PGETENABLEDXSTATEFEATURES)(); +PGETENABLEDXSTATEFEATURES g_pfnGetEnabledXStateFeatures = NULL; + +typedef BOOL(WINAPI* PGETXSTATEFEATURESMASK)(PCONTEXT Context, PDWORD64 FeatureMask); +PGETXSTATEFEATURESMASK g_pfnGetXStateFeaturesMask = NULL; + +typedef BOOL(WINAPI* PSETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask); +PSETXSTATEFEATURESMASK g_pfnSetXStateFeaturesMask = NULL; +#endif // TARGET_ARM64 + static BOOLEAN WINAPI RtlDllShutdownInProgressFallback() { return g_fProcessDetach; @@ -412,6 +423,12 @@ void InitializeOptionalWindowsAPIPointers() HMODULE hm = GetModuleHandleW(_T("kernel32.dll")); g_pfnInitializeContext2 = (PINITIALIZECONTEXT2)GetProcAddress(hm, "InitializeContext2"); +#ifdef TARGET_ARM64 + g_pfnGetEnabledXStateFeatures = (PGETENABLEDXSTATEFEATURES)GetProcAddress(hm, "GetEnabledXStateFeatures"); + g_pfnGetXStateFeaturesMask = (PGETXSTATEFEATURESMASK)GetProcAddress(hm, "GetXStateFeaturesMask"); + g_pfnSetXStateFeaturesMask = (PSETXSTATEFEATURESMASK)GetProcAddress(hm, "SetXStateFeaturesMask"); +#endif // TARGET_ARM64 + hm = GetModuleHandleW(_T("ntdll.dll")); PRTLDLLSHUTDOWNINPROGRESS pfn = (PRTLDLLSHUTDOWNINPROGRESS)GetProcAddress(hm, "RtlDllShutdownInProgress"); if (pfn != NULL) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index 9cdb8689984339..e9b9ab99b3737f 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -26,7 +26,27 @@ ThreadSuspend::SUSPEND_REASON ThreadSuspend::m_suspendReason; #if defined(TARGET_WINDOWS) void* ThreadSuspend::g_returnAddressHijackTarget = NULL; -#endif +#endif // TARGET_WINDOWS + +#if defined(TARGET_ARM64) +// Mirror the XSTATE_ARM64_SVE flags from winnt.h + +#ifndef XSTATE_ARM64_SVE +#define XSTATE_ARM64_SVE (2) +#endif // XSTATE_ARM64_SVE + +#ifndef XSTATE_MASK_ARM64_SVE +#define XSTATE_MASK_ARM64_SVE (1ui64 << (XSTATE_ARM64_SVE)) +#endif // XSTATE_MASK_ARM64_SVE + +#ifndef CONTEXT_ARM64_XSTATE +#define CONTEXT_ARM64_XSTATE (CONTEXT_ARM64 | 0x20L) +#endif // CONTEXT_ARM64_XSTATE + +#ifndef CONTEXT_XSTATE +#define CONTEXT_XSTATE CONTEXT_ARM64_XSTATE +#endif // CONTEXT_XSTATE +#endif // TARGET_ARM64 // If you add any thread redirection function, make sure the debugger can 1) recognize the redirection // function, and 2) retrieve the original CONTEXT. See code:Debugger.InitializeHijackFunctionAddress and @@ -1956,20 +1976,36 @@ CONTEXT* AllocateOSContextHelper(BYTE** contextBuffer) { CONTEXT* pOSContext = NULL; -#if !defined(TARGET_UNIX) && (defined(TARGET_X86) || defined(TARGET_AMD64)) +#if !defined(TARGET_UNIX) && (defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)) DWORD context = CONTEXT_COMPLETE; - // Determine if the processor supports AVX so we could - // retrieve extended registers - DWORD64 FeatureMask = GetEnabledXStateFeatures(); - if ((FeatureMask & (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)) != 0) +#if defined(TARGET_X86) || defined(TARGET_AMD64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_AVX | XSTATE_MASK_AVX512; + const ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | XSTATE_MASK_MPX | xStateFeatureMask; +#elif defined(TARGET_ARM64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_ARM64_SVE; + const ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | xStateFeatureMask; +#endif + + // Determine if the processor supports extended features so we could retrieve those registers + DWORD64 FeatureMask = 0; + +#if defined(TARGET_X86) || defined(TARGET_AMD64) + FeatureMask = GetEnabledXStateFeatures(); +#elif defined(TARGET_ARM64) + if (g_pfnGetEnabledXStateFeatures != NULL) + { + FeatureMask = g_pfnGetEnabledXStateFeatures(); + } +#endif + + if ((FeatureMask & xStateFeatureMask) != 0) { context = context | CONTEXT_XSTATE; } // Retrieve contextSize by passing NULL for Buffer DWORD contextSize = 0; - ULONG64 xStateCompactionMask = XSTATE_MASK_LEGACY | XSTATE_MASK_AVX | XSTATE_MASK_MPX | XSTATE_MASK_AVX512; // The initialize call should fail but return contextSize BOOL success = g_pfnInitializeContext2 ? g_pfnInitializeContext2(NULL, context, NULL, &contextSize, xStateCompactionMask) : @@ -2005,7 +2041,6 @@ CONTEXT* AllocateOSContextHelper(BYTE** contextBuffer) } *contextBuffer = buffer; - #else pOSContext = new (nothrow) CONTEXT; pOSContext->ContextFlags = CONTEXT_COMPLETE; @@ -2896,17 +2931,20 @@ BOOL Thread::RedirectThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt) // Always get complete context, pCtx->ContextFlags are set during Initialization -#if defined(TARGET_X86) || defined(TARGET_AMD64) // Scenarios like GC stress may indirectly disable XState features in the pCtx // depending on the state at the time of GC stress interrupt. // - // Make sure that AVX feature mask is set, if supported. - // // This should not normally fail. // The system silently ignores any feature specified in the FeatureMask // which is not enabled on the processor. - SetXStateFeaturesMask(pCtx, (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)); -#endif //defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) + SetXStateFeaturesMask(pCtx, XSTATE_MASK_AVX | XSTATE_MASK_AVX512); +#elif defined(TARGET_ARM64) + if (g_pfnSetXStateFeaturesMask != NULL) + { + g_pfnSetXStateFeaturesMask(pCtx, XSTATE_MASK_ARM64_SVE); + } +#endif // Make sure we specify CONTEXT_EXCEPTION_REQUEST to detect "trap frame reporting". pCtx->ContextFlags |= CONTEXT_EXCEPTION_REQUEST; @@ -3026,14 +3064,23 @@ BOOL Thread::RedirectCurrentThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt, CONT // Get and save the thread's context BOOL success = TRUE; -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) // This method is called for GC stress interrupts in managed code. // The current context may have various XState features, depending on what is used/dirty, - // but only AVX feature may contain live data. (that could change with new features in JIT) + // but only some features may contain live data. (that could change with new features in JIT) // Besides pCtx may not have space to store other features. - // So we will mask out everything but AVX. + // So we will mask out everything but those we are known to use. DWORD64 srcFeatures = 0; + +#if defined(TARGET_X86) || defined(TARGET_AMD64) success = GetXStateFeaturesMask(pCurrentThreadCtx, &srcFeatures); +#elif defined(TARGET_ARM64) + if (g_pfnGetXStateFeaturesMask != NULL) + { + success = g_pfnGetXStateFeaturesMask(pCurrentThreadCtx, &srcFeatures); + } +#endif + _ASSERTE(success); if (!success) return FALSE; @@ -3041,7 +3088,21 @@ BOOL Thread::RedirectCurrentThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt, CONT // Get may return 0 if no XState is set, which Set would not accept. if (srcFeatures != 0) { - success = SetXStateFeaturesMask(pCurrentThreadCtx, srcFeatures & (XSTATE_MASK_AVX | XSTATE_MASK_AVX512)); +#if defined(TARGET_X86) || defined(TARGET_AMD64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_AVX | XSTATE_MASK_AVX512; +#elif defined(TARGET_ARM64) + const DWORD64 xStateFeatureMask = XSTATE_MASK_ARM64_SVE; +#endif + +#if defined(TARGET_X86) || defined(TARGET_AMD64) + success = SetXStateFeaturesMask(pCurrentThreadCtx, srcFeatures & xStateFeatureMask); +#elif defined(TARGET_ARM64) + if (g_pfnSetXStateFeaturesMask != NULL) + { + success = g_pfnSetXStateFeaturesMask(pCurrentThreadCtx, srcFeatures & xStateFeatureMask); + } +#endif + _ASSERTE(success); if (!success) return FALSE; @@ -5850,7 +5911,7 @@ void Thread::ApcActivationCallback(ULONG_PTR Parameter) #if defined(TARGET_ARM64) // Windows incorrectly set the CONTEXT_UNWOUND_TO_CALL in the flags of the context it passes to us. - // That results in incorrect compensation of PC at some places and sometimes incorrect unwinding + // That results in incorrect compensation of PC at some places and sometimes incorrect unwinding // and GC holes due to that. pContext->ContextFlags &= ~CONTEXT_UNWOUND_TO_CALL; #endif // TARGET_ARM64 diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index 85069abdad9d97..5814aa1ee83483 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -164,7 +164,7 @@ class OBJECTREF { //------------------------------------------------------------- OBJECTREF& operator=(const OBJECTREF &objref); OBJECTREF& operator=(TADDR nul); - + // We use this delayed check to avoid ambiguous overload issues with TADDR // on platforms where NULL is defined as anything other than a uintptr_t constant // or nullptr_t exactly. @@ -299,7 +299,7 @@ GARY_DECL(TypeHandle, g_pPredefinedArrayTypes, ELEMENT_TYPE_MAX); // g_TrapReturningThreads == 0 disables thread polling/traping. // This allows to short-circuit further examining of thread states in the most // common scenario - when we are not interested in trapping anything. -// +// // The bit #1 is reserved for controlling thread suspension. // Setting bit #1 allows to atomically indicate/check that EE suspension is in progress. // There could be only one EE suspension in progress at a time. (it requires holding ThreadStore lock) @@ -640,6 +640,17 @@ GSCookie GetProcessGSCookie() { return *(RAW_KEYWORD(volatile) GSCookie *)(&s_gs typedef BOOL(WINAPI* PINITIALIZECONTEXT2)(PVOID Buffer, DWORD ContextFlags, PCONTEXT* Context, PDWORD ContextLength, ULONG64 XStateCompactionMask); extern PINITIALIZECONTEXT2 g_pfnInitializeContext2; +#ifdef TARGET_ARM64 +typedef DWORD64(WINAPI* PGETENABLEDXSTATEFEATURES)(); +extern PGETENABLEDXSTATEFEATURES g_pfnGetEnabledXStateFeatures; + +typedef BOOL(WINAPI* PGETXSTATEFEATURESMASK)(PCONTEXT Context, PDWORD64 FeatureMask); +extern PGETXSTATEFEATURESMASK g_pfnGetXStateFeaturesMask; + +typedef BOOL(WINAPI* PSETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask); +extern PSETXSTATEFEATURESMASK g_pfnSetXStateFeaturesMask; +#endif // TARGET_ARM64 + #ifdef TARGET_X86 typedef VOID(__cdecl* PRTLRESTORECONTEXT)(PCONTEXT ContextRecord, struct _EXCEPTION_RECORD* ExceptionRecord); extern PRTLRESTORECONTEXT g_pfnRtlRestoreContext;