diff options
author | Jeff Greene <hippiehunterenator@gmail.com> | 2017-09-15 22:51:40 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-09-15 22:51:40 +0300 |
commit | 3a1a99acefc9b84182ff5ebba254246d557e7163 (patch) | |
tree | 4e26b3dfdf83058493bd5ea1e72486334cb4c0ce /src/Native | |
parent | 9b22fdfd6c714d19f3e2c22e1db85727097e5dcb (diff) |
Implemented portable pinvoke infrastructure for CppCodeGen (#4503)
Diffstat (limited to 'src/Native')
-rw-r--r-- | src/Native/Bootstrap/CppCodeGen.h | 17 | ||||
-rw-r--r-- | src/Native/Bootstrap/common.h | 11 | ||||
-rw-r--r-- | src/Native/Bootstrap/main.cpp | 13 | ||||
-rw-r--r-- | src/Native/Runtime/inc/rhbinder.h | 15 | ||||
-rw-r--r-- | src/Native/Runtime/portable.cpp | 13 | ||||
-rw-r--r-- | src/Native/Runtime/thread.cpp | 41 | ||||
-rw-r--r-- | src/Native/Runtime/thread.h | 3 |
7 files changed, 94 insertions, 19 deletions
diff --git a/src/Native/Bootstrap/CppCodeGen.h b/src/Native/Bootstrap/CppCodeGen.h index 65ef9c0a5..c1ef78eb3 100644 --- a/src/Native/Bootstrap/CppCodeGen.h +++ b/src/Native/Bootstrap/CppCodeGen.h @@ -41,4 +41,19 @@ inline double __uint64_to_double(uint64_t v) return val.d; } -#endif // __CPP_CODE_GEN_H +struct ReversePInvokeFrame +{ + void* m_savedPInvokeTransitionFrame; + void* m_savedThread; +}; + +struct PInvokeTransitionFrame +{ + void* m_RIP; + void* m_FramePointer; + void* m_pThread; // unused by stack crawler, this is so GetThread is only called once per method + // can be an invalid pointer in universal transition cases (which never need to call GetThread) + uint32_t m_dwFlags; // PInvokeTransitionFrameFlags + uint64_t m_PreservedRegs[]; +}; +#endif diff --git a/src/Native/Bootstrap/common.h b/src/Native/Bootstrap/common.h index 1aa9679e3..06a1ac5e6 100644 --- a/src/Native/Bootstrap/common.h +++ b/src/Native/Bootstrap/common.h @@ -73,15 +73,16 @@ struct RawEEType void* m_pIndirectionModule; }; -struct ReversePInvokeFrame -{ - void* m_savedPInvokeTransitionFrame; - void* m_savedThread; -}; +struct ReversePInvokeFrame; void __reverse_pinvoke(ReversePInvokeFrame* pRevFrame); void __reverse_pinvoke_return(ReversePInvokeFrame* pRevFrame); +struct PInvokeTransitionFrame; + +void __pinvoke(PInvokeTransitionFrame* pFrame); +void __pinvoke_return(PInvokeTransitionFrame* pFrame); + typedef size_t UIntNative; inline bool IS_ALIGNED(UIntNative val, UIntNative alignment) diff --git a/src/Native/Bootstrap/main.cpp b/src/Native/Bootstrap/main.cpp index a4726c176..8bb2bab23 100644 --- a/src/Native/Bootstrap/main.cpp +++ b/src/Native/Bootstrap/main.cpp @@ -151,6 +151,19 @@ void __reverse_pinvoke_return(ReversePInvokeFrame* pRevFrame) RhpReversePInvokeReturn2(pRevFrame); } +extern "C" void RhpPInvoke2(PInvokeTransitionFrame* pFrame); +extern "C" void RhpPInvokeReturn2(PInvokeTransitionFrame* pFrame); + +void __pinvoke(PInvokeTransitionFrame* pFrame) +{ + RhpPInvoke2(pFrame); +} + +void __pinvoke_return(PInvokeTransitionFrame* pFrame) +{ + RhpPInvokeReturn2(pFrame); +} + namespace System_Private_CoreLib { namespace System { class Object { diff --git a/src/Native/Runtime/inc/rhbinder.h b/src/Native/Runtime/inc/rhbinder.h index 695660a7d..49e39f6a7 100644 --- a/src/Native/Runtime/inc/rhbinder.h +++ b/src/Native/Runtime/inc/rhbinder.h @@ -631,6 +631,20 @@ enum PInvokeTransitionFrameFlags #pragma warning(push) #pragma warning(disable:4200) // nonstandard extension used: zero-sized array in struct/union class Thread; +#ifdef USE_PORTABLE_HELPERS +//the members of this structure are currently unused except m_pThread and exist only to allow compilation +//of StackFrameIterator their values are not currently being filled in and will require significant rework +//in order to satisfy the runtime requirements of StackFrameIterator +struct PInvokeTransitionFrame +{ + void* m_RIP; + void* m_FramePointer; + Thread* m_pThread; // unused by stack crawler, this is so GetThread is only called once per method + // can be an invalid pointer in universal transition cases (which never need to call GetThread) + uint32_t m_dwFlags; // PInvokeTransitionFrameFlags + uint64_t m_PreservedRegs[]; +}; +#else struct PInvokeTransitionFrame { #ifdef _TARGET_ARM_ @@ -646,6 +660,7 @@ struct PInvokeTransitionFrame #endif UIntTarget m_PreservedRegs[]; }; +#endif //USE_PORTABLE_HELPERS #pragma warning(pop) #ifdef _TARGET_AMD64_ diff --git a/src/Native/Runtime/portable.cpp b/src/Native/Runtime/portable.cpp index c6615b375..f1e04f980 100644 --- a/src/Native/Runtime/portable.cpp +++ b/src/Native/Runtime/portable.cpp @@ -208,19 +208,6 @@ COOP_PINVOKE_HELPER(Array *, RhpNewArrayAlign8, (EEType * pArrayEEType, int numE } #endif -// -// PInvoke -// -COOP_PINVOKE_HELPER(void, RhpPInvoke, (void* pFrame)) -{ - // TODO: RhpPInvoke -} - -COOP_PINVOKE_HELPER(void, RhpPInvokeReturn, (void* pFrame)) -{ - // TODO: RhpPInvokeReturn -} - COOP_PINVOKE_HELPER(void, RhpInitialDynamicInterfaceDispatch, ()) { ASSERT_UNCONDITIONALLY("NYI"); diff --git a/src/Native/Runtime/thread.cpp b/src/Native/Runtime/thread.cpp index 2c64a22fa..c106963fc 100644 --- a/src/Native/Runtime/thread.cpp +++ b/src/Native/Runtime/thread.cpp @@ -1158,6 +1158,31 @@ FORCEINLINE void Thread::InlineReversePInvokeReturn(ReversePInvokeFrame * pFrame } } +FORCEINLINE void Thread::InlinePInvoke(PInvokeTransitionFrame * pFrame) +{ + pFrame->m_pThread = this; + // set our mode to preemptive + m_pTransitionFrame = pFrame; + + // We need to prevent compiler reordering between above write and below read. + _ReadWriteBarrier(); + + // now check if we need to trap the thread + if (ThreadStore::IsTrapThreadsRequested()) + { + RhpWaitForSuspend2(); + } +} + +FORCEINLINE void Thread::InlinePInvokeReturn(PInvokeTransitionFrame * pFrame) +{ + m_pTransitionFrame = NULL; + if (ThreadStore::IsTrapThreadsRequested()) + { + RhpWaitForGC2(pFrame); + } +} + Object * Thread::GetThreadAbortException() { return m_threadAbortException; @@ -1287,4 +1312,20 @@ COOP_PINVOKE_HELPER(void, RhpReversePInvokeReturn2, (ReversePInvokeFrame * pFram pFrame->m_savedThread->InlineReversePInvokeReturn(pFrame); } +#ifdef USE_PORTABLE_HELPERS + +COOP_PINVOKE_HELPER(void, RhpPInvoke2, (PInvokeTransitionFrame* pFrame)) +{ + Thread * pCurThread = ThreadStore::RawGetCurrentThread(); + pCurThread->InlinePInvoke(pFrame); +} + +COOP_PINVOKE_HELPER(void, RhpPInvokeReturn2, (PInvokeTransitionFrame* pFrame)) +{ + //reenter cooperative mode + pFrame->m_pThread->InlinePInvokeReturn(pFrame); +} + +#endif //USE_PORTABLE_HELPERS + #endif // !DACCESS_COMPILE diff --git a/src/Native/Runtime/thread.h b/src/Native/Runtime/thread.h index e88881ff4..63a89c715 100644 --- a/src/Native/Runtime/thread.h +++ b/src/Native/Runtime/thread.h @@ -255,6 +255,9 @@ public: bool InlineTryFastReversePInvoke(ReversePInvokeFrame * pFrame); void InlineReversePInvokeReturn(ReversePInvokeFrame * pFrame); + void InlinePInvoke(PInvokeTransitionFrame * pFrame); + void InlinePInvokeReturn(PInvokeTransitionFrame * pFrame); + Object * GetThreadAbortException(); void SetThreadAbortException(Object *exception); |