mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/internal/goobj2, cmd/link: experiment new aux symbol accessors
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>
This commit is contained in:
parent
8e100a05a5
commit
8a074fa275
4 changed files with 71 additions and 20 deletions
|
|
@ -368,6 +368,15 @@ func (a *Aux) Size() int {
|
||||||
return 1 + a.Sym.Size()
|
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 {
|
type Writer struct {
|
||||||
wr *bio.Writer
|
wr *bio.Writer
|
||||||
stringMap map[string]uint32
|
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)
|
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.
|
// DataOff returns the offset of the i-th symbol's data.
|
||||||
func (r *Reader) DataOff(i int) uint32 {
|
func (r *Reader) DataOff(i int) uint32 {
|
||||||
dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
|
dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,20 @@ func dummyWriter() *Writer {
|
||||||
func TestSize(t *testing.T) {
|
func TestSize(t *testing.T) {
|
||||||
// This test checks that hard-coded sizes match the actual sizes
|
// This test checks that hard-coded sizes match the actual sizes
|
||||||
// in the object file format.
|
// in the object file format.
|
||||||
|
tests := []struct {
|
||||||
|
x interface{ Write(*Writer) }
|
||||||
|
want uint32
|
||||||
|
}{
|
||||||
|
{&Reloc{}, RelocSize},
|
||||||
|
{&Aux{}, AuxSize},
|
||||||
|
}
|
||||||
w := dummyWriter()
|
w := dummyWriter()
|
||||||
(&Reloc{}).Write(w)
|
for _, test := range tests {
|
||||||
off := w.off
|
off0 := w.off
|
||||||
if sz := uint32(RelocSize); off != sz {
|
test.x.Write(w)
|
||||||
t.Errorf("size mismatch: %d bytes written, but size=%d", off, sz)
|
got := w.off - off0
|
||||||
|
if got != test.want {
|
||||||
|
t.Errorf("size(%T) mismatch: %d bytes written, but size=%d", test.x, got, test.want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,6 @@ func (d *deadcodePass2) init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deadcodePass2) flood() {
|
func (d *deadcodePass2) flood() {
|
||||||
auxSyms := []loader.Sym{}
|
|
||||||
for !d.wq.empty() {
|
for !d.wq.empty() {
|
||||||
symIdx := d.wq.pop()
|
symIdx := d.wq.pop()
|
||||||
|
|
||||||
|
|
@ -162,9 +161,9 @@ func (d *deadcodePass2) flood() {
|
||||||
}
|
}
|
||||||
d.mark(r.Sym(), symIdx)
|
d.mark(r.Sym(), symIdx)
|
||||||
}
|
}
|
||||||
auxSyms = d.ldr.ReadAuxSyms(symIdx, auxSyms)
|
naux := d.ldr.NAux(symIdx)
|
||||||
for i := 0; i < len(auxSyms); i++ {
|
for i := 0; i < naux; i++ {
|
||||||
d.mark(auxSyms[i], symIdx)
|
d.mark(d.ldr.Aux2(symIdx, i).Sym(), symIdx)
|
||||||
}
|
}
|
||||||
// Some host object symbols have an outer object, which acts like a
|
// Some host object symbols have an outer object, which acts like a
|
||||||
// "carrier" symbol, or it holds all the symbols for a particular
|
// "carrier" symbol, or it holds all the symbols for a particular
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,16 @@ type Reloc2 struct {
|
||||||
func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) + rel.typ }
|
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()) }
|
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
|
// oReader is a wrapper type of obj.Reader, along with some
|
||||||
// extra information.
|
// extra information.
|
||||||
// TODO: rename to objReader once the old one is gone?
|
// TODO: rename to objReader once the old one is gone?
|
||||||
|
|
@ -1164,13 +1174,12 @@ func (l *Loader) SymGoType(i Sym) Sym {
|
||||||
return pp.gotype
|
return pp.gotype
|
||||||
}
|
}
|
||||||
r, li := l.toLocal(i)
|
r, li := l.toLocal(i)
|
||||||
naux := r.NAux(li)
|
auxs := r.Auxs2(li)
|
||||||
for j := 0; j < naux; j++ {
|
for j := range auxs {
|
||||||
a := goobj2.Aux{}
|
a := &auxs[j]
|
||||||
a.Read(r.Reader, r.AuxOff(li, j))
|
switch a.Type() {
|
||||||
switch a.Type {
|
|
||||||
case goobj2.AuxGotype:
|
case goobj2.AuxGotype:
|
||||||
return l.resolve(r, a.Sym)
|
return l.resolve(r, a.Sym())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -1266,6 +1275,18 @@ func (l *Loader) AuxSym(i Sym, j int) Sym {
|
||||||
return l.resolve(r, a.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
|
// GetFuncDwarfAuxSyms collects and returns the auxiliary DWARF
|
||||||
// symbols associated with a given function symbol. Prior to the
|
// symbols associated with a given function symbol. Prior to the
|
||||||
// introduction of the loader, this was done purely using name
|
// introduction of the loader, this was done purely using name
|
||||||
|
|
@ -1593,12 +1614,11 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo {
|
||||||
return FuncInfo{}
|
return FuncInfo{}
|
||||||
}
|
}
|
||||||
r, li := l.toLocal(i)
|
r, li := l.toLocal(i)
|
||||||
n := r.NAux(li)
|
auxs := r.Auxs2(li)
|
||||||
for j := 0; j < n; j++ {
|
for j := range auxs {
|
||||||
a := goobj2.Aux{}
|
a := &auxs[j]
|
||||||
a.Read(r.Reader, r.AuxOff(li, j))
|
if a.Type() == goobj2.AuxFuncInfo {
|
||||||
if a.Type == goobj2.AuxFuncInfo {
|
b := r.Data(int(a.Sym().SymIdx))
|
||||||
b := r.Data(int(a.Sym.SymIdx))
|
|
||||||
return FuncInfo{l, r, b}
|
return FuncInfo{l, r, b}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue