diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-11-20 17:10:34 -0500 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-05-06 15:41:12 +0000 |
commit | ee330385ca684f7c166913e10998f791d1be06e7 (patch) | |
tree | 63f9b19a0811656bb78fc35df4ad2c7ced36a49d /src/runtime/signal_arm64.go | |
parent | 4daf8719e7f4c71a620f650d73caab2a9d7ea499 (diff) | |
download | go-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_arm64.go')
-rw-r--r-- | src/runtime/signal_arm64.go | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/runtime/signal_arm64.go b/src/runtime/signal_arm64.go index ef65f92aa3..3c20139c99 100644 --- a/src/runtime/signal_arm64.go +++ b/src/runtime/signal_arm64.go @@ -79,7 +79,7 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) { c.set_pc(uint64(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. @@ -88,7 +88,7 @@ func (c *sigctxt) pushCall(targetPC uintptr) { c.set_sp(sp) *(*uint64)(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(uint64(resumePC)) c.set_pc(uint64(targetPC)) } |