aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_arm.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-11-20 17:10:34 -0500
committerCherry Zhang <cherryyz@google.com>2020-05-06 15:41:12 +0000
commitee330385ca684f7c166913e10998f791d1be06e7 (patch)
tree63f9b19a0811656bb78fc35df4ad2c7ced36a49d /src/runtime/signal_arm.go
parent4daf8719e7f4c71a620f650d73caab2a9d7ea499 (diff)
downloadgo-ee330385ca684f7c166913e10998f791d1be06e7.tar.gz
go-ee330385ca684f7c166913e10998f791d1be06e7.zip
cmd/internal/obj, runtime: preempt & restart some instruction sequences
On some architectures, for async preemption the injected call needs to clobber a register (usually REGTMP) in order to return to the preempted function. As a consequence, the PC ranges where REGTMP is live are not preemptible. The uses of REGTMP are usually generated by the assembler, where it needs to load or materialize a large constant or offset that doesn't fit into the instruction. In those cases, REGTMP is not live at the start of the instruction sequence. Instead of giving up preemption in those cases, we could preempt it and restart the sequence when resuming the execution. Basically, this is like reissuing an interrupted instruction, except that here the "instruction" is a Prog that consists of multiple machine instructions. For this to work, we need to generate PC data to mark the start of the Prog. Currently this is only done for ARM64. TODO: the split-stack function prologue is currently not async preemptible. We could use this mechanism, preempt it and restart at the function entry. Change-Id: I37cb282f8e606e7ab6f67b3edfdc6063097b4bd1 Reviewed-on: https://go-review.googlesource.com/c/go/+/208126 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/signal_arm.go')
-rw-r--r--src/runtime/signal_arm.go6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/runtime/signal_arm.go b/src/runtime/signal_arm.go
index b4b3ca458f..156d9d384c 100644
--- a/src/runtime/signal_arm.go
+++ b/src/runtime/signal_arm.go
@@ -63,7 +63,7 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_pc(uint32(funcPC(sigpanic)))
}
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
// Push the LR to stack, as we'll clobber it in order to
// push the call. The function being pushed is responsible
// for restoring the LR and setting the SP back.
@@ -72,7 +72,7 @@ func (c *sigctxt) pushCall(targetPC uintptr) {
c.set_sp(sp)
*(*uint32)(unsafe.Pointer(uintptr(sp))) = c.lr()
// Set up PC and LR to pretend the function being signaled
- // calls targetPC at the faulting PC.
- c.set_lr(c.pc())
+ // calls targetPC at resumePC.
+ c.set_lr(uint32(resumePC))
c.set_pc(uint32(targetPC))
}