aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/mips
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-11-20 20:12:38 -0500
committerCherry Zhang <cherryyz@google.com>2020-05-06 15:41:25 +0000
commitef3571bf076f4255579bedb3409bdccc91555b86 (patch)
treebbefb711651df3bf4538c52d025c0efe3e716002 /src/cmd/internal/obj/mips
parentee330385ca684f7c166913e10998f791d1be06e7 (diff)
downloadgo-ef3571bf076f4255579bedb3409bdccc91555b86.tar.xz
cmd/internal/obj/mips: mark restartable sequences
Following CL 208126, do the same for MIPS. Change-Id: I95f8fc99a234524119a4d29c7695676dc0ea1025 Reviewed-on: https://go-review.googlesource.com/c/go/+/208217 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/cmd/internal/obj/mips')
-rw-r--r--src/cmd/internal/obj/mips/asm0.go25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index 957f2d5c93..faa12bf133 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -526,16 +526,29 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
// We use REGTMP as a scratch register during call injection,
// so instruction sequences that use REGTMP are unsafe to
// preempt asynchronously.
- obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, nil)
+ obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, c.isRestartable)
}
-// Return whether p is an unsafe point.
+// isUnsafePoint returns whether p is an unsafe point.
func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
- if p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP {
- return true
+ // If p explicitly uses REGTMP, it's unsafe to preempt, because the
+ // preemption sequence clobbers REGTMP.
+ return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
+}
+
+// isRestartable returns whether p is a multi-instruction sequence that,
+// if preempted, can be restarted.
+func (c *ctxt0) isRestartable(p *obj.Prog) bool {
+ if c.isUnsafePoint(p) {
+ return false
}
- // Most of the multi-instruction sequence uses REGTMP, except
- // ones marked safe.
+ // If p is a multi-instruction sequence with uses REGTMP inserted by
+ // the assembler in order to materialize a large constant/offset, we
+ // can restart p (at the start of the instruction sequence), recompute
+ // the content of REGTMP, upon async preemption. Currently, all cases
+ // of assembler-inserted REGTMP fall into this category.
+ // If p doesn't use REGTMP, it can be simply preempted, so we don't
+ // mark it.
o := c.oplook(p)
return o.size > 4 && o.flag&NOTUSETMP == 0
}