From 198679832ad627ee88ed5b3d75cc96819889a51c Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 28 Jun 2018 15:42:20 -0400 Subject: [PATCH] cmd/link: use side table instead of sym.Symbol 'Reachparent' field The sym.Symbol 'Reachparent' field is used only when field tracking is enabled. So as to use less memory for the common case where field tracking is not enabled, remove this field and use a side table stored in the context to achieve the same functionality. Updates #26186 Change-Id: Idc5f8b0aa323689d4d51dddb5d1b0341a37bb7d2 Reviewed-on: https://go-review.googlesource.com/121915 Reviewed-by: Ian Lance Taylor --- src/cmd/link/internal/ld/deadcode.go | 4 +++- src/cmd/link/internal/ld/go.go | 2 +- src/cmd/link/internal/ld/link.go | 3 +++ src/cmd/link/internal/ld/main.go | 5 +++++ src/cmd/link/internal/sym/symbol.go | 21 ++++++++++----------- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index ce0fe1f7a1329..540f4068cb8ea 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -190,7 +190,9 @@ func (d *deadcodepass) mark(s, parent *sym.Symbol) { fmt.Printf("%s -> %s\n", p, s.Name) } s.Attr |= sym.AttrReachable - s.Reachparent = parent + if d.ctxt.Reachparent != nil { + d.ctxt.Reachparent[s] = parent + } d.markQueue = append(d.markQueue, s) } diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index 8d50332c7c6e1..eb6c2ccc83128 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go @@ -294,7 +294,7 @@ func fieldtrack(ctxt *Link) { s.Attr |= sym.AttrNotInSymbolTable if s.Attr.Reachable() { buf.WriteString(s.Name[9:]) - for p := s.Reachparent; p != nil; p = p.Reachparent { + for p := ctxt.Reachparent[s]; p != nil; p = ctxt.Reachparent[p] { buf.WriteString("\t") buf.WriteString(p.Name) } diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go index 2e66cf857c3ed..bf5754435786f 100644 --- a/src/cmd/link/internal/ld/link.go +++ b/src/cmd/link/internal/ld/link.go @@ -86,6 +86,9 @@ type Link struct { // unresolvedSymSet is a set of erroneous unresolved references. // Used to avoid duplicated error messages. unresolvedSymSet map[unresolvedSymKey]bool + + // Used to implement field tracking. + Reachparent map[*sym.Symbol]*sym.Symbol } type unresolvedSymKey struct { diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index d7929d59fdddf..23462f1154b7e 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -34,6 +34,7 @@ import ( "bufio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/sym" "flag" "log" "os" @@ -144,6 +145,10 @@ func Main(arch *sys.Arch, theArch Arch) { } } + if objabi.Fieldtrack_enabled != 0 { + ctxt.Reachparent = make(map[*sym.Symbol]*sym.Symbol) + } + startProfile() if ctxt.BuildMode == BuildModeUnset { ctxt.BuildMode = BuildModeExe diff --git a/src/cmd/link/internal/sym/symbol.go b/src/cmd/link/internal/sym/symbol.go index b3ff6c4e19079..8893dcf0d69e1 100644 --- a/src/cmd/link/internal/sym/symbol.go +++ b/src/cmd/link/internal/sym/symbol.go @@ -31,17 +31,16 @@ 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 - Reachparent *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 + Dynimplib string + Dynimpvers string + Sect *Section + FuncInfo *FuncInfo + Lib *Library // Package defining this symbol // P contains the raw symbol data. P []byte R []Reloc