From 6cbf37b30b852164b1cd098e0369498ca72ede09 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 16 Oct 2019 09:29:56 -0400 Subject: [PATCH] [dev.link] cmd/link: record go.itablink symbols during object file read Change the new loader to keep a note of the set of "go.itablink.*" symbols (using a small map), and add a method that clients can use to query whether a given global index corresponds to a "go.itablink.*" sym. This eliminates one instance of raw symbol name reading/matching during new deadcode, which should produce a minor speedup. Change-Id: I5915773a3f33c16099ccd68592dbba783d909bc9 Reviewed-on: https://go-review.googlesource.com/c/go/+/201400 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/link/internal/ld/deadcode2.go | 3 +-- src/cmd/link/internal/loader/loader.go | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/cmd/link/internal/ld/deadcode2.go b/src/cmd/link/internal/ld/deadcode2.go index 818024069e8..82626c7a289 100644 --- a/src/cmd/link/internal/ld/deadcode2.go +++ b/src/cmd/link/internal/ld/deadcode2.go @@ -11,7 +11,6 @@ import ( "cmd/link/internal/loader" "cmd/link/internal/sym" "fmt" - "strings" "unicode" ) @@ -226,7 +225,7 @@ func deadcode2(ctxt *Link) { // (When BuildModeShared, always keep itablinks.) for i := 1; i < n; i++ { s := loader.Sym(i) - if strings.HasPrefix(ldr.RawSymName(s), "go.itablink.") { // TODO: use an attribute instread of checking name + if ldr.IsItabLink(s) { relocs := ldr.Relocs(s) if relocs.Count > 0 && ldr.Reachable.Has(relocs.At(0).Sym) { ldr.Reachable.Set(s) diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 708e8d0d3ec..5f631f16256 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -100,6 +100,8 @@ type Loader struct { symsByName map[nameVer]Sym // map symbol name to index overwrite map[Sym]Sym // overwrite[i]=j if symbol j overwrites symbol i + itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.* + objByPkg map[string]*oReader // map package path to its Go object reader Syms []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now. @@ -114,6 +116,7 @@ func NewLoader() *Loader { symsByName: make(map[nameVer]Sym), objByPkg: make(map[string]*oReader), overwrite: make(map[Sym]Sym), + itablink: make(map[Sym]struct{}), } } @@ -369,6 +372,14 @@ func (l *Loader) IsGoType(i Sym) bool { return l.SymAttr(i)&goobj2.SymFlagGoType != 0 } +// Returns whether this is a "go.itablink.*" symbol. +func (l *Loader) IsItabLink(i Sym) bool { + if _, ok := l.itablink[i]; ok { + return true + } + return false +} + // Returns the symbol content of the i-th symbol. i is global index. func (l *Loader) Data(i Sym) []byte { if l.isExternal(i) { @@ -491,7 +502,10 @@ func (l *Loader) Preload(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib * } v := abiToVer(osym.ABI, localSymVersion) dupok := osym.Dupok() - l.AddSym(name, v, istart+Sym(i), or, dupok, sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]) + added := l.AddSym(name, v, istart+Sym(i), or, dupok, sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]) + if added && strings.HasPrefix(name, "go.itablink.") { + l.itablink[istart+Sym(i)] = struct{}{} + } } // The caller expects us consuming all the data