]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: memoize/cache whether plugin.Open symbol available
authorThan McIntosh <thanm@google.com>
Wed, 4 Sep 2019 15:25:06 +0000 (11:25 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 6 Sep 2019 12:16:32 +0000 (12:16 +0000)
Perform a single lookup of "plugin.Open" at the point where we set the
loaded flag for the context, then cache whether the result is nil, so
that we can consult this cached value later on (instead of having to
look up the symbol each time). This helps speed up the DynLinkingGo()
context method, which is called from within some very hot loops in the
linker (when linking 'hyperkube' from kubernetes, reduces total calls
to "sym.(*Symbols).ROLookup" from 6.5M to 4.3M)

Change-Id: I92a2ea2b21d24f67aec0a7afeef4acc77c095adf
Reviewed-on: https://go-review.googlesource.com/c/go/+/193260
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go

index 92dc9ba061173b28dcbaa272885acf0a1041f2bf..1deab660b71c511ff239a1d173bb1818b23c86d4 100644 (file)
@@ -173,12 +173,15 @@ func (ctxt *Link) DynlinkingGo() bool {
        if !ctxt.Loaded {
                panic("DynlinkingGo called before all symbols loaded")
        }
-       return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins()
+       return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins
 }
 
 // CanUsePlugins reports whether a plugins can be used
 func (ctxt *Link) CanUsePlugins() bool {
-       return ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil
+       if !ctxt.Loaded {
+               panic("CanUsePlugins called before all symbols loaded")
+       }
+       return ctxt.canUsePlugins
 }
 
 // UseRelro reports whether to make use of "read only relocations" aka
@@ -595,6 +598,9 @@ func (ctxt *Link) loadlib() {
        // We've loaded all the code now.
        ctxt.Loaded = true
 
+       // Record whether we can use plugins.
+       ctxt.canUsePlugins = (ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil)
+
        // If there are no dynamic libraries needed, gcc disables dynamic linking.
        // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
        // assumes that a dynamic binary always refers to at least one dynamic library.
index d3ffacf54e370fa9149e07b9589e4c8ea86614be..dc39f084bf64c13ecaa283e518c7a2f5105f8c9b 100644 (file)
@@ -67,6 +67,7 @@ type Link struct {
        linkShared    bool // link against installed Go shared libraries
        LinkMode      LinkMode
        BuildMode     BuildMode
+       canUsePlugins bool // initialized when Loaded is set to true
        compressDWARF bool
 
        Tlsg         *sym.Symbol