1
0
mirror of https://github.com/golang/go synced 2024-11-23 08:20:05 -07:00

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 <iant@golang.org>
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Michael Hudson-Doyle 2016-05-27 15:41:55 +12:00
parent 068c745e1e
commit d25c3eadea
3 changed files with 13 additions and 2 deletions

View File

@ -12,6 +12,10 @@ type Dep struct {
X int X int
} }
func (d *Dep) Method() int {
return 10
}
func F() int { func F() int {
return V return V
} }

View File

@ -3,5 +3,6 @@ package main
import "dep2" import "dep2"
func main() { func main() {
dep2.W = dep2.G() + 1 d := &dep2.Dep2{}
dep2.W = dep2.G() + 1 + d.Method()
} }

View File

@ -1860,7 +1860,13 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
dot := adddot(NodSym(OXDOT, this.Left, method.Sym)) dot := adddot(NodSym(OXDOT, this.Left, method.Sym))
// generate call // 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. // generate tail call: adjust pointer receiver and jump to embedded method.
dot = dot.Left // skip final .M dot = dot.Left // skip final .M
// TODO(mdempsky): Remove dependency on dotlist. // TODO(mdempsky): Remove dependency on dotlist.