mirror of
https://github.com/golang/go
synced 2024-11-23 11:10:04 -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:
parent
068c745e1e
commit
d25c3eadea
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user