diff options
author | Lubomir Litchev <llitchev@live.com> | 2015-02-19 11:42:30 -0800 |
---|---|---|
committer | Lubomir Litchev <lubol@microsoft.com> | 2015-10-20 14:20:36 -0700 |
commit | 378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5 (patch) | |
tree | b83aec8f77caeb9ca94c6d7505a548b93cdb7259 /src/vm/threads.h | |
parent | 3015ff7afb4936a1c5c5856daa4e3482e6b390a9 (diff) | |
download | coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.tar.gz coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.tar.bz2 coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.zip |
Implementation of System V ABI struct passing.
This PR adds support for System V x86_64 ABI classification and calling
convention to the VM and the Jit, including, but not limited to Ubuntu
Linux and Mac OS X.
The general rules outlined in the System V x86_64 ABI (described at
http://www.x86-64.org/documentation/abi.pdf) are followed with a few
little exceptions, described below:
1. The hidden argument for by-value passed structs is always after
the ÎéÎíthisÎéÎí parameter (if there is one.). This is a difference with
the Sysetem V ABI and affects only the internal jit calling conventions.
For PInvoke calls the hidden argument is always the first parameter since
there is no ÎéÎíthisÎéÎí parameter in this case.
2. Managed structs that have no fields are always passed by-value on
the stack.
3. The jit proactively generates frame register frames (with RBP as a
frame register) in order to aid the native OS tooling for stack unwinding
and the like.
Diffstat (limited to 'src/vm/threads.h')
-rw-r--r-- | src/vm/threads.h | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/vm/threads.h b/src/vm/threads.h index 0ab550f741..da94c0e2ce 100644 --- a/src/vm/threads.h +++ b/src/vm/threads.h @@ -689,6 +689,9 @@ void InitThreadManager(); 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 #ifdef _TARGET_X86_ EXTERN_C void __stdcall OnHijackFloatingPointTripThread(); // hijacked JIT code is returning an FP value @@ -1017,6 +1020,9 @@ typedef DWORD (*AppropriateWaitFunc) (void *args, DWORD timeout, DWORD option); 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 #endif // FEATURE_HIJACK // This is the code we pass around for Thread.Interrupt, mainly for assertions @@ -1067,7 +1073,9 @@ class Thread: public IUnknown 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 #ifdef PLATFORM_UNIX friend void PALAPI HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext); #endif // PLATFORM_UNIX @@ -5553,6 +5561,24 @@ public: _ASSERTE(pAllLoggedTypes != NULL ? m_pAllLoggedTypes == NULL : TRUE); m_pAllLoggedTypes = pAllLoggedTypes; } +#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING +private: + EEClass* m_pHijackReturnTypeClass; +public: + EEClass* GetHijackReturnTypeClass() + { + LIMITED_METHOD_CONTRACT; + + return m_pHijackReturnTypeClass; + } + + void SetHijackReturnTypeClass(EEClass* pClass) + { + LIMITED_METHOD_CONTRACT; + + m_pHijackReturnTypeClass = pClass; + } +#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING }; // End of class Thread |