Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-08-12 03:47:07 +0300
committerJan Vorlicek <janvorli@microsoft.com>2016-08-12 03:47:07 +0300
commitbe6ba12cce4c4404729c4d4a5b462b458a36b8dc (patch)
treeaf8a94986645fbd3098714b5d7d893e620a7a77c /src/Native/Runtime/i386
parent91a33c98269c5f06ec980c30ef79fec06fccf3ce (diff)
This fixes debugger step-in in the interface dispatch changes
[tfs-changeset: 1622102]
Diffstat (limited to 'src/Native/Runtime/i386')
-rw-r--r--src/Native/Runtime/i386/AsmMacros.inc6
-rw-r--r--src/Native/Runtime/i386/ManagedCalloutThunk.asm64
-rw-r--r--src/Native/Runtime/i386/StubDispatch.asm90
-rw-r--r--src/Native/Runtime/i386/UniversalTransition.asm17
4 files changed, 25 insertions, 152 deletions
diff --git a/src/Native/Runtime/i386/AsmMacros.inc b/src/Native/Runtime/i386/AsmMacros.inc
index 7c8f4d372..bc8051d2b 100644
--- a/src/Native/Runtime/i386/AsmMacros.inc
+++ b/src/Native/Runtime/i386/AsmMacros.inc
@@ -139,12 +139,6 @@ PTFF_RAX_IS_GCREF equ 00010000h ;; iff PTFF_SAVE_RAX: set -> eax is Obje
PTFF_RAX_IS_BYREF equ 00020000h ;; iff PTFF_SAVE_RAX: set -> eax is ByRef, clear -> eax is Object or scalar
;;
-;; Offset from FP (ebp) where the managed callout thunk (ManagedCallout2 and possibly others in the future)
-;; store a pointer to a transition frame.
-;;
-MANAGED_CALLOUT_THUNK_TRANSITION_FRAME_POINTER_OFFSET equ -4
-
-;;
;; Rename fields of nested structs
;;
OFFSETOF__Thread__m_alloc_context__alloc_ptr equ OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__alloc_context__alloc_ptr
diff --git a/src/Native/Runtime/i386/ManagedCalloutThunk.asm b/src/Native/Runtime/i386/ManagedCalloutThunk.asm
deleted file mode 100644
index 8b0a181e3..000000000
--- a/src/Native/Runtime/i386/ManagedCalloutThunk.asm
+++ /dev/null
@@ -1,64 +0,0 @@
-;; 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.
-
- .586
- .model flat
- option casemap:none
- .code
-
-
-include AsmMacros.inc
-
-;;
-;; Defines a small assembly thunk designed to be used when unmanaged code in the runtime calls out to managed
-;; code. In such cases the stack walker needs to be able to bridge the unmanaged gap in the stack between the
-;; callout and whatever managed code initially entered the runtime. This thunk makes that goal achievable by
-;; (a) exporting a well-known address in the thunk that will be the result of unwinding from the callout (so
-;; the stack frame iterator knows when its hit this case) and (b) placing a copy of a pointer to a transition
-;; frame saved when the previous managed caller entered the runtime into a well-known location relative to the
-;; thunk's frame, enabling the stack frame iterator to recover the transition frame address and use it to
-;; re-initialize the stack walk at the previous managed caller.
-;;
-;; If we end up with more cases of this (currently it's used only for the ICastable extension point for
-;; interface dispatch) then we might decide to produce a general routine which can handle an arbitrary number
-;; of arguments to the target method. For now we'll just implement the case we need, which takes two regular
-;; arguments (that's the 2 in the ManagedCallout2 name).
-;;
-;; Inputs:
-;; ecx : Argument 1 to target method
-;; edx : Argument 2 to target method
-;; [esp + 4] : Target method address
-;; [esp + 8] : Pointer to previous managed method's transition frame into the runtime
-;;
-FASTCALL_FUNC ManagedCallout2, 16
-
- ;; Push an EBP frame. Apart from making it easier to walk the stack the stack frame iterator locates
- ;; the transition frame for the previous managed caller relative to the frame pointer to keep the code
- ;; architecture independent.
- push ebp
- mov ebp, esp
-
- ;; Stash the previous transition frame's address immediately on top of the old ebp value. This
- ;; position is important; the stack frame iterator knows about this setup.
-.erre MANAGED_CALLOUT_THUNK_TRANSITION_FRAME_POINTER_OFFSET eq -4
- mov eax, [ebp + 0Ch]
- push eax
-
- ;; Grab the target method's address. Since the arguments are already set up in the correct registers
- ;; we can just go. The _ReturnFromManagedCallout2 label must immediately follow the call instruction.
- mov eax, [ebp + 08h]
- call eax
-LABELED_RETURN_ADDRESS ReturnFromManagedCallout2
-
- ;; Pop the ebp frame and return.
- mov esp, ebp
- pop ebp
- ret 8
-
-FASTCALL_ENDFUNC
-
-PUBLIC _ReturnFromManagedCallout2
-
-
-END
diff --git a/src/Native/Runtime/i386/StubDispatch.asm b/src/Native/Runtime/i386/StubDispatch.asm
index accf90891..3e8426311 100644
--- a/src/Native/Runtime/i386/StubDispatch.asm
+++ b/src/Native/Runtime/i386/StubDispatch.asm
@@ -13,7 +13,8 @@ include AsmMacros.inc
ifdef FEATURE_CACHED_INTERFACE_DISPATCH
-EXTERN @RhpResolveInterfaceMethodCacheMiss@12 : PROC
+EXTERN RhpCidResolve : PROC
+EXTERN _RhpUniversalTransition_DebugStepTailCall@0 : PROC
;; Macro that generates code to check a single cache entry.
@@ -62,6 +63,7 @@ CurrentEntry = CurrentEntry + 1
;; eax currently contains the cache block. We need to point it back to the
;; indirection cell using the back pointer in the cache block
mov eax, [eax + OFFSETOF__InterfaceDispatchCache__m_pCell]
+ pop ebx
jmp InterfaceDispatchCacheMiss
StubName endp
@@ -80,81 +82,17 @@ DEFINE_INTERFACE_DISPATCH_STUB 64
;; Shared out of line helper used on cache misses.
InterfaceDispatchCacheMiss proc
+;; eax points at InterfaceDispatchCell
- ;; Push an ebp frame since it makes some of our later calculations easier.
- push ebp
- mov ebp, esp
-
- ;; Save argument registers while we call out to the C++ helper. Note that we depend on these registers
- ;; (which may contain GC references) being spilled before we build the PInvokeTransitionFrame below
- ;; due to the way we build a stack range to report to the GC conservatively during a collection.
- push ecx
- push edx
-
- ;; Build PInvokeTransitionFrame. This is only required if we end up resolving the interface method via
- ;; a callout to a managed ICastable method. In that instance we need to be able to cope with garbage
- ;; collections which in turn need to be able to walk the stack from the ICastable method, skip the
- ;; unmanaged runtime portions and resume walking at our caller. This frame provides both the means to
- ;; unwind to that caller and a place to spill callee saved registers in case they contain GC
- ;; references from the caller.
-
- ;; Calculate caller's esp: relative to ebp's current value we've pushed the old ebp, ebx and a return
- ;; address.
- lea edx, [ebp + (3 * 4)]
- push edx
-
- ;; Push callee saved registers. Note we've already pushed ebx but we need to do it here again so that
- ;; it is reported to the GC correctly if necessary. As such it's necessary to pushed the saved version
- ;; of ebx and make sure when we restore it we use this copy and discard the version that was initially
- ;; pushed (since its value may now be stale).
- push edi
- push esi
- mov edx, [ebp + 04h] ; Old RBX value
- push edx
-
- ;; Push flags.
- push PTFF_SAVE_ALL_PRESERVED + PTFF_SAVE_RSP
-
- ;; Leave space for the Thread* (stackwalker does not use this).
- push 0
-
- ;; The caller's ebp.
- push [ebp]
-
- ;; The caller's eip.
- push [ebp + 08h]
-
- ;; First argument is the instance we're dispatching on which is already in ecx.
-
- ;; Second argument is the dispatch data cell.
- ;; We still have this in eax
- mov edx, eax
-
- ;; The third argument is the address of the transition frame we build above. Currently it's at the top
- ;; of the stack so esp points to it.
- push esp
-
- call @RhpResolveInterfaceMethodCacheMiss@12
-
- ;; Recover callee-saved values from the transition frame in case a GC updated them.
- mov ebx, [esp + 010h]
- mov esi, [esp + 014h]
- mov edi, [esp + 018h]
-
- ;; Restore real argument registers.
- mov edx, [ebp - 08h]
- mov ecx, [ebp - 04h]
-
- ;; Remove the transition and ebp frames from the stack.
- mov esp, ebp
- pop ebp
-
- ;; Discard the space where ebx was pushed on entry, its value is now potentially stale.
- add esp, 4
-
- ;; Final target address is in eax.
- jmp eax
+;; Setup call to Universal Transition thunk
+ push ebp
+ mov ebp, esp
+ push eax ; First argument (Interface Dispatch Cell)
+ lea eax, [RhpCidResolve]
+ push eax ; Second argument (RhpCidResolve)
+;; Jump to Universal Transition
+ jmp _RhpUniversalTransition_DebugStepTailCall@0
InterfaceDispatchCacheMiss endp
;; Out of line helper used when we try to interface dispatch on a null pointer. Sets up the stack so the
@@ -171,10 +109,6 @@ RhpInterfaceDispatchNullReference endp
RhpInitialInterfaceDispatch proc public
ALTERNATE_ENTRY RhpInitialDynamicInterfaceDispatch
- ;; Mainly we just tail call to the cache miss helper. But this helper expects that ebx has been pushed
- ;; on the stack.
- push ebx
-
jmp InterfaceDispatchCacheMiss
RhpInitialInterfaceDispatch endp
diff --git a/src/Native/Runtime/i386/UniversalTransition.asm b/src/Native/Runtime/i386/UniversalTransition.asm
index 3f69d463b..1c16e369d 100644
--- a/src/Native/Runtime/i386/UniversalTransition.asm
+++ b/src/Native/Runtime/i386/UniversalTransition.asm
@@ -55,13 +55,15 @@ ifdef FEATURE_DYNAMIC_CODE
; everything between the base of the IntArgRegs and the top of the StackPassedArgs.
;
-FASTCALL_FUNC RhpUniversalTransition_FAKE_ENTRY, 0
+UNIVERSAL_TRANSITION macro FunctionName
+
+FASTCALL_FUNC Rhp&FunctionName&_FAKE_ENTRY, 0
; Set up an ebp frame
push ebp
mov ebp, esp
push eax
push eax
-ALTERNATE_ENTRY RhpUniversalTransition@0
+ALTERNATE_ENTRY Rhp&FunctionName&@0
push ecx
push edx
@@ -72,7 +74,7 @@ ALTERNATE_ENTRY RhpUniversalTransition@0
mov edx, [ebp-4] ; Get the extra argument to pass to the callee
lea ecx, [ebp-10h] ; Get pointer to edx value pushed above
call eax
-LABELED_RETURN_ADDRESS ReturnFromUniversalTransition
+LABELED_RETURN_ADDRESS ReturnFrom&FunctionName
pop edx
pop ecx
@@ -81,7 +83,14 @@ LABELED_RETURN_ADDRESS ReturnFromUniversalTransition
jmp eax
FASTCALL_ENDFUNC
-
+ endm
+
+ ; To enable proper step-in behavior in the debugger, we need to have two instances
+ ; of the thunk. For the first one, the debugger steps into the call in the function,
+ ; for the other, it steps over it.
+ UNIVERSAL_TRANSITION UniversalTransition
+ UNIVERSAL_TRANSITION UniversalTransition_DebugStepTailCall
+
endif
end