Commit 2c50bffe authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: simplify funcsyms

Sym.Fsym is used only to avoid adding duplicate
entries to funcsyms, but that is easily
accomplished by detecting the first lookup
vs subsequent lookups of the func sym name.

This avoids creating an unnecessary ONAME node
during funcsym, which eliminates a dependency
in the backend on Curfn and lineno.

It also makes the code a lot simpler and clearer.

Updates #15756

Passes toolstash-check -all.
No compiler performance changes.
funcsymname does generate garbage via string
concatenation, but it is not called very much,
and this CL also eliminates allocation of several
Nodes and Names.

Change-Id: I7116c78fa39d975b7bd2c65a1d228749cf0dd46b
Reviewed-on: https://go-review.googlesource.com/38605Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 3a89065c
...@@ -1161,22 +1161,36 @@ func funccompile(n *Node) { ...@@ -1161,22 +1161,36 @@ func funccompile(n *Node) {
dclcontext = PEXTERN dclcontext = PEXTERN
} }
func funcsym(s *Sym) *Sym { func (s *Sym) funcsymname() string {
if s.Fsym != nil { return s.Name + "·f"
return s.Fsym }
}
s1 := Pkglookup(s.Name+"·f", s.Pkg) // funcsym returns s·f.
if !Ctxt.Flag_dynlink && s1.Def == nil { func funcsym(s *Sym) *Sym {
s1.Def = newfuncname(s1) sf, existed := s.Pkg.LookupOK(s.funcsymname())
s1.Def.Func.Shortname = s // Don't export s·f when compiling for dynamic linking.
funcsyms = append(funcsyms, s1.Def) // When dynamically linking, the necessary function
} // symbols will be created explicitly with makefuncsym.
s.Fsym = s1 // See the makefuncsym comment for details.
return s1 if !Ctxt.Flag_dynlink && !existed {
funcsyms = append(funcsyms, s)
}
return sf
} }
// makefuncsym ensures that s·f is exported.
// It is only used with -dynlink.
// When not compiling for dynamic linking,
// the funcsyms are created as needed by
// the packages that use them.
// Normally we emit the s·f stubs as DUPOK syms,
// but DUPOK doesn't work across shared library boundaries.
// So instead, when dynamic linking, we only create
// the s·f stubs in s's package.
func makefuncsym(s *Sym) { func makefuncsym(s *Sym) {
if !Ctxt.Flag_dynlink {
Fatalf("makefuncsym dynlink")
}
if isblanksym(s) { if isblanksym(s) {
return return
} }
...@@ -1185,13 +1199,9 @@ func makefuncsym(s *Sym) { ...@@ -1185,13 +1199,9 @@ func makefuncsym(s *Sym) {
// not get a funcsym. // not get a funcsym.
return return
} }
s1 := funcsym(s) if _, existed := s.Pkg.LookupOK(s.funcsymname()); !existed {
if s1.Def != nil { funcsyms = append(funcsyms, s)
return
} }
s1.Def = newfuncname(s1)
s1.Def.Func.Shortname = s
funcsyms = append(funcsyms, s1.Def)
} }
type nowritebarrierrecChecker struct { type nowritebarrierrecChecker struct {
......
...@@ -58,7 +58,6 @@ type Sym struct { ...@@ -58,7 +58,6 @@ type Sym struct {
Label *Node // corresponding label (ephemeral) Label *Node // corresponding label (ephemeral)
Origpkg *Pkg // original package for . import Origpkg *Pkg // original package for . import
Lsym *obj.LSym Lsym *obj.LSym
Fsym *Sym // funcsym
} }
const ( const (
...@@ -239,7 +238,7 @@ var exportlist []*Node ...@@ -239,7 +238,7 @@ var exportlist []*Node
var importlist []*Node // imported functions and methods with inlinable bodies var importlist []*Node // imported functions and methods with inlinable bodies
var funcsyms []*Node var funcsyms []*Sym
var dclcontext Class // PEXTERN/PAUTO var dclcontext Class // PEXTERN/PAUTO
......
...@@ -216,9 +216,10 @@ func dumpglobls() { ...@@ -216,9 +216,10 @@ func dumpglobls() {
ggloblnod(n) ggloblnod(n)
} }
for _, n := range funcsyms { for _, s := range funcsyms {
dsymptr(n.Sym, 0, n.Sym.Def.Func.Shortname, 0) sf := s.Pkg.Lookup(s.funcsymname())
ggloblsym(n.Sym, int32(Widthptr), obj.DUPOK|obj.RODATA) dsymptr(sf, 0, s, 0)
ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA)
} }
// Do not reprocess funcsyms on next dumpglobls call. // Do not reprocess funcsyms on next dumpglobls call.
......
...@@ -26,7 +26,7 @@ func TestSizeof(t *testing.T) { ...@@ -26,7 +26,7 @@ func TestSizeof(t *testing.T) {
{Name{}, 36, 56}, {Name{}, 36, 56},
{Param{}, 28, 56}, {Param{}, 28, 56},
{Node{}, 84, 136}, {Node{}, 84, 136},
{Sym{}, 64, 112}, {Sym{}, 60, 104},
{Type{}, 52, 88}, {Type{}, 52, 88},
{MapType{}, 20, 40}, {MapType{}, 20, 40},
{ForwardType{}, 20, 32}, {ForwardType{}, 20, 32},
......
...@@ -254,14 +254,20 @@ var nopkg = &Pkg{ ...@@ -254,14 +254,20 @@ var nopkg = &Pkg{
} }
func (pkg *Pkg) Lookup(name string) *Sym { func (pkg *Pkg) Lookup(name string) *Sym {
s, _ := pkg.LookupOK(name)
return s
}
// LookupOK looks up name in pkg and reports whether it previously existed.
func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) {
if pkg == nil { if pkg == nil {
pkg = nopkg pkg = nopkg
} }
if s := pkg.Syms[name]; s != nil { if s := pkg.Syms[name]; s != nil {
return s return s, true
} }
s := &Sym{ s = &Sym{
Name: name, Name: name,
Pkg: pkg, Pkg: pkg,
} }
...@@ -269,7 +275,7 @@ func (pkg *Pkg) Lookup(name string) *Sym { ...@@ -269,7 +275,7 @@ func (pkg *Pkg) Lookup(name string) *Sym {
initSyms = append(initSyms, s) initSyms = append(initSyms, s)
} }
pkg.Syms[name] = s pkg.Syms[name] = s
return s return s, false
} }
func (pkg *Pkg) LookupBytes(name []byte) *Sym { func (pkg *Pkg) LookupBytes(name []byte) *Sym {
......
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