aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2021-07-30 16:40:17 -0400
committerAustin Clements <austin@google.com>2021-07-30 21:51:49 +0000
commite3e9f0bb2d6cc15b201fe2e0a0ac095d62cf4b8c (patch)
tree1c5960b23d5810b75637928c33a6bd4c6357e8c1 /src/cmd/internal
parent40e561d9337afbae221b34d6d0811761f32412f6 (diff)
downloadgo-e3e9f0bb2d6cc15b201fe2e0a0ac095d62cf4b8c.tar.gz
go-e3e9f0bb2d6cc15b201fe2e0a0ac095d62cf4b8c.zip
[dev.typeparams] Revert "[dev.typeparams] runtime,cmd/compile,cmd/link: replace jmpdefer with a loop"
This reverts CL 227652. I'm reverting CL 337651 and this builds on top of it. Change-Id: I03ce363be44c2a3defff2e43e7b1aad83386820d Reviewed-on: https://go-review.googlesource.com/c/go/+/338709 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r--src/cmd/internal/obj/arm/asm5.go11
-rw-r--r--src/cmd/internal/obj/wasm/wasmobj.go36
-rw-r--r--src/cmd/internal/obj/x86/asm6.go1
-rw-r--r--src/cmd/internal/objabi/funcid.go2
4 files changed, 46 insertions, 4 deletions
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index 7b1682776e..ccf5f9e7f8 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -355,10 +355,11 @@ var oprange [ALAST & obj.AMask][]Optab
var xcmp [C_GOK + 1][C_GOK + 1]bool
var (
- symdiv *obj.LSym
- symdivu *obj.LSym
- symmod *obj.LSym
- symmodu *obj.LSym
+ deferreturn *obj.LSym
+ symdiv *obj.LSym
+ symdivu *obj.LSym
+ symmod *obj.LSym
+ symmodu *obj.LSym
)
// Note about encoding: Prog.scond holds the condition encoding,
@@ -1218,6 +1219,8 @@ func buildop(ctxt *obj.Link) {
return
}
+ deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
+
symdiv = ctxt.Lookup("runtime._div")
symdivu = ctxt.Lookup("runtime._divu")
symmod = ctxt.Lookup("runtime._mod")
diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go
index 4d276db678..ceeae7a257 100644
--- a/src/cmd/internal/obj/wasm/wasmobj.go
+++ b/src/cmd/internal/obj/wasm/wasmobj.go
@@ -129,6 +129,8 @@ var (
morestackNoCtxt *obj.LSym
gcWriteBarrier *obj.LSym
sigpanic *obj.LSym
+ deferreturn *obj.LSym
+ jmpdefer *obj.LSym
)
const (
@@ -141,6 +143,10 @@ func instinit(ctxt *obj.Link) {
morestackNoCtxt = ctxt.Lookup("runtime.morestack_noctxt")
gcWriteBarrier = ctxt.LookupABI("runtime.gcWriteBarrier", obj.ABIInternal)
sigpanic = ctxt.LookupABI("runtime.sigpanic", obj.ABIInternal)
+ deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
+ // jmpdefer is defined in assembly as ABI0. The compiler will
+ // generate a direct ABI0 call from Go, so look for that.
+ jmpdefer = ctxt.LookupABI(`"".jmpdefer`, obj.ABI0)
}
func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
@@ -417,6 +423,12 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
pcAfterCall-- // sigpanic expects to be called without advancing the pc
}
+ // jmpdefer manipulates the return address on the stack so deferreturn gets called repeatedly.
+ // Model this in WebAssembly with a loop.
+ if call.To.Sym == deferreturn {
+ p = appendp(p, ALoop)
+ }
+
// SP -= 8
p = appendp(p, AGet, regAddr(REG_SP))
p = appendp(p, AI32Const, constAddr(8))
@@ -467,6 +479,15 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
break
}
+ // jmpdefer removes the frame of deferreturn from the Go stack.
+ // However, its WebAssembly function still returns normally,
+ // so we need to return from deferreturn without removing its
+ // stack frame (no RET), because the frame is already gone.
+ if call.To.Sym == jmpdefer {
+ p = appendp(p, AReturn)
+ break
+ }
+
// return value of call is on the top of the stack, indicating whether to unwind the WebAssembly stack
if call.As == ACALLNORESUME && call.To.Sym != sigpanic { // sigpanic unwinds the stack, but it never resumes
// trying to unwind WebAssembly stack but call has no resume point, terminate with error
@@ -479,6 +500,21 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
unwindExitBranches = append(unwindExitBranches, p)
}
+ // jump to before the call if jmpdefer has reset the return address to the call's PC
+ if call.To.Sym == deferreturn {
+ // get PC_B from -8(SP)
+ p = appendp(p, AGet, regAddr(REG_SP))
+ p = appendp(p, AI32Const, constAddr(8))
+ p = appendp(p, AI32Sub)
+ p = appendp(p, AI32Load16U, constAddr(0))
+ p = appendp(p, ATee, regAddr(REG_PC_B))
+
+ p = appendp(p, AI32Const, constAddr(call.Pc))
+ p = appendp(p, AI32Eq)
+ p = appendp(p, ABrIf, constAddr(0))
+ p = appendp(p, AEnd) // end of Loop
+ }
+
case obj.ARET, ARETUNWIND:
ret := *p
p.As = obj.ANOP
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index 331a98dfef..17fa76727e 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -43,6 +43,7 @@ import (
var (
plan9privates *obj.LSym
+ deferreturn *obj.LSym
)
// Instruction layout.
diff --git a/src/cmd/internal/objabi/funcid.go b/src/cmd/internal/objabi/funcid.go
index 68f6a26a76..d881cdd061 100644
--- a/src/cmd/internal/objabi/funcid.go
+++ b/src/cmd/internal/objabi/funcid.go
@@ -34,6 +34,7 @@ const (
FuncID_gogo
FuncID_gopanic
FuncID_handleAsyncEvent
+ FuncID_jmpdefer
FuncID_mcall
FuncID_morestack
FuncID_mstart
@@ -59,6 +60,7 @@ var funcIDs = map[string]FuncID{
"gogo": FuncID_gogo,
"gopanic": FuncID_gopanic,
"handleAsyncEvent": FuncID_handleAsyncEvent,
+ "jmpdefer": FuncID_jmpdefer,
"main": FuncID_runtime_main,
"mcall": FuncID_mcall,
"morestack": FuncID_morestack,