]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use new relocation accessors in DWARF generation
authorCherry Zhang <cherryyz@google.com>
Mon, 16 Mar 2020 16:09:52 +0000 (12:09 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 16 Mar 2020 17:33:50 +0000 (17:33 +0000)
This gives some speedup and reduces some allocations:

(linking cmd/compile)
DwarfGenerateDebugInfo    63.2ms ± 3%    41.7ms ± 3%  -34.04%  (p=0.008 n=5+5)

DwarfGenerateDebugInfo    20.0MB ± 0%    10.1MB ± 0%  -49.62%  (p=0.008 n=5+5)

There are code that modify relocations, which are still using
the earlier loader.Reloc slice for now.

Change-Id: I3359ba305bf82cc882ae3c0f548d6ccfc8add789
Reviewed-on: https://go-review.googlesource.com/c/go/+/223663
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/deadcode2.go
src/cmd/link/internal/ld/decodesym2.go
src/cmd/link/internal/ld/dwarf.go

index 5088a6e1beb64cf92687d3f1831a559fd8ce8453..892f3f41e5753a30384a0efe4241bc4713aeadb0 100644 (file)
@@ -306,8 +306,8 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
        var buf bytes.Buffer
        var methods []methodsig
        for i := 0; i < count; i++ {
-               buf.WriteString(decodetypeName3(ldr, symIdx, relocs, off))
-               mtypSym := decodeRelocSym3(ldr, symIdx, relocs, int32(off+4))
+               buf.WriteString(decodetypeName2(ldr, symIdx, relocs, off))
+               mtypSym := decodeRelocSym2(ldr, symIdx, relocs, int32(off+4))
                // FIXME: add some sort of caching here, since we may see some of the
                // same symbols over time for param types.
                mrelocs := ldr.Relocs(mtypSym)
@@ -319,7 +319,7 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
                        if i > 0 {
                                buf.WriteString(", ")
                        }
-                       a := decodetypeFuncInType3(ldr, arch, mtypSym, &mrelocs, i)
+                       a := decodetypeFuncInType2(ldr, arch, mtypSym, &mrelocs, i)
                        buf.WriteString(ldr.SymName(a))
                }
                buf.WriteString(") (")
@@ -328,7 +328,7 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
                        if i > 0 {
                                buf.WriteString(", ")
                        }
-                       a := decodetypeFuncOutType3(ldr, arch, mtypSym, &mrelocs, i)
+                       a := decodetypeFuncOutType2(ldr, arch, mtypSym, &mrelocs, i)
                        buf.WriteString(ldr.SymName(a))
                }
                buf.WriteRune(')')
@@ -345,7 +345,7 @@ func (d *deadcodePass2) decodeIfaceMethods2(ldr *loader.Loader, arch *sys.Arch,
        if decodetypeKind(arch, p)&kindMask != kindInterface {
                panic(fmt.Sprintf("symbol %q is not an interface", ldr.SymName(symIdx)))
        }
-       rel := decodeReloc3(ldr, symIdx, relocs, int32(commonsize(arch)+arch.PtrSize))
+       rel := decodeReloc2(ldr, symIdx, relocs, int32(commonsize(arch)+arch.PtrSize))
        s := rel.Sym()
        if s == 0 {
                return nil
index e93cc91a9f1352daf62835377689e9a2a15baf45..d4967211221c80aac078d542ee994f4acc969fa4 100644 (file)
@@ -15,17 +15,7 @@ import (
 // At some point we'll want to migrate the contents of this file
 // to decodesym.go once the rouetines there have been decprecated + removed.
 
-func decodeReloc2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int32) loader.Reloc {
-       for j := 0; j < len(symRelocs); j++ {
-               rel := symRelocs[j]
-               if rel.Off == off {
-                       return rel
-               }
-       }
-       return loader.Reloc{}
-}
-
-func decodeReloc3(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Reloc2 {
+func decodeReloc2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Reloc2 {
        for j := 0; j < relocs.Count; j++ {
                rel := relocs.At2(j)
                if rel.Off() == off {
@@ -35,17 +25,13 @@ func decodeReloc3(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs,
        return loader.Reloc2{}
 }
 
-func decodeRelocSym2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int32) loader.Sym {
-       return decodeReloc2(ldr, symIdx, symRelocs, off).Sym
-}
-
-func decodeRelocSym3(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Sym {
-       return decodeReloc3(ldr, symIdx, relocs, off).Sym()
+func decodeRelocSym2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Sym {
+       return decodeReloc2(ldr, symIdx, relocs, off).Sym()
 }
 
 // decodetypeName2 decodes the name from a reflect.name.
-func decodetypeName2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int) string {
-       r := decodeRelocSym2(ldr, symIdx, symRelocs, int32(off))
+func decodetypeName2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) string {
+       r := decodeRelocSym2(ldr, symIdx, relocs, int32(off))
        if r == 0 {
                return ""
        }
@@ -55,18 +41,7 @@ func decodetypeName2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.R
        return string(data[3 : 3+namelen])
 }
 
-func decodetypeName3(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) string {
-       r := decodeRelocSym3(ldr, symIdx, relocs, int32(off))
-       if r == 0 {
-               return ""
-       }
-
-       data := ldr.Data(r)
-       namelen := int(uint16(data[1])<<8 | uint16(data[2]))
-       return string(data[3 : 3+namelen])
-}
-
-func decodetypeFuncInType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc, i int) loader.Sym {
+func decodetypeFuncInType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
        uadd := commonsize(arch) + 4
        if arch.PtrSize == 8 {
                uadd += 4
@@ -74,35 +49,16 @@ func decodetypeFuncInType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym
        if decodetypeHasUncommon(arch, ldr.Data(symIdx)) {
                uadd += uncommonSize()
        }
-       return decodeRelocSym2(ldr, symIdx, symRelocs, int32(uadd+i*arch.PtrSize))
-}
-
-func decodetypeFuncInType3(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
-       uadd := commonsize(arch) + 4
-       if arch.PtrSize == 8 {
-               uadd += 4
-       }
-       if decodetypeHasUncommon(arch, ldr.Data(symIdx)) {
-               uadd += uncommonSize()
-       }
-       return decodeRelocSym3(ldr, symIdx, relocs, int32(uadd+i*arch.PtrSize))
-}
-
-func decodetypeFuncOutType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc, i int) loader.Sym {
-       return decodetypeFuncInType2(ldr, arch, symIdx, symRelocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
+       return decodeRelocSym2(ldr, symIdx, relocs, int32(uadd+i*arch.PtrSize))
 }
 
-func decodetypeFuncOutType3(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
-       return decodetypeFuncInType3(ldr, arch, symIdx, relocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
+func decodetypeFuncOutType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
+       return decodetypeFuncInType2(ldr, arch, symIdx, relocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
 }
 
 func decodetypeArrayElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(commonsize(arch))) // 0x1c / 0x30
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 func decodetypeArrayLen2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int64 {
@@ -111,38 +67,23 @@ func decodetypeArrayLen2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym)
 }
 
 func decodetypeChanElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(commonsize(arch))) // 0x1c / 0x30
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 func decodetypeMapKey2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(commonsize(arch))) // 0x1c / 0x30
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 func decodetypeMapValue2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
 }
 
 func decodetypePtrElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(commonsize(arch))) // 0x1c / 0x30
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
 }
 
 func decodetypeStructFieldCount2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int {
@@ -162,22 +103,14 @@ func decodetypeStructFieldArrayOff2(ldr *loader.Loader, arch *sys.Arch, symIdx l
 
 func decodetypeStructFieldName2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) string {
        off := decodetypeStructFieldArrayOff2(ldr, arch, symIdx, i)
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodetypeName2(ldr, symIdx, rslice, off)
+       return decodetypeName2(ldr, symIdx, &relocs, off)
 }
 
 func decodetypeStructFieldType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) loader.Sym {
        off := decodetypeStructFieldArrayOff2(ldr, arch, symIdx, i)
-       // FIXME: it's inefficient to read the relocations each time. Add some
-       // sort of cache here, or pass in the relocs. Alternatively we could
-       // switch to relocs.At() to see if that performs better.
        relocs := ldr.Relocs(symIdx)
-       rslice := relocs.ReadAll(nil)
-       return decodeRelocSym2(ldr, symIdx, rslice, int32(off+arch.PtrSize))
+       return decodeRelocSym2(ldr, symIdx, &relocs, int32(off+arch.PtrSize))
 }
 
 func decodetypeStructFieldOffsAnon2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int64 {
index dcc957655ae418e34f7c9396f0cce57dfaffdf3f..a9a1a1c41f9bc3d56bd05abe353b2e827aee3949 100644 (file)
@@ -580,10 +580,9 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
                data := d.ldr.Data(gotype)
                // FIXME: add caching or reuse reloc slice.
                relocs := d.ldr.Relocs(gotype)
-               rslice := relocs.ReadAll(nil)
                nfields := decodetypeFuncInCount(d.arch, data)
                for i := 0; i < nfields; i++ {
-                       s := decodetypeFuncInType2(d.ldr, d.arch, gotype, rslice, i)
+                       s := decodetypeFuncInType2(d.ldr, d.arch, gotype, &relocs, i)
                        sn := d.ldr.SymName(s)
                        fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, sn[5:], 0)
                        d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
@@ -594,7 +593,7 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
                }
                nfields = decodetypeFuncOutCount(d.arch, data)
                for i := 0; i < nfields; i++ {
-                       s := decodetypeFuncOutType2(d.ldr, d.arch, gotype, rslice, i)
+                       s := decodetypeFuncOutType2(d.ldr, d.arch, gotype, &relocs, i)
                        sn := d.ldr.SymName(s)
                        fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, sn[5:], 0)
                        d.newrefattr(fld, dwarf.DW_AT_type, d.defptrto(d.defgotype(s)))
@@ -1109,22 +1108,22 @@ func (d *dwctxt2) importInfoSymbol(ctxt *Link, dsym loader.Sym) {
        if d.ldr.SymType(dsym) != sym.SDWARFINFO {
                log.Fatalf("error: DWARF info sym %d/%s with incorrect type %s", dsym, d.ldr.SymName(dsym), d.ldr.SymType(dsym).String())
        }
-       drelocs := d.ldr.Relocs(dsym)
-       rslice := drelocs.ReadSyms(nil)
-       for i := 0; i < len(rslice); i++ {
-               r := &rslice[i]
-               if r.Type != objabi.R_DWARFSECREF {
+       relocs := d.ldr.Relocs(dsym)
+       for i := 0; i < relocs.Count; i++ {
+               r := relocs.At2(i)
+               if r.Type() != objabi.R_DWARFSECREF {
                        continue
                }
+               rsym := r.Sym()
                // If there is an entry for the symbol in our rtmap, then it
                // means we've processed the type already, and can skip this one.
-               if _, ok := d.rtmap[r.Sym]; ok {
+               if _, ok := d.rtmap[rsym]; ok {
                        // type already generated
                        continue
                }
                // FIXME: is there a way we could avoid materializing the
                // symbol name here?
-               sn := d.ldr.SymName(r.Sym)
+               sn := d.ldr.SymName(rsym)
                tn := sn[len(dwarf.InfoPrefix):]
                ts := d.ldr.Lookup("type."+tn, 0)
                d.defgotype(ts)
@@ -1848,7 +1847,6 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
        // fake root DIE for compile unit DIEs
        var dwroot dwarf.DWDie
        flagVariants := make(map[string]bool)
-       var relocs []loader.Reloc
 
        for _, lib := range ctxt.Library {
 
@@ -1929,11 +1927,10 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
                                }
 
                                drelocs := d.ldr.Relocs(infosym)
-                               relocs = drelocs.ReadSyms(relocs)
                                for ri := 0; ri < drelocs.Count; ri++ {
-                                       r := &relocs[ri]
-                                       if r.Type == objabi.R_DWARFSECREF {
-                                               rsym := r.Sym
+                                       r := drelocs.At2(ri)
+                                       if r.Type() == objabi.R_DWARFSECREF {
+                                               rsym := r.Sym()
                                                rsn := d.ldr.SymName(rsym)
                                                if len(rsn) == 0 {
                                                        continue
@@ -2011,12 +2008,11 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
                        for _, list := range lists {
                                for _, s := range list {
                                        symIdx := loader.Sym(s)
-                                       srelocs := d.ldr.Relocs(symIdx)
-                                       relocs = srelocs.ReadSyms(relocs)
-                                       for i := 0; i < len(relocs); i++ {
-                                               r := &relocs[i]
-                                               if r.Type == objabi.R_USETYPE {
-                                                       d.defgotype(r.Sym)
+                                       relocs := d.ldr.Relocs(symIdx)
+                                       for i := 0; i < relocs.Count; i++ {
+                                               r := relocs.At2(i)
+                                               if r.Type() == objabi.R_USETYPE {
+                                                       d.defgotype(r.Sym())
                                                }
                                        }
                                }
@@ -2122,20 +2118,19 @@ func (d *dwctxt2) dwarfGenerateDebugSyms() {
 
 func (d *dwctxt2) collectlocs(syms []loader.Sym, units []*sym.CompilationUnit) []loader.Sym {
        empty := true
-       rslice := []loader.Reloc{}
        for _, u := range units {
                for _, fn := range u.FuncDIEs2 {
                        relocs := d.ldr.Relocs(loader.Sym(fn))
-                       rslice := relocs.ReadSyms(rslice)
-                       for i := range rslice {
-                               reloc := &rslice[i]
-                               if reloc.Type != objabi.R_DWARFSECREF {
+                       for i := 0; i < relocs.Count; i++ {
+                               reloc := relocs.At2(i)
+                               if reloc.Type() != objabi.R_DWARFSECREF {
                                        continue
                                }
-                               if d.ldr.SymType(reloc.Sym) == sym.SDWARFLOC {
-                                       d.ldr.SetAttrReachable(reloc.Sym, true)
-                                       d.ldr.SetAttrNotInSymbolTable(reloc.Sym, true)
-                                       syms = append(syms, reloc.Sym)
+                               rsym := reloc.Sym()
+                               if d.ldr.SymType(rsym) == sym.SDWARFLOC {
+                                       d.ldr.SetAttrReachable(rsym, true)
+                                       d.ldr.SetAttrNotInSymbolTable(rsym, true)
+                                       syms = append(syms, rsym)
                                        empty = false
                                        // One location list entry per function, but many relocations to it. Don't duplicate.
                                        break