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>
any := true
for any {
var load []uint64
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
for _, r := range s.R {
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
}
func dosymtype() {
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if len(s.P) > 0 {
if s.Type == obj.SBSS {
s.Type = obj.SDATA
var last *LSym
datap = nil
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if !s.Reachable || s.Special != 0 {
continue
}
buckets := make([]uint32, nbucket)
var b int
- var hc uint32
- var name string
- for sy := Ctxt.Allsym; sy != nil; sy = sy.Allsym {
+ for _, sy := range Ctxt.Allsym {
if sy.Dynid <= 0 {
continue
}
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
}
- name = sy.Extname
- hc = elfhash([]byte(name))
+ name := sy.Extname
+ hc := elfhash([]byte(name))
b = int(hc % uint32(nbucket))
chain[sy.Dynid] = buckets[b]
if Buildmode == BuildmodeShared {
// Mark all symbols defined in this library as reachable when
// 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 {
mark(s)
}
markflood()
// 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.") {
s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
}
}
}
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.weak.") {
s.Special = 1 // do not lay out in data segment
s.Reachable = true
// record field tracking references
var buf bytes.Buffer
- var p *LSym
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.track.") {
s.Special = 1 // do not lay out in data segment
s.Hidden = true
if s.Reachable {
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(p.Name)
}
}
func doweak() {
- var t *LSym
-
// resolve weak references only if
// 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.") {
- 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 {
s.Value = t.Value
s.Type = t.Type
if Linkmode == LinkInternal {
// Drop all the cgo_import_static declarations.
// 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 a symbol was marked both
// cgo_import_static and cgo_import_dynamic,
// If we have any undefined symbols in external
// objects, try to read them from the libgcc file.
any := false
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
for _, r := range s.R {
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF && r.Sym.Name != ".got" {
any = true
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.") {
continue
}
Locals int32
Value int64
Size int64
- Allsym *LSym
Next *LSym
Sub *LSym
Outer *LSym
Windows int32
Goroot string
Hash map[symVer]*LSym
- Allsym *LSym
+ Allsym []*LSym
Nsymbol int32
Tlsg *LSym
Libdir []string
func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
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.Reachable {
put(s, "", 'D', 0, 0, 0, nil)
dr = nil
var m *Imp
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if !s.Reachable || s.Type != obj.SDYNIMPORT {
continue
}
func initdynexport() {
nexport = 0
- for s := Ctxt.Allsym; s != nil; s = s.Allsym {
+ for _, s := range Ctxt.Allsym {
if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
continue
}
}
func linknew(arch *LinkArch) *Link {
- ctxt := new(Link)
- // Preallocate about 2mb for hash
- ctxt.Hash = make(map[symVer]*LSym, 100000)
- ctxt.Arch = arch
- ctxt.Version = obj.HistVersion
- ctxt.Goroot = obj.Getgoroot()
+ ctxt := &Link{
+ Hash: make(map[symVer]*LSym, 100000), // preallocate about 2mb for hash
+ Allsym: make([]*LSym, 0, 100000),
+ Arch: arch,
+ Version: obj.HistVersion,
+ Goroot: obj.Getgoroot(),
+ }
p := obj.Getgoarch()
if p != arch.Name {
s.Plt = -1
s.Got = -1
s.Name = symb
- s.Type = 0
s.Version = int16(v)
- s.Value = 0
- s.Size = 0
ctxt.Nsymbol++
- s.Allsym = ctxt.Allsym
- ctxt.Allsym = s
-
+ ctxt.Allsym = append(ctxt.Allsym, s)
return s
}
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// 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 {
continue
}