]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: add internal packages at the end
authorCherry Zhang <cherryyz@google.com>
Thu, 31 Oct 2019 01:24:22 +0000 (21:24 -0400)
committerCherry Zhang <cherryyz@google.com>
Sat, 2 Nov 2019 19:21:37 +0000 (19:21 +0000)
Currently in the linker we load internal packges first, then the
main package, and then load imported packages following the
dependency graph. As a result, packages are loaded mostly in the
dependency order, except the internal packages. The global symbol
indices are assigned the same way.

By loading the internal packages at the end, the packages are
loaded in the dependency order, so are the global indices. This
way, a relocation edge is mostly either within a packge or a
forward edge from a smaller index to a larger one. This allows
us to use a min-heap work queue in the deadcode pass, to achieve
better spatial locality (in the next CL).

Change-Id: I01fa9b3cf0c9e9e66006040f6378a51fd78f0f39
Reviewed-on: https://go-review.googlesource.com/c/go/+/204437
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/ld/lib.go

index 9f939e5c824198744eb9bcac06e7ee7b829dab77..4c7451a11448720d285bb796c8278b06e6a482a2 100644 (file)
@@ -384,7 +384,19 @@ func (ctxt *Link) loadlib() {
        ctxt.cgo_export_static = make(map[string]bool)
        ctxt.cgo_export_dynamic = make(map[string]bool)
 
-       loadinternal(ctxt, "runtime")
+       // ctxt.Library grows during the loop, so not a range loop.
+       i := 0
+       for ; i < len(ctxt.Library); i++ {
+               lib := ctxt.Library[i]
+               if lib.Shlib == "" {
+                       if ctxt.Debugvlog > 1 {
+                               ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
+                       }
+                       loadobjfile(ctxt, lib)
+               }
+       }
+
+       // load internal packages, if not already
        if ctxt.Arch.Family == sys.ARM {
                loadinternal(ctxt, "math")
        }
@@ -394,14 +406,10 @@ func (ctxt *Link) loadlib() {
        if *flagMsan {
                loadinternal(ctxt, "runtime/msan")
        }
-
-       // ctxt.Library grows during the loop, so not a range loop.
-       for i := 0; i < len(ctxt.Library); i++ {
+       loadinternal(ctxt, "runtime")
+       for ; i < len(ctxt.Library); i++ {
                lib := ctxt.Library[i]
                if lib.Shlib == "" {
-                       if ctxt.Debugvlog > 1 {
-                               ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
-                       }
                        loadobjfile(ctxt, lib)
                }
        }