]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: split off 'Dynimp' string fields to reduce sym.Symbol size
authorThan McIntosh <thanm@google.com>
Thu, 28 Jun 2018 20:10:19 +0000 (16:10 -0400)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 3 Jul 2018 14:48:40 +0000 (14:48 +0000)
The linker's sym.Symbol struct contains two string fields, "Dynimplib"
and "Dynimpvers" that are used only in very specific circumstances
(for many symbols, such as DWARF syms, they are wasted space). Split
these two off into a separate struct, then point to an instance of
that struct when needed. This reduces the size of sym.Symbol so as to
save space in the common case.

Updates #26186

Change-Id: Id9c74824e78423a215c8cbc105b72665525a1eff
Reviewed-on: https://go-review.googlesource.com/121916
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/go.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/loadelf/ldelf.go
src/cmd/link/internal/loadmacho/ldmacho.go
src/cmd/link/internal/sym/symbol.go

index 877e4bfd5f0bf8c546e015ac8c8f074f3bd15852..4ecbff86a9c5dd29507bbd72062ccaada8c057d9 100644 (file)
@@ -1030,8 +1030,8 @@ func elfdynhash(ctxt *Link) {
                        continue
                }
 
-               if sy.Dynimpvers != "" {
-                       need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
+               if sy.Dynimpvers() != "" {
+                       need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
                }
 
                name := sy.Extname
@@ -2287,8 +2287,8 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) {
                /* size of object */
                d.AddUint64(ctxt.Arch, uint64(s.Size))
 
-               if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
-                       Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
+               if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] {
+                       Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib())))
                }
        } else {
                s.Dynid = int32(Nelfsym)
index eb6c2ccc83128cbb5b1d45d32b33069bdaaddb53..06ee6968c6804b6fb4a3a76ac487e273bcae41c5 100644 (file)
@@ -155,9 +155,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
                        }
                        s := ctxt.Syms.Lookup(local, 0)
                        if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
-                               s.Dynimplib = lib
+                               s.SetDynimplib(lib)
                                s.Extname = remote
-                               s.Dynimpvers = q
+                               s.SetDynimpvers(q)
                                if s.Type != sym.SHOSTOBJ {
                                        s.Type = sym.SDYNIMPORT
                                }
@@ -198,10 +198,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
 
                        // export overrides import, for openbsd/cgo.
                        // see issue 4878.
-                       if s.Dynimplib != "" {
-                               s.Dynimplib = ""
+                       if s.Dynimplib() != "" {
+                               s.ResetDyninfo()
                                s.Extname = ""
-                               s.Dynimpvers = ""
                                s.Type = 0
                        }
 
index 0fe0b420144759b91e95723cc3c68a2bbf84c01f..d3abb7a6cba87919bd3c22d409f915bc0d096018 100644 (file)
@@ -416,7 +416,7 @@ func (ctxt *Link) loadlib() {
                                // cgo_import_static and cgo_import_dynamic,
                                // then we want to make it cgo_import_dynamic
                                // now.
-                               if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
+                               if s.Extname != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
                                        s.Type = sym.SDYNIMPORT
                                } else {
                                        s.Type = 0
index efd971c1cf8da68fb765d9156fd15f9f3effb10d..c81e3d6af577641e95b2cb9c381d53a6b9390656 100644 (file)
@@ -989,7 +989,7 @@ func initdynimport(ctxt *Link) *Dll {
                        continue
                }
                for d = dr; d != nil; d = d.next {
-                       if d.name == s.Dynimplib {
+                       if d.name == s.Dynimplib() {
                                m = new(Imp)
                                break
                        }
@@ -997,7 +997,7 @@ func initdynimport(ctxt *Link) *Dll {
 
                if d == nil {
                        d = new(Dll)
-                       d.name = s.Dynimplib
+                       d.name = s.Dynimplib()
                        d.next = dr
                        dr = d
                        m = new(Imp)
index 301c2ce1168e1e600c1d5a30a23ef21406703617..8e32e7dee61906119f51c74e9b3bcc265a96ee77 100644 (file)
@@ -805,7 +805,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
                s.Type = sect.sym.Type
                s.Attr |= sym.AttrSubSymbol
                if !s.Attr.CgoExportDynamic() {
-                       s.Dynimplib = "" // satisfy dynimport
+                       s.SetDynimplib("") // satisfy dynimport
                }
                s.Value = int64(elfsym.value)
                s.Size = int64(elfsym.size)
index e6b0f70e3822a54f7f25298c0b739953109b457e..85aa606ff51efaf40ebb48ec5feb0fb8117d165d 100644 (file)
@@ -644,7 +644,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
                s.Outer = outer
                s.Value = int64(machsym.value - sect.addr)
                if !s.Attr.CgoExportDynamic() {
-                       s.Dynimplib = "" // satisfy dynimport
+                       s.SetDynimplib("") // satisfy dynimport
                }
                if outer.Type == sym.STEXT {
                        if s.Attr.External() && !s.Attr.DuplicateOK() {
index 8893dcf0d69e1133c7a8cc1210bda95f18929a90..ea0eb89e2bc99410685af4fe8b941cfd0c89d47c 100644 (file)
@@ -31,21 +31,25 @@ type Symbol struct {
        // ElfType is set for symbols read from shared libraries by ldshlibsyms. It
        // is not set for symbols defined by the packages being linked or by symbols
        // read by ldelf (and so is left as elf.STT_NOTYPE).
-       ElfType    elf.SymType
-       Sub        *Symbol
-       Outer      *Symbol
-       Gotype     *Symbol
-       File       string
-       Dynimplib  string
-       Dynimpvers string
-       Sect       *Section
-       FuncInfo   *FuncInfo
-       Lib        *Library // Package defining this symbol
+       ElfType  elf.SymType
+       Sub      *Symbol
+       Outer    *Symbol
+       Gotype   *Symbol
+       File     string
+       dyninfo  *dynimp
+       Sect     *Section
+       FuncInfo *FuncInfo
+       Lib      *Library // Package defining this symbol
        // P contains the raw symbol data.
        P []byte
        R []Reloc
 }
 
+type dynimp struct {
+       dynimplib  string
+       dynimpvers string
+}
+
 func (s *Symbol) String() string {
        if s.Version == 0 {
                return s.Name
@@ -264,6 +268,40 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
        return off + wid
 }
 
+func (s *Symbol) Dynimplib() string {
+       if s.dyninfo == nil {
+               return ""
+       }
+       return s.dyninfo.dynimplib
+}
+
+func (s *Symbol) Dynimpvers() string {
+       if s.dyninfo == nil {
+               return ""
+       }
+       return s.dyninfo.dynimpvers
+}
+
+func (s *Symbol) SetDynimplib(lib string) {
+       if s.dyninfo == nil {
+               s.dyninfo = &dynimp{dynimplib: lib}
+       } else {
+               s.dyninfo.dynimplib = lib
+       }
+}
+
+func (s *Symbol) SetDynimpvers(vers string) {
+       if s.dyninfo == nil {
+               s.dyninfo = &dynimp{dynimpvers: vers}
+       } else {
+               s.dyninfo.dynimpvers = vers
+       }
+}
+
+func (s *Symbol) ResetDyninfo() {
+       s.dyninfo = nil
+}
+
 // SortSub sorts a linked-list (by Sub) of *Symbol by Value.
 // Used for sub-symbols when loading host objects (see e.g. ldelf.go).
 func SortSub(l *Symbol) *Symbol {