Permalink
Browse files

cmd/link: fix accidentally-quadratic library loading

Programs built from N libraries required O(N²) time to do the
deduplication checks, even if there were never any duplicates.
In most programs N is small enough not to worry, but this may
affect large programs.

Noticed by inspection, not any specific bug report.

Fixes #20578.

Change-Id: Ic4108f1058be39da990a79b1e0b8ce95fde44cef
Reviewed-on: https://go-review.googlesource.com/44852
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information...
rsc committed May 31, 2017
1 parent 6a42568 commit 51711d1429cb592c9ddc772e6362e74ac8545dc8
Showing with 18 additions and 19 deletions.
  1. +7 −10 src/cmd/link/internal/ld/ld.go
  2. +9 −8 src/cmd/link/internal/ld/link.go
  3. +2 −1 src/cmd/link/internal/ld/sym.go
@@ -50,10 +50,8 @@ func addlib(ctxt *Link, src string, obj string, pathname string) *Library {
}
// already loaded?
for i := 0; i < len(ctxt.Library); i++ {
if ctxt.Library[i].Pkg == pkg {
return ctxt.Library[i]
}
if l := ctxt.LibraryByPkg[pkg]; l != nil {
return l
}
var pname string
@@ -97,18 +95,17 @@ func addlib(ctxt *Link, src string, obj string, pathname string) *Library {
* pkg: package import path, e.g. container/vector
*/
func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlibnamefile string) *Library {
for i := 0; i < len(ctxt.Library); i++ {
if pkg == ctxt.Library[i].Pkg {
return ctxt.Library[i]
}
if l := ctxt.LibraryByPkg[pkg]; l != nil {
return l
}
if ctxt.Debugvlog > 1 {
ctxt.Logf("%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s shlibnamefile: %s\n", Cputime(), srcref, objref, file, pkg, shlibnamefile)
}
ctxt.Library = append(ctxt.Library, &Library{})
l := ctxt.Library[len(ctxt.Library)-1]
l := &Library{}
ctxt.LibraryByPkg[pkg] = l
ctxt.Library = append(ctxt.Library, l)
l.Objref = objref
l.Srcref = srcref
l.File = file
@@ -220,14 +220,15 @@ type Link struct {
Loaded bool // set after all inputs have been loaded as symbols
Tlsg *Symbol
Libdir []string
Library []*Library
Shlibs []Shlib
Tlsoffset int
Textp []*Symbol
Filesyms []*Symbol
Moduledata *Symbol
Tlsg *Symbol
Libdir []string
Library []*Library
LibraryByPkg map[string]*Library
Shlibs []Shlib
Tlsoffset int
Textp []*Symbol
Filesyms []*Symbol
Moduledata *Symbol
tramps []*Symbol // trampolines
}
@@ -47,7 +47,8 @@ func linknew(arch *sys.Arch) *Link {
},
Allsym: make([]*Symbol, 0, 100000),
},
Arch: arch,
Arch: arch,
LibraryByPkg: make(map[string]*Library),
}
if objabi.GOARCH != arch.Name {

0 comments on commit 51711d1

Please sign in to comment.