Commit d25c3ead authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

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/23468Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 068c745e
......@@ -12,6 +12,10 @@ type Dep struct {
X int
}
func (d *Dep) Method() int {
return 10
}
func F() int {
return V
}
......@@ -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()
}
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment