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:
authorMichal Strehovský <michals@microsoft.com>2018-04-12 23:30:16 +0300
committerMichal Strehovský <michals@microsoft.com>2018-04-12 23:30:16 +0300
commit900214568e1e752ee1d68674007f7875364766e6 (patch)
tree1d035f809e918cc9f542e349567550c669179fd5 /src/Native
parent657a36664050c9c5f0053a341d5f99b5d6588dd6 (diff)
parentf1da066af8bf9c66cbe02910e27d996dc3681f25 (diff)
Merge remote-tracking branch 'upstream/nmirror' into nmirror-merge
Diffstat (limited to 'src/Native')
-rw-r--r--src/Native/Runtime/arm64/ExceptionHandling.asm7
-rw-r--r--src/Native/Runtime/arm64/GcProbe.asm119
2 files changed, 123 insertions, 3 deletions
diff --git a/src/Native/Runtime/arm64/ExceptionHandling.asm b/src/Native/Runtime/arm64/ExceptionHandling.asm
index 1ea8520ef..c71194da9 100644
--- a/src/Native/Runtime/arm64/ExceptionHandling.asm
+++ b/src/Native/Runtime/arm64/ExceptionHandling.asm
@@ -15,15 +15,16 @@
;; Macro used to create frame of exception throwing helpers (RhpThrowEx, RhpThrowHwEx)
MACRO
ALLOC_THROW_FRAME $exceptionType
-
- PROLOG_NOP mov x3, sp
+ PROLOG_NOP mov x3, sp
+
;; Setup a PAL_LIMITED_CONTEXT on the stack {
- PROLOG_STACK_ALLOC 0x50
IF $exceptionType == HARDWARE_EXCEPTION
+ PROLOG_NOP sub sp,sp,#0x50
PROLOG_NOP stp x3, x1, [sp] ; x3 is the SP and x1 is the IP of the fault site
PROLOG_PUSH_MACHINE_FRAME
ELSE
+ PROLOG_STACK_ALLOC 0x50
PROLOG_NOP stp x3, lr, [sp] ; x3 is the SP and lr is the IP of the fault site
ENDIF
PROLOG_NOP stp d8, d9, [sp, #0x10]
diff --git a/src/Native/Runtime/arm64/GcProbe.asm b/src/Native/Runtime/arm64/GcProbe.asm
index 051b4158d..3554c8eb3 100644
--- a/src/Native/Runtime/arm64/GcProbe.asm
+++ b/src/Native/Runtime/arm64/GcProbe.asm
@@ -852,4 +852,123 @@ Abort
INLINE_GETTHREAD_CONSTANT_POOL
+;; Trap to GC.
+;; Set up the P/Invoke transition frame with the return address as the safe point.
+;; All registers, both volatile and non-volatile, are preserved.
+;; The function should be called not jumped because it's expecting the return address
+ NESTED_ENTRY RhpTrapToGC, _TEXT
+;;
+ ;; What we want to get to:
+ ;;
+ ;; [sp + ] -> m_FramePointer -------|
+ ;; [sp + 8] -> m_RIP |
+ ;; [sp + 10] -> m_pThread |
+ ;; [sp + 18] -> m_Flags / m_dwAlignPad2 |
+ ;; [sp + 20] -> x19 save |
+ ;; [sp + 28] -> x20 save |
+ ;; [sp + 30] -> x21 save |
+ ;; [sp + 38] -> x22 save |
+ ;; [sp + 40] -> x23 save |
+ ;; [sp + 48] -> x24 save | PInvokeTransitionFrame
+ ;; [sp + 50] -> x25 save |
+ ;; [sp + 58] -> x26 save |
+ ;; [sp + 60] -> x27 save |
+ ;; [sp + 68] -> x28 save |
+ ;; [sp + 70] -> sp save ;caller sp |
+ ;; [sp + 78] -> x0 save |
+ ;; [sp + 80] -> x1 save |
+ ;; [sp + 88] -> x2 save |
+ ;; [sp + 90] -> x3 save |
+ ;; [sp + 98] -> x4 save |
+ ;; [sp + a0] -> x5 save |
+ ;; [sp + a8] -> x6 save |
+ ;; [sp + b0] -> x7 save |
+ ;; [sp + b8] -> x8 save |
+ ;; [sp + c0] -> x9 save |
+ ;; [sp + c8] -> x10 save |
+ ;; [sp + d0] -> x11 save |
+ ;; [sp + d8] -> x12 save |
+ ;; [sp + e0] -> x13 save |
+ ;; [sp + e8] -> x14 save |
+ ;; [sp + f0] -> x15 save |
+ ;; [sp + f8] -> x16 save |
+ ;; [sp + 100] -> x17 save |
+ ;; [sp + 108] -> x18 save |
+ ;; [sp + 110] -> lr save -------|
+ ;;
+ ;; [sp + 118] -> NZCV
+ ;;
+ ;; [sp + 120] -> d0, d1, d2, d3
+ ;; [sp + 140] -> d4 ... d31
+ ;;
+
+ ALLOC_LOOP_HIJACK_FRAME
+
+ ;; Slot at [sp, #0x118] is reserved for NZCV
+ mrs x1, NZCV
+ str x1, [sp, #m_SavedNZCV]
+
+ ;; x4 <- GetThread(), TRASHES x1
+ INLINE_GETTHREAD x4, x1
+ INIT_PROBE_FRAME x4, x1, #PROBE_SAVE_FLAGS_EVERYTHING, 0, (PROBE_FRAME_SIZE + EXTRA_SAVE_SIZE)
+
+ ; Early out if GC stress is currently suppressed. Do this after we have computed the real address to
+ ; return to but before we link the transition frame onto m_pHackPInvokeTunnel (because hitting this
+ ; condition implies we're running restricted callouts during a GC itself and we could end up
+ ; overwriting a co-op frame set by the code that caused the GC in the first place, e.g. a GC.Collect
+ ; call).
+ ldr w1, [x4, #OFFSETOF__Thread__m_ThreadStateFlags]
+ tst w1, #TSF_SuppressGcStress__OR__TSF_DoNotTriggerGC
+ bne DoNotTriggerGC
+
+ ; link the frame into the Thread
+ add x1, sp, xzr
+ str x1, [x4, #OFFSETOF__Thread__m_pHackPInvokeTunnel]
+
+ ;;
+ ;; Unhijack this thread, if necessary.
+ ;;
+ INLINE_THREAD_UNHIJACK x4, x1, x2 ;; trashes x1, x2
+
+#ifdef FEATURE_GC_STRESS
+
+ ldr x1, =g_fGcStressStarted
+ ldr w1, [x1]
+ cbnz w1, SkipGcStress
+
+ mov x1, x0
+ ldr x0, =$g_pTheRuntimeInstance
+ ldr x0, [x0]
+ bl $RuntimeInstance__ShouldHijackLoopForGcStress
+ cbnz x0, SkipGcStress
+
+ bl $REDHAWKGCINTERFACE__STRESSGC
+SkipGcStress
+#endif ;; FEATURE_GC_STRESS
+
+ add x9, sp, xzr ; sp is address of PInvokeTransitionFrame
+ bl RhpWaitForGCNoAbort
+
+DoNotTriggerGC
+ ldr x1, [sp, #OFFSETOF__PInvokeTransitionFrame__m_Flags]
+ tbnz x1, #PTFF_THREAD_ABORT_BIT, ToAbort
+
+ ; restore condition codes
+ ldr x1, [sp, #m_SavedNZCV]
+ msr NZCV, x1
+
+ FREE_LOOP_HIJACK_FRAME
+ EPILOG_RETURN
+
+ToAbort
+ FREE_LOOP_HIJACK_FRAME
+ EPILOG_NOP mov w0, #STATUS_REDHAWK_THREAD_ABORT
+ EPILOG_NOP mov x1, lr ; hijack target address as exception PC
+ EPILOG_NOP b RhpThrowHwEx
+
+ NESTED_END RhpTrapToGC
+
+ INLINE_GETTHREAD_CONSTANT_POOL
+
end
+