summaryrefslogtreecommitdiff
path: root/src/vm/i386
diff options
context:
space:
mode:
authorFadi Hanna <fadim@microsoft.com>2019-04-01 12:07:47 -0700
committerGitHub <noreply@github.com>2019-04-01 12:07:47 -0700
commitbc9248cad132fa01dd2b641b6b22849bc7a05457 (patch)
tree5d1ee71059353a66004fc7a4d2501a7452db849f /src/vm/i386
parentff43a803a814eaaa5eba02cafa4a91def3e4c7be (diff)
downloadcoreclr-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.inc23
-rw-r--r--src/vm/i386/PInvokeStubs.asm111
-rw-r--r--src/vm/i386/asmconstants.h17
-rw-r--r--src/vm/i386/pinvokestubs.S31
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