]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: do not generate tail calls when dynamic linking on ppc64le
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Fri, 27 May 2016 03:41:55 +0000 (15:41 +1200)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Thu, 2 Jun 2016 02:34:01 +0000 (02:34 +0000)
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>

misc/cgo/testshared/src/depBase/dep.go
misc/cgo/testshared/src/exe2/exe2.go
src/cmd/compile/internal/gc/subr.go

index f9d3d7ce3a948e6d631537f29d17fe5957592fa7..3ceba34a2ba4f061e4d571deee094a7043848934 100644 (file)
@@ -12,6 +12,10 @@ type Dep struct {
        X int
 }
 
+func (d *Dep) Method() int {
+       return 10
+}
+
 func F() int {
        return V
 }
index acdb4ddcc569012649584b2bddbd3f80a07285b4..675fd1f365cc665b8db52c80db0eed6ab3dd2890 100644 (file)
@@ -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()
 }
index c2abff7b63487b7dc2c56147018a2fcdf437594d..1db1cbade820cb2337445db7dcbc13d745f96051 100644 (file)
@@ -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.