diff options
| author | Cherry Zhang <cherryyz@google.com> | 2019-11-20 20:12:38 -0500 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2020-05-06 15:41:25 +0000 |
| commit | ef3571bf076f4255579bedb3409bdccc91555b86 (patch) | |
| tree | bbefb711651df3bf4538c52d025c0efe3e716002 /src/cmd/internal/obj/mips | |
| parent | ee330385ca684f7c166913e10998f791d1be06e7 (diff) | |
| download | go-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.go | 25 |
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 } |
