From: Michael Hudson-Doyle Date: Fri, 27 May 2016 03:41:55 +0000 (+1200) Subject: cmd/compile: do not generate tail calls when dynamic linking on ppc64le X-Git-Tag: go1.7beta2~80 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d25c3eadea9bc5c8b6451c3502d6063dd618a3af;p=gostls13.git cmd/compile: do not generate tail calls when dynamic linking on ppc64le When a wrapper method calls the real implementation, it's not possible to use a tail call when dynamic linking on ppc64le. The bad scenario is when a local call is made to the wrapper: the wrapper will call the implementation, which might be in a different module and so set the TOC to the appropriate value for that module. But if it returns directly to the wrapper's caller, nothing will reset it to the correct value for that function. Change-Id: Icebf24c9a2a0a9a7c2bce6bd6f1358657284fb10 Reviewed-on: https://go-review.googlesource.com/23468 Reviewed-by: Ian Lance Taylor Run-TryBot: Michael Hudson-Doyle TryBot-Result: Gobot Gobot --- diff --git a/misc/cgo/testshared/src/depBase/dep.go b/misc/cgo/testshared/src/depBase/dep.go index f9d3d7ce3a..3ceba34a2b 100644 --- a/misc/cgo/testshared/src/depBase/dep.go +++ b/misc/cgo/testshared/src/depBase/dep.go @@ -12,6 +12,10 @@ type Dep struct { X int } +func (d *Dep) Method() int { + return 10 +} + func F() int { return V } diff --git a/misc/cgo/testshared/src/exe2/exe2.go b/misc/cgo/testshared/src/exe2/exe2.go index acdb4ddcc5..675fd1f365 100644 --- a/misc/cgo/testshared/src/exe2/exe2.go +++ b/misc/cgo/testshared/src/exe2/exe2.go @@ -3,5 +3,6 @@ package main import "dep2" func main() { - dep2.W = dep2.G() + 1 + d := &dep2.Dep2{} + dep2.W = dep2.G() + 1 + d.Method() } diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index c2abff7b63..1db1cbade8 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -1860,7 +1860,13 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { dot := adddot(NodSym(OXDOT, this.Left, method.Sym)) // generate call - if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) { + // It's not possible to use a tail call when dynamic linking on ppc64le. The + // bad scenario is when a local call is made to the wrapper: the wrapper will + // call the implementation, which might be in a different module and so set + // the TOC to the appropriate value for that module. But if it returns + // directly to the wrapper's caller, nothing will reset it to the correct + // value for that function. + if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(Thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) { // generate tail call: adjust pointer receiver and jump to embedded method. dot = dot.Left // skip final .M // TODO(mdempsky): Remove dependency on dotlist.