summaryrefslogtreecommitdiff
path: root/src/vm/threads.h
diff options
context:
space:
mode:
authorSwaroop Sridhar <swaroops@microsoft.com>2016-07-20 16:50:22 -0700
committerSwaroop Sridhar <swaroops@microsoft.com>2016-08-05 14:05:55 -0700
commitd302e64bcb4ea445f6702c529f8a964df20ab494 (patch)
tree6fda2c392acf1d44aa4222ed6d9813533c455a0a /src/vm/threads.h
parent5b0953d50e9d0c6e388643210476d6a95a55a247 (diff)
downloadcoreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.tar.gz
coreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.tar.bz2
coreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.zip
Implement GcInfo v2
Ref #4379 This change implements GcInfo version 2 for all platforms that use the GcInfo library (all architectures other than X86). Changes are: 1) Defines ReturnKind enumeration for all platforms 2) Change the GcInfo encoder library to encode the ReturnKind and ReversePInvokeFrame slot 3) Change the CM's GcInfo decoder to encode the ReturnKind and ReversePInvokeFrame slot for GCINFO_VERSION 2 4) Some corrections to GCINFO_MEASUREments 5) Changes to RYU Jit to provide the correct information to the encoder 6) Changes to the VM to use the ReturnKind information while hijacking a thread - If ReturnKind is available from GcInfo, new hijack routines are used - Otherwise, fall back to old method (for compatibility) 7) Rework and simplify the thread hijack routines by scanning HijackFrames directly for gcroots 8) Supporting code to implement the above features. Returning Structs in multiple registers Hijacking for StructInRegs is currently only implemented for Unix SystemV ABI Multi-reg struct returns. However, the hijack-workers that use ReturnKind are ready to handle other platforms (ex: ARM/ARM64 Windows) once the corresponding HijackTripThread() assembly routines are defined. The New feature flag: FEATURE_MULTIREG_RETURN is set for platforms where a struct value can be returned in multiple registers [ex: Windows/Unix ARM/ARM64, Unix-AMD64] FEATURE_UNIX_AMD64_STRUCT_PASSING is a specific kind of FEATURE_MULTIREG_RETURN specified by SystemV ABI for AMD64 Compatibility with other JITs - All new GCInfo generated by RYU Jit is in GcInfo version 2 - All Ngen images must be regenerated with the new GcInfo version. - Ready-to-run images with old GcInfo will continue to work. - Jit64/X64 uses the GcInfo library, so it generates GcInfo version 2. However, it doesn't (yet) provide the data to encode the correct ReturnKind Similar is the case for ARM32 code running on JIT32, and any other JITs that may be using GcInfo library but not yet modified to use the new API. So, compatibility is achived using RT_Unset flag. When ReturnKind is RT_Unset, it means that the JIT did not set the ReturnKind in the GCInfo, and therefore the VM cannot rely on it, and must use other mechanisms (similar to GcInfo ver 1) to determine the Return type's GC information. Implement GC root scanning for Hijack-frames This change implements GCScanRoots() method for Hijacke-frames based on the ReturnKind information available from the GcInfo. If the exact ReturnKind is not available in the GcInfo, the thread-suspension logic will compute the ReturnKind based on the method-signature. As a result of this change, several hijack-helpers in the VM are cleaned up. There's only one implementation of HijackWorker() to handle all returnKinds. This change also simplifies the thread-hijack logic by using a single assembly helper OnHijackTripThread() in most cases. The only other helper used is for X86 floating point return values for save/restoring the top of the FP stack. ARM64 Only GcIndfo v2 is reliably supported for ARM64 platform. The changes to thread-hijack mechanism fixes #6494 for ARM64. No measurable change in JIT throughput, performance or native-image size from this change.
Diffstat (limited to 'src/vm/threads.h')
-rw-r--r--src/vm/threads.h64
1 files changed, 34 insertions, 30 deletions
diff --git a/src/vm/threads.h b/src/vm/threads.h
index e704c2b4f0..bd81c63432 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -143,6 +143,7 @@
#include "mscoree.h"
#include "appdomainstack.h"
#include "gc.h"
+#include "gcinfotypes.h"
#include <clrhost.h>
class Thread;
@@ -630,8 +631,9 @@ enum ThreadpoolThreadType
//
// Public functions for taking control of a thread at a safe point
//
-// VOID OnHijackObjectTripThread() - we've hijacked a JIT object-ref return
-// VOID OnHijackScalarTripThread() - we've hijacked a JIT non-object ref return
+// VOID OnHijackTripThread() - we've hijacked a JIT method
+// VOID OnHijackFPTripThread() - we've hijacked a JIT method,
+// and need to save the x87 FP stack.
//
//***************************************************************************
@@ -686,15 +688,9 @@ void InitThreadManager();
#ifdef FEATURE_HIJACK
-EXTERN_C void __stdcall OnHijackObjectTripThread(); // hijacked JIT code is returning an objectref
-EXTERN_C void __stdcall OnHijackInteriorPointerTripThread(); // hijacked JIT code is returning a byref
-EXTERN_C void __stdcall OnHijackScalarTripThread(); // hijacked JIT code is returning a non-objectref, non-FP
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-EXTERN_C void __stdcall OnHijackStructInRegsTripThread(); // hijacked JIT code is returning a struct in registers
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
-
+EXTERN_C void __stdcall OnHijackTripThread();
#ifdef _TARGET_X86_
-EXTERN_C void __stdcall OnHijackFloatingPointTripThread(); // hijacked JIT code is returning an FP value
+EXTERN_C void __stdcall OnHijackFPTripThread(); // hijacked JIT code is returning an FP value
#endif // _TARGET_X86_
#endif // FEATURE_HIJACK
@@ -1016,13 +1012,17 @@ typedef DWORD (*AppropriateWaitFunc) (void *args, DWORD timeout, DWORD option);
// unstarted System.Thread), then this instance can be found in the TLS
// of that physical thread.
-#ifdef FEATURE_HIJACK
-EXTERN_C void STDCALL OnHijackObjectWorker(HijackArgs * pArgs);
-EXTERN_C void STDCALL OnHijackInteriorPointerWorker(HijackArgs * pArgs);
-EXTERN_C void STDCALL OnHijackScalarWorker(HijackArgs * pArgs);
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-EXTERN_C void STDCALL OnHijackStructInRegsWorker(HijackArgs * pArgs);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+// FEATURE_MULTIREG_RETURN is set for platforms where a struct return value
+// [GcInfo v2 only] can be returned in multiple registers
+// ex: Windows/Unix ARM/ARM64, Unix-AMD64.
+//
+//
+// FEATURE_UNIX_AMD64_STRUCT_PASSING is a specific kind of FEATURE_MULTIREG_RETURN
+// [GcInfo v1 and v2] specified by SystemV ABI for AMD64
+//
+
+#ifdef FEATURE_HIJACK // Hijack function returning
+EXTERN_C void STDCALL OnHijackWorker(HijackArgs * pArgs);
#endif // FEATURE_HIJACK
// This is the code we pass around for Thread.Interrupt, mainly for assertions
@@ -1070,12 +1070,7 @@ class Thread: public IUnknown
#ifdef FEATURE_HIJACK
// MapWin32FaultToCOMPlusException needs access to Thread::IsAddrOfRedirectFunc()
friend DWORD MapWin32FaultToCOMPlusException(EXCEPTION_RECORD *pExceptionRecord);
- friend void STDCALL OnHijackObjectWorker(HijackArgs *pArgs);
- friend void STDCALL OnHijackInteriorPointerWorker(HijackArgs *pArgs);
- friend void STDCALL OnHijackScalarWorker(HijackArgs *pArgs);
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- friend void STDCALL OnHijackStructInRegsWorker(HijackArgs *pArgs);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+ friend void STDCALL OnHijackWorker(HijackArgs * pArgs);
#ifdef PLATFORM_UNIX
friend void PALAPI HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext);
#endif // PLATFORM_UNIX
@@ -5577,24 +5572,33 @@ public:
_ASSERTE(pAllLoggedTypes != NULL ? m_pAllLoggedTypes == NULL : TRUE);
m_pAllLoggedTypes = pAllLoggedTypes;
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+
+#ifdef FEATURE_HIJACK
private:
- EEClass* m_pHijackReturnTypeClass;
+
+ // By the time a frame is scanned by the runtime, m_pHijackReturnKind always
+ // identifies the gc-ness of the return register(s)
+ // If the ReturnKind information is not available from the GcInfo, the runtime
+ // computes it using the return types's class handle.
+
+ ReturnKind m_HijackReturnKind;
+
public:
- EEClass* GetHijackReturnTypeClass()
+
+ ReturnKind GetHijackReturnKind()
{
LIMITED_METHOD_CONTRACT;
- return m_pHijackReturnTypeClass;
+ return m_HijackReturnKind;
}
- void SetHijackReturnTypeClass(EEClass* pClass)
+ void SetHijackReturnKind(ReturnKind returnKind)
{
LIMITED_METHOD_CONTRACT;
- m_pHijackReturnTypeClass = pClass;
+ m_HijackReturnKind = returnKind;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_HIJACK
};
// End of class Thread