]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix accidentally-quadratic library loading
authorRuss Cox <rsc@golang.org>
Wed, 31 May 2017 15:33:04 +0000 (11:33 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 5 Jun 2017 19:56:34 +0000 (19:56 +0000)
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>
src/cmd/link/internal/ld/ld.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/sym.go

index 52f82c3b87c0fed893bbf8b3e79440ae5f35b990..c6cad49f26bc14c2c9f30ac1101c1f2b6e64c8cb 100644 (file)
@@ -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
index 8d9e4a7cf3a019d1db0d3f3a9cf95e7bf9cef68e..45ce20a7000d5f6a9f702638af913c0208e34734 100644 (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
 }
index f1bbdeb58b4cb92e722111c534221a3c84c5dddd..6e239d79a53b534a48ba716816a267a5edbbb40e 100644 (file)
@@ -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 {