[dev.link] cmd/link: add internal packages at the end

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>
This commit is contained in:
Cherry Zhang 2019-10-30 21:24:22 -04:00
parent 5597e3d389
commit 24ea07d592

View 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)
}
}