diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2016-02-06 01:40:03 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-02-06 01:55:29 +0300 |
commit | cfb63d562045aafa3a81a4834dd457ad60e81ba6 (patch) | |
tree | 879c790ab2a8f656dadc6a8a822399483eee4263 /src/Native/Runtime/i386 | |
parent | 08d78ae391e3eea9ad51265f867e42ee1649282d (diff) |
Add RhpCopyAnyWithWriteBarrier helper
[tfs-changeset: 1572900]
Diffstat (limited to 'src/Native/Runtime/i386')
-rw-r--r-- | src/Native/Runtime/i386/MiscStubs.asm | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/Native/Runtime/i386/MiscStubs.asm b/src/Native/Runtime/i386/MiscStubs.asm index 541c96f92..e6ffd4cc5 100644 --- a/src/Native/Runtime/i386/MiscStubs.asm +++ b/src/Native/Runtime/i386/MiscStubs.asm @@ -14,6 +14,7 @@ EXTERN @GetClasslibCCtorCheck@4 : PROC EXTERN _memcpy : PROC EXTERN _memcpyGCRefs : PROC EXTERN _memcpyGCRefsWithWriteBarrier : PROC +EXTERN _memcpyAnyWithWriteBarrier : PROC ;; ;; Currently called only from a managed executable once Main returns, this routine does whatever is needed to @@ -300,4 +301,47 @@ NothingToCopy: _RhpCopyMultibyteWithWriteBarrier ENDP +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void* __cdecl RhpCopyAnyWithWriteBarrier(void*, void*, size_t) +;; +;; The purpose of this wrapper is to hoist the potential null reference exceptions of copying memory up to a place where +;; the stack unwinder and exception dispatch can properly transform the exception into a managed exception and dispatch +;; it to managed code. +;; Runs a card table update via RhpBulkWriteBarrier after the copy if it contained GC pointers +;; +_RhpCopyAnyWithWriteBarrier PROC PUBLIC + + ; #locals, num_params, prolog bytes, #regs saved, use ebp, frame type (0 == FRAME_FPO) + .FPO( 0, 3, 0, 0, 0, 0) + + ; [esp + 0] return address + ; [esp + 4] dest + ; [esp + 8] src + ; [esp + c] count + + cmp dword ptr [esp + 0Ch], 0 ; check for a zero-length copy + jz NothingToCopy + + mov ecx, [esp + 4] ; ecx <- dest + mov edx, [esp + 8] ; edx <- src + + ; Now check the dest and src pointers. If they AV, the EH subsystem will recognize the address of the AV, + ; unwind the frame, and fixup the stack to make it look like the (managed) caller AV'ed, which will be + ; translated to a managed exception as usual. +ALTERNATE_ENTRY RhpCopyAnyWithWriteBarrierDestAVLocation + cmp byte ptr [ecx], 0 +ALTERNATE_ENTRY RhpCopyAnyWithWriteBarrierSrcAVLocation + cmp byte ptr [edx], 0 + + ; tail-call to the GC-safe memcpy implementation + ; NOTE: this is also a __cdecl function + jmp _memcpyAnyWithWriteBarrier + +NothingToCopy: + mov eax, [esp + 4] ; return dest + ret + +_RhpCopyAnyWithWriteBarrier ENDP + end |