]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify funcsyms
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Mar 2017 18:33:29 +0000 (11:33 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Mar 2017 23:34:24 +0000 (23:34 +0000)
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/38605
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/gc/sizeof_test.go
src/cmd/compile/internal/gc/subr.go

index 7ac8622fc6b23f2e13602075a055a379611c055e..c29a98c60f604940997ec186746de37104eae300 100644 (file)
@@ -1161,22 +1161,36 @@ func funccompile(n *Node) {
        dclcontext = PEXTERN
 }
 
-func funcsym(s *Sym) *Sym {
-       if s.Fsym != nil {
-               return s.Fsym
-       }
+func (s *Sym) funcsymname() string {
+       return s.Name + "·f"
+}
 
-       s1 := Pkglookup(s.Name+"·f", s.Pkg)
-       if !Ctxt.Flag_dynlink && s1.Def == nil {
-               s1.Def = newfuncname(s1)
-               s1.Def.Func.Shortname = s
-               funcsyms = append(funcsyms, s1.Def)
-       }
-       s.Fsym = s1
-       return s1
+// funcsym returns s·f.
+func funcsym(s *Sym) *Sym {
+       sf, existed := s.Pkg.LookupOK(s.funcsymname())
+       // Don't export s·f when compiling for dynamic linking.
+       // When dynamically linking, the necessary function
+       // symbols will be created explicitly with makefuncsym.
+       // See the makefuncsym comment for details.
+       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) {
+       if !Ctxt.Flag_dynlink {
+               Fatalf("makefuncsym dynlink")
+       }
        if isblanksym(s) {
                return
        }
@@ -1185,13 +1199,9 @@ func makefuncsym(s *Sym) {
                // not get a funcsym.
                return
        }
-       s1 := funcsym(s)
-       if s1.Def != nil {
-               return
+       if _, existed := s.Pkg.LookupOK(s.funcsymname()); !existed {
+               funcsyms = append(funcsyms, s)
        }
-       s1.Def = newfuncname(s1)
-       s1.Def.Func.Shortname = s
-       funcsyms = append(funcsyms, s1.Def)
 }
 
 type nowritebarrierrecChecker struct {
index 12076fc94a6dc2655aeac9aafe7e6b63a85e01ef..99e481cc87cef7db7140926b8dca3e841696073a 100644 (file)
@@ -58,7 +58,6 @@ type Sym struct {
        Label   *Node // corresponding label (ephemeral)
        Origpkg *Pkg  // original package for . import
        Lsym    *obj.LSym
-       Fsym    *Sym // funcsym
 }
 
 const (
@@ -239,7 +238,7 @@ var exportlist []*Node
 
 var importlist []*Node // imported functions and methods with inlinable bodies
 
-var funcsyms []*Node
+var funcsyms []*Sym
 
 var dclcontext Class // PEXTERN/PAUTO
 
index a7fe4692830f3c04894648ced1723fad2f9fc5c0..6ecb332242b1e3a9200cc79b4b5edac91df8f0c0 100644 (file)
@@ -216,9 +216,10 @@ func dumpglobls() {
                ggloblnod(n)
        }
 
-       for _, n := range funcsyms {
-               dsymptr(n.Sym, 0, n.Sym.Def.Func.Shortname, 0)
-               ggloblsym(n.Sym, int32(Widthptr), obj.DUPOK|obj.RODATA)
+       for _, s := range funcsyms {
+               sf := s.Pkg.Lookup(s.funcsymname())
+               dsymptr(sf, 0, s, 0)
+               ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA)
        }
 
        // Do not reprocess funcsyms on next dumpglobls call.
index 6d130b7ead4d6aca6e4643fb0a6e857d240c6772..644b9a0736e0fd269a7340bc100813bf0c28c4cd 100644 (file)
@@ -26,7 +26,7 @@ func TestSizeof(t *testing.T) {
                {Name{}, 36, 56},
                {Param{}, 28, 56},
                {Node{}, 84, 136},
-               {Sym{}, 64, 112},
+               {Sym{}, 60, 104},
                {Type{}, 52, 88},
                {MapType{}, 20, 40},
                {ForwardType{}, 20, 32},
index 726f84794c5abcba37f5e446ceee9ab29933897d..3885ca32be0124773d0c597781330d95d6e24826 100644 (file)
@@ -254,14 +254,20 @@ var nopkg = &Pkg{
 }
 
 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 {
                pkg = nopkg
        }
        if s := pkg.Syms[name]; s != nil {
-               return s
+               return s, true
        }
 
-       s := &Sym{
+       s = &Sym{
                Name: name,
                Pkg:  pkg,
        }
@@ -269,7 +275,7 @@ func (pkg *Pkg) Lookup(name string) *Sym {
                initSyms = append(initSyms, s)
        }
        pkg.Syms[name] = s
-       return s
+       return s, false
 }
 
 func (pkg *Pkg) LookupBytes(name []byte) *Sym {