]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link/internal/loader: change storage mechanism for sym alignment
authorThan McIntosh <thanm@google.com>
Thu, 30 Apr 2020 20:01:03 +0000 (16:01 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 1 May 2020 01:50:58 +0000 (01:50 +0000)
Switch the storage mechanism for symbol alignment away from a map and
to a slice of uint8 values per symbol, where value K indicates
alignment 2^K. Intended to help speed up alignment get/set in dodata.

Change-Id: I26416e455c808f697dd0d7f6d2582247ee5c5b40
Reviewed-on: https://go-review.googlesource.com/c/go/+/231220
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/loader/loader.go

index 749995bf8e89c39b372aeb2281681c88e30baa7c..60c38cc1d459cf293f8281a58ebc0724d1e3747a 100644 (file)
@@ -223,6 +223,8 @@ type Loader struct {
        sects    []*sym.Section // sections
        symSects []uint16       // symbol's section, index to sects array
 
+       align []uint8 // symbol 2^N alignment, indexed by global index
+
        outdata   [][]byte     // symbol's data in the output buffer
        extRelocs [][]ExtReloc // symbol's external relocations
 
@@ -263,8 +265,6 @@ type Loader struct {
        outer map[Sym]Sym
        sub   map[Sym]Sym
 
-       align map[Sym]int32 // stores alignment for symbols
-
        dynimplib   map[Sym]string      // stores Dynimplib symbol attribute
        dynimpvers  map[Sym]string      // stores Dynimpvers symbol attribute
        localentry  map[Sym]uint8       // stores Localentry symbol attribute
@@ -336,7 +336,6 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor
                objByPkg:             make(map[string]*oReader),
                outer:                make(map[Sym]Sym),
                sub:                  make(map[Sym]Sym),
-               align:                make(map[Sym]int32),
                dynimplib:            make(map[Sym]string),
                dynimpvers:           make(map[Sym]string),
                localentry:           make(map[Sym]uint8),
@@ -1128,36 +1127,35 @@ func (l *Loader) InitExtRelocs() {
 
 // SymAlign returns the alignment for a symbol.
 func (l *Loader) SymAlign(i Sym) int32 {
-       // If an alignment has been recorded, return that.
-       if align, ok := l.align[i]; ok {
-               return align
+       if int(i) >= len(l.align) {
+               // align is extended lazily -- it the sym in question is
+               // outside the range of the existing slice, then we assume its
+               // alignment has not yet been set.
+               return 0
        }
        // TODO: would it make sense to return an arch-specific
        // alignment depending on section type? E.g. STEXT => 32,
        // SDATA => 1, etc?
-       return 0
+       abits := l.align[i]
+       if abits == 0 {
+               return 0
+       }
+       return int32(1 << (abits - 1))
 }
 
 // SetSymAlign sets the alignment for a symbol.
 func (l *Loader) SetSymAlign(i Sym, align int32) {
-       // reject bad synbols
-       if i >= Sym(len(l.objSyms)) || i == 0 {
-               panic("bad symbol index in SetSymAlign")
-       }
        // Reject nonsense alignments.
-       // TODO: do we need this?
-       if align < 0 {
+       if align < 0 || align&(align-1) != 0 {
                panic("bad alignment value")
        }
+       if int(i) >= len(l.align) {
+               l.align = append(l.align, make([]uint8, l.NSym()-len(l.align))...)
+       }
        if align == 0 {
-               delete(l.align, i)
-       } else {
-               // Alignment should be a power of 2.
-               if bits.OnesCount32(uint32(align)) != 1 {
-                       panic("bad alignment value")
-               }
-               l.align[i] = align
+               l.align[i] = 0
        }
+       l.align[i] = uint8(bits.Len32(uint32(align)))
 }
 
 // SymValue returns the section of the i-th symbol. i is global index.