diff options
author | Fadi Hanna <fadim@microsoft.com> | 2019-04-01 12:07:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-01 12:07:47 -0700 |
commit | bc9248cad132fa01dd2b641b6b22849bc7a05457 (patch) | |
tree | 5d1ee71059353a66004fc7a4d2501a7452db849f /src/vm/i386 | |
parent | ff43a803a814eaaa5eba02cafa4a91def3e4c7be (diff) | |
download | coreclr-bc9248cad132fa01dd2b641b6b22849bc7a05457.tar.gz coreclr-bc9248cad132fa01dd2b641b6b22849bc7a05457.tar.bz2 coreclr-bc9248cad132fa01dd2b641b6b22849bc7a05457.zip |
Enable R2R compilation/inlining of PInvoke stubs where no marshalling is required (#22560)
* These changes enable the inlining of some PInvokes that do not require any marshalling. With inlined pinvokes, R2R performance should become slightly better, since we'll avoid jitting some of the pinvoke IL stubs that we jit today for S.P.CoreLib. Performance gains not yet measured.
* Added JIT_PInvokeBegin/End helpers for all architectures. Linux stubs not yet implemented
* Add INLINE_GETTHREAD for arm/arm64
* Set CORJIT_FLAG_USE_PINVOKE_HELPERS jit flag for ReadyToRun compilations
* Updating R2RDump tool to handle pinvokes
Diffstat (limited to 'src/vm/i386')
-rw-r--r-- | src/vm/i386/AsmMacros.inc | 23 | ||||
-rw-r--r-- | src/vm/i386/PInvokeStubs.asm | 111 | ||||
-rw-r--r-- | src/vm/i386/asmconstants.h | 17 | ||||
-rw-r--r-- | src/vm/i386/pinvokestubs.S | 31 |
4 files changed, 182 insertions, 0 deletions
diff --git a/src/vm/i386/AsmMacros.inc b/src/vm/i386/AsmMacros.inc new file mode 100644 index 0000000000..86ce6ac626 --- /dev/null +++ b/src/vm/i386/AsmMacros.inc @@ -0,0 +1,23 @@ +; Licensed to the .NET Foundation under one or more agreements. +; The .NET Foundation licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +; +; Define macros to build unwind data for prologues. +; + +__tls_array equ 2Ch ;; offsetof(TEB, ThreadLocalStoragePointer) + + +INLINE_GETTHREAD macro destReg, trashReg + ASSUME fs : NOTHING + + EXTERN __tls_index:DWORD + EXTERN _gCurrentThreadInfo:DWORD + + mov destReg, [__tls_index] + mov trashReg, fs:[__tls_array] + mov trashReg, [trashReg + destReg * 4] + add trashReg, SECTIONREL _gCurrentThreadInfo + mov destReg, [trashReg] +endm diff --git a/src/vm/i386/PInvokeStubs.asm b/src/vm/i386/PInvokeStubs.asm new file mode 100644 index 0000000000..7295c568e7 --- /dev/null +++ b/src/vm/i386/PInvokeStubs.asm @@ -0,0 +1,111 @@ +; Licensed to the .NET Foundation under one or more agreements. +; The .NET Foundation licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +; *********************************************************************** +; File: PInvokeStubs.asm +; +; *********************************************************************** +; +; *** NOTE: If you make changes to this file, propagate the changes to +; PInvokeStubs.s in this directory + +; This contains JITinterface routines that are 100% x86 assembly + + .586 + .model flat + + include asmconstants.inc + include asmmacros.inc + + option casemap:none + .code + +extern _s_gsCookie:DWORD +extern ??_7InlinedCallFrame@@6B@:DWORD +extern _g_TrapReturningThreads:DWORD + +extern @JIT_PInvokeEndRarePath@0:proc + +.686P +.XMM + +; +; in: +; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right +; before actual InlinedCallFrame data) +; +; +_JIT_PInvokeBegin@4 PROC public + + mov eax, dword ptr [_s_gsCookie] + mov dword ptr [ecx], eax + add ecx, SIZEOF_GSCookie + + ;; set first slot to the value of InlinedCallFrame::`vftable' (checked by runtime code) + lea eax,[??_7InlinedCallFrame@@6B@] + mov dword ptr [ecx], eax + + mov dword ptr [ecx + InlinedCallFrame__m_Datum], 0 + + + mov eax, esp + add eax, 4 + mov dword ptr [ecx + InlinedCallFrame__m_pCallSiteSP], eax + mov dword ptr [ecx + InlinedCallFrame__m_pCalleeSavedFP], ebp + + mov eax, [esp] + mov dword ptr [ecx + InlinedCallFrame__m_pCallerReturnAddress], eax + + ;; edx = GetThread(). Trashes eax + INLINE_GETTHREAD edx, eax + + ;; pFrame->m_Next = pThread->m_pFrame; + mov eax, dword ptr [edx + Thread_m_pFrame] + mov dword ptr [ecx + Frame__m_Next], eax + + ;; pThread->m_pFrame = pFrame; + mov dword ptr [edx + Thread_m_pFrame], ecx + + ;; pThread->m_fPreemptiveGCDisabled = 0 + mov dword ptr [edx + Thread_m_fPreemptiveGCDisabled], 0 + + ret + +_JIT_PInvokeBegin@4 ENDP + +; +; in: +; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right +; before actual InlinedCallFrame data) +; +; +_JIT_PInvokeEnd@4 PROC public + + add ecx, SIZEOF_GSCookie + + ;; edx = GetThread(). Trashes eax + INLINE_GETTHREAD edx, eax + + ;; ecx = pFrame + ;; edx = pThread + + ;; pThread->m_fPreemptiveGCDisabled = 1 + mov dword ptr [edx + Thread_m_fPreemptiveGCDisabled], 1 + + ;; Check return trap + cmp [_g_TrapReturningThreads], 0 + jnz RarePath + + ;; pThread->m_pFrame = pFrame->m_Next + mov eax, dword ptr [ecx + Frame__m_Next] + mov dword ptr [edx + Thread_m_pFrame], eax + + ret + +RarePath: + jmp @JIT_PInvokeEndRarePath@0 + +_JIT_PInvokeEnd@4 ENDP + + end diff --git a/src/vm/i386/asmconstants.h b/src/vm/i386/asmconstants.h index 9b4735b5df..136a31e7b1 100644 --- a/src/vm/i386/asmconstants.h +++ b/src/vm/i386/asmconstants.h @@ -339,6 +339,23 @@ ASMCONSTANTS_C_ASSERT(Thread__m_pDomain == offsetof(Thread, m_pDomain)); #endif +// For JIT_PInvokeBegin and JIT_PInvokeEnd helpers +#define Frame__m_Next 0x04 +ASMCONSTANTS_C_ASSERT(Frame__m_Next == offsetof(Frame, m_Next)); + +#define InlinedCallFrame__m_Datum 0x08 +ASMCONSTANTS_C_ASSERT(InlinedCallFrame__m_Datum == offsetof(InlinedCallFrame, m_Datum)); + +#define InlinedCallFrame__m_pCallSiteSP 0x0C +ASMCONSTANTS_C_ASSERT(InlinedCallFrame__m_pCallSiteSP == offsetof(InlinedCallFrame, m_pCallSiteSP)); + +#define InlinedCallFrame__m_pCallerReturnAddress 0x10 +ASMCONSTANTS_C_ASSERT(InlinedCallFrame__m_pCallerReturnAddress == offsetof(InlinedCallFrame, m_pCallerReturnAddress)); + +#define InlinedCallFrame__m_pCalleeSavedFP 0x14 +ASMCONSTANTS_C_ASSERT(InlinedCallFrame__m_pCalleeSavedFP == offsetof(InlinedCallFrame, m_pCalleeSavedFP)); + + #ifdef FEATURE_STUBS_AS_IL // DelegateObject from src/vm/object.h #define DelegateObject___target 0x04 // offset 0 is m_pMethTab of base class Object diff --git a/src/vm/i386/pinvokestubs.S b/src/vm/i386/pinvokestubs.S new file mode 100644 index 0000000000..74b20b51bb --- /dev/null +++ b/src/vm/i386/pinvokestubs.S @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.intel_syntax noprefix +#include "unixasmmacros.inc" +#include "asmconstants.h" + +// +// IN: +// InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right +// before actual InlinedCallFrame data) +// +// +LEAF_ENTRY JIT_PInvokeBegin, _TEXT + // Not yet supported + int 3 + ret +LEAF_END JIT_PInvokeBegin, _TEXT + +// +// IN: +// InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right +// before actual InlinedCallFrame data) +// +// +LEAF_ENTRY JIT_PInvokeEnd, _TEXT + // Not yet supported + int 3 + ret +LEAF_END JIT_PInvokeEnd, _TEXT |