Skip to content

Commit d592ac1

Browse files
committed
cmd/link: split off 'Dynimp' string fields to reduce sym.Symbol size
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 <[email protected]>
1 parent 1986798 commit d592ac1

File tree

7 files changed

+61
-24
lines changed

7 files changed

+61
-24
lines changed

src/cmd/link/internal/ld/elf.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,8 @@ func elfdynhash(ctxt *Link) {
10301030
continue
10311031
}
10321032

1033-
if sy.Dynimpvers != "" {
1034-
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
1033+
if sy.Dynimpvers() != "" {
1034+
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
10351035
}
10361036

10371037
name := sy.Extname
@@ -2287,8 +2287,8 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) {
22872287
/* size of object */
22882288
d.AddUint64(ctxt.Arch, uint64(s.Size))
22892289

2290-
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
2291-
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
2290+
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] {
2291+
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib())))
22922292
}
22932293
} else {
22942294
s.Dynid = int32(Nelfsym)

src/cmd/link/internal/ld/go.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
155155
}
156156
s := ctxt.Syms.Lookup(local, 0)
157157
if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
158-
s.Dynimplib = lib
158+
s.SetDynimplib(lib)
159159
s.Extname = remote
160-
s.Dynimpvers = q
160+
s.SetDynimpvers(q)
161161
if s.Type != sym.SHOSTOBJ {
162162
s.Type = sym.SDYNIMPORT
163163
}
@@ -198,10 +198,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
198198

199199
// export overrides import, for openbsd/cgo.
200200
// see issue 4878.
201-
if s.Dynimplib != "" {
202-
s.Dynimplib = ""
201+
if s.Dynimplib() != "" {
202+
s.ResetDyninfo()
203203
s.Extname = ""
204-
s.Dynimpvers = ""
205204
s.Type = 0
206205
}
207206

src/cmd/link/internal/ld/lib.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ func (ctxt *Link) loadlib() {
416416
// cgo_import_static and cgo_import_dynamic,
417417
// then we want to make it cgo_import_dynamic
418418
// now.
419-
if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
419+
if s.Extname != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
420420
s.Type = sym.SDYNIMPORT
421421
} else {
422422
s.Type = 0

src/cmd/link/internal/ld/pe.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -989,15 +989,15 @@ func initdynimport(ctxt *Link) *Dll {
989989
continue
990990
}
991991
for d = dr; d != nil; d = d.next {
992-
if d.name == s.Dynimplib {
992+
if d.name == s.Dynimplib() {
993993
m = new(Imp)
994994
break
995995
}
996996
}
997997

998998
if d == nil {
999999
d = new(Dll)
1000-
d.name = s.Dynimplib
1000+
d.name = s.Dynimplib()
10011001
d.next = dr
10021002
dr = d
10031003
m = new(Imp)

src/cmd/link/internal/loadelf/ldelf.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
805805
s.Type = sect.sym.Type
806806
s.Attr |= sym.AttrSubSymbol
807807
if !s.Attr.CgoExportDynamic() {
808-
s.Dynimplib = "" // satisfy dynimport
808+
s.SetDynimplib("") // satisfy dynimport
809809
}
810810
s.Value = int64(elfsym.value)
811811
s.Size = int64(elfsym.size)

src/cmd/link/internal/loadmacho/ldmacho.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
644644
s.Outer = outer
645645
s.Value = int64(machsym.value - sect.addr)
646646
if !s.Attr.CgoExportDynamic() {
647-
s.Dynimplib = "" // satisfy dynimport
647+
s.SetDynimplib("") // satisfy dynimport
648648
}
649649
if outer.Type == sym.STEXT {
650650
if s.Attr.External() && !s.Attr.DuplicateOK() {

src/cmd/link/internal/sym/symbol.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,25 @@ type Symbol struct {
3131
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
3232
// is not set for symbols defined by the packages being linked or by symbols
3333
// read by ldelf (and so is left as elf.STT_NOTYPE).
34-
ElfType elf.SymType
35-
Sub *Symbol
36-
Outer *Symbol
37-
Gotype *Symbol
38-
File string
39-
Dynimplib string
40-
Dynimpvers string
41-
Sect *Section
42-
FuncInfo *FuncInfo
43-
Lib *Library // Package defining this symbol
34+
ElfType elf.SymType
35+
Sub *Symbol
36+
Outer *Symbol
37+
Gotype *Symbol
38+
File string
39+
dyninfo *dynimp
40+
Sect *Section
41+
FuncInfo *FuncInfo
42+
Lib *Library // Package defining this symbol
4443
// P contains the raw symbol data.
4544
P []byte
4645
R []Reloc
4746
}
4847

48+
type dynimp struct {
49+
dynimplib string
50+
dynimpvers string
51+
}
52+
4953
func (s *Symbol) String() string {
5054
if s.Version == 0 {
5155
return s.Name
@@ -264,6 +268,40 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
264268
return off + wid
265269
}
266270

271+
func (s *Symbol) Dynimplib() string {
272+
if s.dyninfo == nil {
273+
return ""
274+
}
275+
return s.dyninfo.dynimplib
276+
}
277+
278+
func (s *Symbol) Dynimpvers() string {
279+
if s.dyninfo == nil {
280+
return ""
281+
}
282+
return s.dyninfo.dynimpvers
283+
}
284+
285+
func (s *Symbol) SetDynimplib(lib string) {
286+
if s.dyninfo == nil {
287+
s.dyninfo = &dynimp{dynimplib: lib}
288+
} else {
289+
s.dyninfo.dynimplib = lib
290+
}
291+
}
292+
293+
func (s *Symbol) SetDynimpvers(vers string) {
294+
if s.dyninfo == nil {
295+
s.dyninfo = &dynimp{dynimpvers: vers}
296+
} else {
297+
s.dyninfo.dynimpvers = vers
298+
}
299+
}
300+
301+
func (s *Symbol) ResetDyninfo() {
302+
s.dyninfo = nil
303+
}
304+
267305
// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
268306
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
269307
func SortSub(l *Symbol) *Symbol {

0 commit comments

Comments
 (0)