mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: make Allsym a slice
Looks a tiny bit faster, which is a surprise. Probably noise. Motivation is making the LSym structure a little easier to understand. Linking juju, best of 10: before: real 0m4.811s user 0m5.582s after: real 0m4.611s user 0m5.267s Change-Id: Idbedaf4a6e6e199036a1bbb6760e98c94ed2c282 Reviewed-on: https://go-review.googlesource.com/20142 Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com> Run-TryBot: David Crawshaw <crawshaw@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
4598382724
commit
4b92cd4ec1
10 changed files with 29 additions and 39 deletions
|
|
@ -97,7 +97,7 @@ func hostArchive(name string) {
|
||||||
any := true
|
any := true
|
||||||
for any {
|
for any {
|
||||||
var load []uint64
|
var load []uint64
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
for _, r := range s.R {
|
for _, r := range s.R {
|
||||||
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF {
|
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF {
|
||||||
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
|
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
|
||||||
|
|
|
||||||
|
|
@ -1006,7 +1006,7 @@ func addinitarrdata(s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dosymtype() {
|
func dosymtype() {
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if len(s.P) > 0 {
|
if len(s.P) > 0 {
|
||||||
if s.Type == obj.SBSS {
|
if s.Type == obj.SBSS {
|
||||||
s.Type = obj.SDATA
|
s.Type = obj.SDATA
|
||||||
|
|
@ -1145,7 +1145,7 @@ func dodata() {
|
||||||
var last *LSym
|
var last *LSym
|
||||||
datap = nil
|
datap = nil
|
||||||
|
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if !s.Reachable || s.Special != 0 {
|
if !s.Reachable || s.Special != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1361,9 +1361,7 @@ func elfdynhash() {
|
||||||
buckets := make([]uint32, nbucket)
|
buckets := make([]uint32, nbucket)
|
||||||
|
|
||||||
var b int
|
var b int
|
||||||
var hc uint32
|
for _, sy := range Ctxt.Allsym {
|
||||||
var name string
|
|
||||||
for sy := Ctxt.Allsym; sy != nil; sy = sy.Allsym {
|
|
||||||
if sy.Dynid <= 0 {
|
if sy.Dynid <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1372,8 +1370,8 @@ func elfdynhash() {
|
||||||
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
|
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
|
||||||
}
|
}
|
||||||
|
|
||||||
name = sy.Extname
|
name := sy.Extname
|
||||||
hc = elfhash([]byte(name))
|
hc := elfhash([]byte(name))
|
||||||
|
|
||||||
b = int(hc % uint32(nbucket))
|
b = int(hc % uint32(nbucket))
|
||||||
chain[sy.Dynid] = buckets[b]
|
chain[sy.Dynid] = buckets[b]
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,7 @@ func deadcode() {
|
||||||
if Buildmode == BuildmodeShared {
|
if Buildmode == BuildmodeShared {
|
||||||
// Mark all symbols defined in this library as reachable when
|
// Mark all symbols defined in this library as reachable when
|
||||||
// building a shared library.
|
// building a shared library.
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if s.Type != 0 && s.Type != obj.SDYNIMPORT {
|
if s.Type != 0 && s.Type != obj.SDYNIMPORT {
|
||||||
mark(s)
|
mark(s)
|
||||||
}
|
}
|
||||||
|
|
@ -471,7 +471,7 @@ func deadcode() {
|
||||||
markflood()
|
markflood()
|
||||||
|
|
||||||
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
|
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.typelink.") {
|
if strings.HasPrefix(s.Name, "go.typelink.") {
|
||||||
s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
|
s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
|
||||||
}
|
}
|
||||||
|
|
@ -503,7 +503,7 @@ func deadcode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.weak.") {
|
if strings.HasPrefix(s.Name, "go.weak.") {
|
||||||
s.Special = 1 // do not lay out in data segment
|
s.Special = 1 // do not lay out in data segment
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
@ -513,14 +513,13 @@ func deadcode() {
|
||||||
|
|
||||||
// record field tracking references
|
// record field tracking references
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
var p *LSym
|
for _, s := range Ctxt.Allsym {
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
|
||||||
if strings.HasPrefix(s.Name, "go.track.") {
|
if strings.HasPrefix(s.Name, "go.track.") {
|
||||||
s.Special = 1 // do not lay out in data segment
|
s.Special = 1 // do not lay out in data segment
|
||||||
s.Hidden = true
|
s.Hidden = true
|
||||||
if s.Reachable {
|
if s.Reachable {
|
||||||
buf.WriteString(s.Name[9:])
|
buf.WriteString(s.Name[9:])
|
||||||
for p = s.Reachparent; p != nil; p = p.Reachparent {
|
for p := s.Reachparent; p != nil; p = p.Reachparent {
|
||||||
buf.WriteString("\t")
|
buf.WriteString("\t")
|
||||||
buf.WriteString(p.Name)
|
buf.WriteString(p.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -543,13 +542,11 @@ func deadcode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func doweak() {
|
func doweak() {
|
||||||
var t *LSym
|
|
||||||
|
|
||||||
// resolve weak references only if
|
// resolve weak references only if
|
||||||
// target symbol will be in binary anyway.
|
// target symbol will be in binary anyway.
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.weak.") {
|
if strings.HasPrefix(s.Name, "go.weak.") {
|
||||||
t = Linkrlookup(Ctxt, s.Name[8:], int(s.Version))
|
t := Linkrlookup(Ctxt, s.Name[8:], int(s.Version))
|
||||||
if t != nil && t.Type != 0 && t.Reachable {
|
if t != nil && t.Type != 0 && t.Reachable {
|
||||||
s.Value = t.Value
|
s.Value = t.Value
|
||||||
s.Type = t.Type
|
s.Type = t.Type
|
||||||
|
|
|
||||||
|
|
@ -599,7 +599,7 @@ func loadlib() {
|
||||||
if Linkmode == LinkInternal {
|
if Linkmode == LinkInternal {
|
||||||
// Drop all the cgo_import_static declarations.
|
// Drop all the cgo_import_static declarations.
|
||||||
// Turns out we won't be needing them.
|
// Turns out we won't be needing them.
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if s.Type == obj.SHOSTOBJ {
|
if s.Type == obj.SHOSTOBJ {
|
||||||
// If a symbol was marked both
|
// If a symbol was marked both
|
||||||
// cgo_import_static and cgo_import_dynamic,
|
// cgo_import_static and cgo_import_dynamic,
|
||||||
|
|
@ -679,7 +679,7 @@ func loadlib() {
|
||||||
// If we have any undefined symbols in external
|
// If we have any undefined symbols in external
|
||||||
// objects, try to read them from the libgcc file.
|
// objects, try to read them from the libgcc file.
|
||||||
any := false
|
any := false
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
for _, r := range s.R {
|
for _, r := range s.R {
|
||||||
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF && r.Sym.Name != ".got" {
|
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF && r.Sym.Name != ".got" {
|
||||||
any = true
|
any = true
|
||||||
|
|
@ -1904,7 +1904,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if s.Hidden || ((s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC.") {
|
if s.Hidden || ((s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC.") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ type LSym struct {
|
||||||
Locals int32
|
Locals int32
|
||||||
Value int64
|
Value int64
|
||||||
Size int64
|
Size int64
|
||||||
Allsym *LSym
|
|
||||||
Next *LSym
|
Next *LSym
|
||||||
Sub *LSym
|
Sub *LSym
|
||||||
Outer *LSym
|
Outer *LSym
|
||||||
|
|
@ -142,7 +141,7 @@ type Link struct {
|
||||||
Windows int32
|
Windows int32
|
||||||
Goroot string
|
Goroot string
|
||||||
Hash map[symVer]*LSym
|
Hash map[symVer]*LSym
|
||||||
Allsym *LSym
|
Allsym []*LSym
|
||||||
Nsymbol int32
|
Nsymbol int32
|
||||||
Tlsg *LSym
|
Tlsg *LSym
|
||||||
Libdir []string
|
Libdir []string
|
||||||
|
|
|
||||||
|
|
@ -652,7 +652,7 @@ func (x machoscmp) Less(i, j int) bool {
|
||||||
|
|
||||||
func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
genasmsym(put)
|
genasmsym(put)
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
|
if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
|
||||||
if s.Reachable {
|
if s.Reachable {
|
||||||
put(s, "", 'D', 0, 0, 0, nil)
|
put(s, "", 'D', 0, 0, 0, nil)
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ func initdynimport() *Dll {
|
||||||
|
|
||||||
dr = nil
|
dr = nil
|
||||||
var m *Imp
|
var m *Imp
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if !s.Reachable || s.Type != obj.SDYNIMPORT {
|
if !s.Reachable || s.Type != obj.SDYNIMPORT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -692,7 +692,7 @@ func (s byExtname) Less(i, j int) bool { return s[i].Extname < s[j].Extname }
|
||||||
|
|
||||||
func initdynexport() {
|
func initdynexport() {
|
||||||
nexport = 0
|
nexport = 0
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
|
if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,13 @@ var headers = []struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func linknew(arch *LinkArch) *Link {
|
func linknew(arch *LinkArch) *Link {
|
||||||
ctxt := new(Link)
|
ctxt := &Link{
|
||||||
// Preallocate about 2mb for hash
|
Hash: make(map[symVer]*LSym, 100000), // preallocate about 2mb for hash
|
||||||
ctxt.Hash = make(map[symVer]*LSym, 100000)
|
Allsym: make([]*LSym, 0, 100000),
|
||||||
ctxt.Arch = arch
|
Arch: arch,
|
||||||
ctxt.Version = obj.HistVersion
|
Version: obj.HistVersion,
|
||||||
ctxt.Goroot = obj.Getgoroot()
|
Goroot: obj.Getgoroot(),
|
||||||
|
}
|
||||||
|
|
||||||
p := obj.Getgoarch()
|
p := obj.Getgoarch()
|
||||||
if p != arch.Name {
|
if p != arch.Name {
|
||||||
|
|
@ -168,15 +169,10 @@ func linknewsym(ctxt *Link, symb string, v int) *LSym {
|
||||||
s.Plt = -1
|
s.Plt = -1
|
||||||
s.Got = -1
|
s.Got = -1
|
||||||
s.Name = symb
|
s.Name = symb
|
||||||
s.Type = 0
|
|
||||||
s.Version = int16(v)
|
s.Version = int16(v)
|
||||||
s.Value = 0
|
|
||||||
s.Size = 0
|
|
||||||
ctxt.Nsymbol++
|
ctxt.Nsymbol++
|
||||||
|
|
||||||
s.Allsym = ctxt.Allsym
|
ctxt.Allsym = append(ctxt.Allsym, s)
|
||||||
ctxt.Allsym = s
|
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -461,7 +461,7 @@ func symtab() {
|
||||||
// within a type they sort by size, so the .* symbols
|
// within a type they sort by size, so the .* symbols
|
||||||
// just defined above will be first.
|
// just defined above will be first.
|
||||||
// hide the specific symbols.
|
// hide the specific symbols.
|
||||||
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
for _, s := range Ctxt.Allsym {
|
||||||
if !s.Reachable || s.Special != 0 || s.Type != obj.SRODATA {
|
if !s.Reachable || s.Special != 0 || s.Type != obj.SRODATA {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue