]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/internal/goobj2, cmd/link: experiment new aux symbol accessors
authorCherry Zhang <cherryyz@google.com>
Fri, 6 Mar 2020 06:15:07 +0000 (01:15 -0500)
committerCherry Zhang <cherryyz@google.com>
Mon, 16 Mar 2020 17:33:43 +0000 (17:33 +0000)
Following the previous CLs, do the same for aux symbols. This has
some small speedup:

(linking cmd/compile)
Dostkcheck    41.0ms ± 1%    38.6ms ± 1%    -6.00%  (p=0.008 n=5+5)

Change-Id: Id62b2fc9e4ef1be92e60e4c03faec0a953eee94e
Reviewed-on: https://go-review.googlesource.com/c/go/+/222303
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/internal/goobj2/objfile.go
src/cmd/internal/goobj2/objfile_test.go
src/cmd/link/internal/ld/deadcode2.go
src/cmd/link/internal/loader/loader.go

index ca254b28e01bdab6871329c7d9adc8421fbe7319..3336f6cffffadee6fb2f7e31b7619392e47d39e3 100644 (file)
@@ -368,6 +368,15 @@ func (a *Aux) Size() int {
        return 1 + a.Sym.Size()
 }
 
+const AuxSize = 9 // TODO: is it possible to not hard-code this?
+
+type Aux2 [AuxSize]byte
+
+func (a *Aux2) Type() uint8 { return a[0] }
+func (a *Aux2) Sym() SymRef {
+       return SymRef{binary.LittleEndian.Uint32(a[1:]), binary.LittleEndian.Uint32(a[5:])}
+}
+
 type Writer struct {
        wr        *bio.Writer
        stringMap map[string]uint32
@@ -616,6 +625,19 @@ func (r *Reader) AuxOff(i int, j int) uint32 {
        return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(auxsiz)
 }
 
+// Aux2 returns a pointer to the j-th aux symbol of the i-th symbol.
+func (r *Reader) Aux2(i int, j int) *Aux2 {
+       off := r.AuxOff(i, j)
+       return (*Aux2)(unsafe.Pointer(&r.b[off]))
+}
+
+// Auxs2 returns the aux symbols of the i-th symbol.
+func (r *Reader) Auxs2(i int) []Aux2 {
+       off := r.AuxOff(i, 0)
+       n := r.NAux(i)
+       return (*[1 << 20]Aux2)(unsafe.Pointer(&r.b[off]))[:n:n]
+}
+
 // DataOff returns the offset of the i-th symbol's data.
 func (r *Reader) DataOff(i int) uint32 {
        dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
index eea97d4756f097c208bc9a994b61c6d486bcd5d7..ee15136cbe3df6db0bde63a047fdf7440a898bca 100644 (file)
@@ -20,10 +20,20 @@ func dummyWriter() *Writer {
 func TestSize(t *testing.T) {
        // This test checks that hard-coded sizes match the actual sizes
        // in the object file format.
+       tests := []struct {
+               x    interface{ Write(*Writer) }
+               want uint32
+       }{
+               {&Reloc{}, RelocSize},
+               {&Aux{}, AuxSize},
+       }
        w := dummyWriter()
-       (&Reloc{}).Write(w)
-       off := w.off
-       if sz := uint32(RelocSize); off != sz {
-               t.Errorf("size mismatch: %d bytes written, but size=%d", off, sz)
+       for _, test := range tests {
+               off0 := w.off
+               test.x.Write(w)
+               got := w.off - off0
+               if got != test.want {
+                       t.Errorf("size(%T) mismatch: %d bytes written, but size=%d", test.x, got, test.want)
+               }
        }
 }
index cbf7e22dbdbf4d25a08b189de363dc857d6876d6..5088a6e1beb64cf92687d3f1831a559fd8ce8453 100644 (file)
@@ -118,7 +118,6 @@ func (d *deadcodePass2) init() {
 }
 
 func (d *deadcodePass2) flood() {
-       auxSyms := []loader.Sym{}
        for !d.wq.empty() {
                symIdx := d.wq.pop()
 
@@ -162,9 +161,9 @@ func (d *deadcodePass2) flood() {
                        }
                        d.mark(r.Sym(), symIdx)
                }
-               auxSyms = d.ldr.ReadAuxSyms(symIdx, auxSyms)
-               for i := 0; i < len(auxSyms); i++ {
-                       d.mark(auxSyms[i], symIdx)
+               naux := d.ldr.NAux(symIdx)
+               for i := 0; i < naux; i++ {
+                       d.mark(d.ldr.Aux2(symIdx, i).Sym(), symIdx)
                }
                // Some host object symbols have an outer object, which acts like a
                // "carrier" symbol, or it holds all the symbols for a particular
index 93cfd44b8f6d7cfd39b7daefab4125bf7f00747b..a3028fcc86b1195dd4caae2ff77bab1af519ace7 100644 (file)
@@ -69,6 +69,16 @@ type Reloc2 struct {
 func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) + rel.typ }
 func (rel Reloc2) Sym() Sym               { return rel.l.resolve(rel.r, rel.Reloc2.Sym()) }
 
+// Aux2 holds a "handle" to access an aux symbol record from an
+// object file.
+type Aux2 struct {
+       *goobj2.Aux2
+       r *oReader
+       l *Loader
+}
+
+func (a Aux2) Sym() Sym { return a.l.resolve(a.r, a.Aux2.Sym()) }
+
 // oReader is a wrapper type of obj.Reader, along with some
 // extra information.
 // TODO: rename to objReader once the old one is gone?
@@ -1164,13 +1174,12 @@ func (l *Loader) SymGoType(i Sym) Sym {
                return pp.gotype
        }
        r, li := l.toLocal(i)
-       naux := r.NAux(li)
-       for j := 0; j < naux; j++ {
-               a := goobj2.Aux{}
-               a.Read(r.Reader, r.AuxOff(li, j))
-               switch a.Type {
+       auxs := r.Auxs2(li)
+       for j := range auxs {
+               a := &auxs[j]
+               switch a.Type() {
                case goobj2.AuxGotype:
-                       return l.resolve(r, a.Sym)
+                       return l.resolve(r, a.Sym())
                }
        }
        return 0
@@ -1266,6 +1275,18 @@ func (l *Loader) AuxSym(i Sym, j int) Sym {
        return l.resolve(r, a.Sym)
 }
 
+// Returns the "handle" to the j-th aux symbol of the i-th symbol.
+func (l *Loader) Aux2(i Sym, j int) Aux2 {
+       if l.IsExternal(i) {
+               return Aux2{}
+       }
+       r, li := l.toLocal(i)
+       if j >= r.NAux(li) {
+               return Aux2{}
+       }
+       return Aux2{r.Aux2(li, j), r, l}
+}
+
 // GetFuncDwarfAuxSyms collects and returns the auxiliary DWARF
 // symbols associated with a given function symbol.  Prior to the
 // introduction of the loader, this was done purely using name
@@ -1593,12 +1614,11 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo {
                return FuncInfo{}
        }
        r, li := l.toLocal(i)
-       n := r.NAux(li)
-       for j := 0; j < n; j++ {
-               a := goobj2.Aux{}
-               a.Read(r.Reader, r.AuxOff(li, j))
-               if a.Type == goobj2.AuxFuncInfo {
-                       b := r.Data(int(a.Sym.SymIdx))
+       auxs := r.Auxs2(li)
+       for j := range auxs {
+               a := &auxs[j]
+               if a.Type() == goobj2.AuxFuncInfo {
+                       b := r.Data(int(a.Sym().SymIdx))
                        return FuncInfo{l, r, b}
                }
        }