Recover some lost EH performance on Unix amd64 (#90033)
authorJan Vorlicek <janvorli@microsoft.com>
Sun, 6 Aug 2023 10:07:55 +0000 (12:07 +0200)
committerGitHub <noreply@github.com>
Sun, 6 Aug 2023 10:07:55 +0000 (12:07 +0200)
* Improve EH performance on Unix amd64

Few months ago, a change to enable AVX512 on Unix was merged in.
That change has enlarged the CONTEXT structure significantly and
it was found that it has caused 6..17% regressions in exception handling
microbenchmarks.

This change gets some of the lost performance back by adding custom
copy constructor and assignment operator to the CONTEXT structure
and preventing copying of the AVX / AVX512 stuff if the source
context doesn't have it. I have observed 3..9% gain on my machine.

Close #84308

* Fix gcc build and size for non-xstate case

* Fix yet another gcc break

* Fix build break

* Revert the gcc fixes and disable the warning

The zeroing of CONTEXT structure is used at too many places and
it is valid, so rather than trying to modify all the places by
using placement new, just disable the warning for gcc.

eng/native/configurecompiler.cmake
src/coreclr/debug/ee/debugger.cpp
src/coreclr/pal/inc/pal.h
src/coreclr/pal/src/thread/context.cpp
src/coreclr/vm/exceptionhandling.cpp

index a10297b..1838110 100644 (file)
@@ -598,14 +598,13 @@ if (CLR_CMAKE_HOST_UNIX)
     add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-stringop-overflow>)
     add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-restrict>)
     add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-Wno-stringop-truncation>)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-class-memaccess>)
 
     if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
       # this warning is only reported by g++ 11 in debug mode when building
       # src/coreclr/vm/stackingallocator.h. It is a false-positive, fixed in g++ 12.
       # see: https://github.com/dotnet/runtime/pull/69188#issuecomment-1136764770
       add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-placement-new>)
-
-      add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-class-memaccess>)
     endif()
 
     if (CMAKE_CXX_COMPILER_ID)
index 073d758..7581c0c 100644 (file)
@@ -6539,7 +6539,7 @@ HRESULT Debugger::LaunchDebuggerForUser(Thread * pThread, EXCEPTION_POINTERS * p
 // once and leave them set without the risk of clobbering something we care about.
 JIT_DEBUG_INFO   Debugger::s_DebuggerLaunchJitInfo = {0};
 EXCEPTION_RECORD Debugger::s_DebuggerLaunchJitInfoExceptionRecord = {0};
-CONTEXT          Debugger::s_DebuggerLaunchJitInfoContext = {0};
+CONTEXT          Debugger::s_DebuggerLaunchJitInfoContext = {};
 
 //----------------------------------------------------------------------------
 //
index 7bc67f1..92455bc 100644 (file)
@@ -1531,6 +1531,14 @@ typedef struct _XMM_SAVE_AREA32 {
 
 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
 
+    _CONTEXT() = default;
+    _CONTEXT(const _CONTEXT& ctx)
+    {
+        *this = ctx;
+    }
+
+    _CONTEXT& operator=(const _CONTEXT& ctx);
+
     //
     // Register parameter home addresses.
     //
index 07afeea..a9ed8c2 100644 (file)
@@ -1880,3 +1880,29 @@ DBG_FlushInstructionCache(
 #endif
     return TRUE;
 }
+
+#ifdef HOST_AMD64
+CONTEXT& CONTEXT::operator=(const CONTEXT& ctx)
+{
+    size_t copySize;
+    if (ctx.ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+    {
+        if ((ctx.XStateFeaturesMask & XSTATE_MASK_AVX512) == XSTATE_MASK_AVX512)
+        {
+            copySize = sizeof(CONTEXT);
+        }
+        else
+        {
+            copySize = offsetof(CONTEXT, KMask0);
+        }
+    }
+    else
+    {
+        copySize = offsetof(CONTEXT, XStateFeaturesMask);
+    }
+
+    memcpy(this, &ctx, copySize);
+
+    return *this;
+}
+#endif // HOST_AMD64
index 2e93beb..cec1175 100644 (file)
@@ -1286,7 +1286,7 @@ bool FixNonvolatileRegisters(UINT_PTR  uOriginalSP,
     }
     CONTRACTL_END;
 
-    CONTEXT _ctx = {0};
+    CONTEXT _ctx = {};
 
     // Ctor will initialize it to NULL
     REGDISPLAY regdisp;