0
1
mirror of https://github.com/golang/go synced 2025-06-16 17:48:47 +00:00

cmd/compile: run escape analysis after method wrapper generation

Also modified test/run.go to ignore messages prefixed <autogenerated>
because those cannot be described with "// ERROR ...", and backed out
patch from issue  because it is no longer necessary.  The reasons
described in the 9537 discussion for why escape analysis cannot run
late no longer hold, happily.

Fixes .

Change-Id: Icb14eccdf2e8cde3d0f8fb8a216b765400a96385
Reviewed-on: https://go-review.googlesource.com/11088
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: David Chase <drchase@google.com>
This commit is contained in:
David Chase
2015-06-16 18:28:01 -04:00
parent 6428a8b437
commit 5be61b18d4
8 changed files with 80 additions and 17 deletions
src/cmd/compile/internal/gc
test

@ -644,8 +644,6 @@ var compiling_runtime int
var compiling_wrappers int
var inl_nonlocal int
var use_writebarrier int
var pure_go int

@ -831,12 +831,10 @@ func inlvar(var_ *Node) *Node {
n.Name.Curfn = Curfn // the calling function, not the called one
n.Addrtaken = var_.Addrtaken
// Esc pass wont run if we're inlining into a iface wrapper.
// Luckily, we can steal the results from the target func.
// If inlining a function defined in another package after
// escape analysis is done, treat all local vars as escaping.
// See issue 9537.
if var_.Esc == EscHeap || (inl_nonlocal != 0 && var_.Op == ONAME) {
// This may no longer be necessary now that we run escape analysis
// after wrapper generation, but for 1.5 this is conservatively left
// unchanged. See bugs 11053 and 9537.
if var_.Esc == EscHeap {
addrescapes(n)
}

@ -2494,15 +2494,8 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
typecheck(&fn, Etop)
typechecklist(fn.Nbody, Etop)
// Set inl_nonlocal to whether we are calling a method on a
// type defined in a different package. Checked in inlvar.
if !methodrcvr.Local {
inl_nonlocal = 1
}
inlcalls(fn)
inl_nonlocal = 0
escAnalyze(list1(fn), false)
Curfn = nil
funccompile(fn)

@ -0,0 +1,9 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
func Int32(i int32) *int32 {
return &i
}

@ -0,0 +1,51 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"p"
)
type I interface {
Add(out *P)
}
type P struct {
V *int32
}
type T struct{}
var x int32 = 42
func Int32x(i int32) *int32 {
return &i
}
func (T) Add(out *P) {
out.V = p.Int32(x) // inlined, p.i.2 moved to heap
}
var PP P
var out *P = &PP
func F(s I) interface{} {
s.Add(out) // not inlined.
return out
}
var s T
func main() {
println("Starting")
fmt.Sprint(new(int32))
resp := F(s).(*P)
println("Before, *resp.V=", *resp.V) // Trashes *resp.V in process of printing.
println("After, *resp.V=", *resp.V)
if got, want := *resp.V, int32(42); got != want {
fmt.Printf("FAIL, got %v, want %v", got, want)
}
}

@ -0,0 +1,10 @@
// rundir
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 11053: Compiler does not run escape analysis on an inlined
// generated method wrapper.
package ignored

@ -0,0 +1,3 @@
Starting
Before, *resp.V= 42
After, *resp.V= 42

@ -729,6 +729,7 @@ func (t *test) expectedOutput() string {
func splitOutput(out string) []string {
// 6g error messages continue onto additional lines with leading tabs.
// Split the output at the beginning of each line that doesn't begin with a tab.
// <autogenerated> lines are impossible to match so those are filtered out.
var res []string
for _, line := range strings.Split(out, "\n") {
if strings.HasSuffix(line, "\r") { // remove '\r', output by compiler on windows
@ -736,7 +737,7 @@ func splitOutput(out string) []string {
}
if strings.HasPrefix(line, "\t") {
res[len(res)-1] += "\n" + line
} else if strings.HasPrefix(line, "go tool") {
} else if strings.HasPrefix(line, "go tool") || strings.HasPrefix(line, "<autogenerated>") {
continue
} else if strings.TrimSpace(line) != "" {
res = append(res, line)