aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisharipo <iskander.sharipov@intel.com>2018-05-17 19:47:52 +0300
committerBrad Fitzpatrick <bradfitz@golang.org>2018-08-21 02:29:51 +0000
commitbc276c585b24a5e3adb9c6cdfebc4d69d910cc2e (patch)
tree80175ad20fee54bf58112df41ecdad0979d7ad5b /src
parent97c7e0e0ad1be5c4d211e0182ff970a2086e7679 (diff)
downloadgo-bc276c585b24a5e3adb9c6cdfebc4d69d910cc2e.tar.xz
cmd/link/internal/ld: avoid Reloc copies in range loops
Copying sym.Reloc in loops hurts performance as it has 48 byte size (on 64-bit platforms). There are quite many symbols and each of them has more than 1 relocation (so, it's possible to have more than 1kk relocs). The're also traversed more than once in some code paths. By using pointers to them, copies are avoided. For linking "hello world" example from net/http: name old time/op new time/op delta Linker-4 530ms ± 2% 521ms ± 3% -1.80% (p=0.000 n=17+20) Change-Id: I6518aec69d6adcd137f84b5c089ceab4cb4ea2dd Reviewed-on: https://go-review.googlesource.com/113636 Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/link/internal/ld/ar.go3
-rw-r--r--src/cmd/link/internal/ld/data.go3
-rw-r--r--src/cmd/link/internal/ld/deadcode.go4
-rw-r--r--src/cmd/link/internal/ld/dwarf.go9
-rw-r--r--src/cmd/link/internal/ld/lib.go3
5 files changed, 14 insertions, 8 deletions
diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go
index ae7554c929..779f3565f9 100644
--- a/src/cmd/link/internal/ld/ar.go
+++ b/src/cmd/link/internal/ld/ar.go
@@ -105,7 +105,8 @@ func hostArchive(ctxt *Link, name string) {
for any {
var load []uint64
for _, s := range ctxt.Syms.Allsym {
- for _, r := range s.R {
+ for i := range s.R {
+ r := &s.R[i] // Copying sym.Reloc has measurable impact on peformance
if r.Sym != nil && r.Sym.Type == sym.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
load = append(load, off)
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index d71b8b6ac7..5dd4aac03e 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -772,7 +772,8 @@ func Datblk(ctxt *Link, addr int64, size int64) {
if ctxt.LinkMode != LinkExternal {
continue
}
- for _, r := range sym.R {
+ for i := range sym.R {
+ r := &sym.R[i] // Copying sym.Reloc has measurable impact on peformance
rsname := ""
if r.Sym != nil {
rsname = r.Sym.Name
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index 540f4068cb..df989cc944 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -245,8 +245,8 @@ func (d *deadcodepass) init() {
// but we do keep the symbols it refers to.
exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
if exports != nil {
- for _, r := range exports.R {
- d.mark(r.Sym, nil)
+ for i := range exports.R {
+ d.mark(exports.R[i].Sym, nil)
}
}
}
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index ae6f90b079..c803180cad 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -1061,7 +1061,8 @@ func getCompilationDir() string {
func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
dsym.Type = sym.SDWARFINFO
- for _, r := range dsym.R {
+ for i := range dsym.R {
+ r := &dsym.R[i] // Copying sym.Reloc has measurable impact on peformance
if r.Type == objabi.R_DWARFSECREF && r.Sym.Size == 0 {
if ctxt.BuildMode == BuildModeShared {
// These type symbols may not be present in BuildModeShared. Skip.
@@ -1090,7 +1091,8 @@ func collectAbstractFunctions(ctxt *Link, fn *sym.Symbol, dsym *sym.Symbol, absf
// Walk the relocations on the primary subprogram DIE and look for
// references to abstract funcs.
- for _, reloc := range dsym.R {
+ for i := range dsym.R {
+ reloc := &dsym.R[i] // Copying sym.Reloc has measurable impact on peformance
candsym := reloc.Sym
if reloc.Type != objabi.R_DWARFSECREF {
continue
@@ -1801,7 +1803,8 @@ func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit) []*sy
empty := true
for _, u := range units {
for _, fn := range u.funcDIEs {
- for _, reloc := range fn.R {
+ for i := range fn.R {
+ reloc := &fn.R[i] // Copying sym.Reloc has measurable impact on peformance
if reloc.Type == objabi.R_DWARFSECREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
syms = append(syms, reloc.Sym)
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 9f89457753..d86b2aa544 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -503,7 +503,8 @@ func (ctxt *Link) loadlib() {
// objects, try to read them from the libgcc file.
any := false
for _, s := range ctxt.Syms.Allsym {
- for _, r := range s.R {
+ for i := range s.R {
+ r := &s.R[i] // Copying sym.Reloc has measurable impact on peformance
if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
any = true
break