]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: remove OutData
authorCherry Zhang <cherryyz@google.com>
Tue, 21 Jul 2020 18:32:09 +0000 (14:32 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 21 Jul 2020 21:23:44 +0000 (21:23 +0000)
OutData was used for a symbol to point to its data in the output
buffer, in order to apply relocations. Now we fold relocation
application to Asmb next to symbol data writing. We can just pass
the output data as a local variable.

Linking cmd/compile,

name         old time/op    new time/op    delta
Asmb_GC        19.0ms ±10%    16.6ms ± 9%  -12.50%  (p=0.032 n=5+5)

name         old alloc/op   new alloc/op   delta
Asmb_GC        3.78MB ± 0%    0.14MB ± 1%  -96.41%  (p=0.008 n=5+5)

name         old live-B     new live-B     delta
Asmb_GC         27.5M ± 0%     23.9M ± 0%  -13.24%  (p=0.008 n=5+5)

Change-Id: Id870a10dce2a0a7447a05029c6d0ab39b47d0a12
Reviewed-on: https://go-review.googlesource.com/c/go/+/244017
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/ld/asmb.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/outbuf.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/mips/asm.go
src/cmd/link/internal/mips64/asm.go

index f3e898bec533ad040050ce585fb7413726072293..9316f34c2a488859ebb9026c379b16a3a84817db 100644 (file)
@@ -18,7 +18,6 @@ import (
 //  - writing out the architecture specific pieces.
 // This function handles the first part.
 func asmb(ctxt *Link) {
-       ctxt.loader.InitOutData()
        if ctxt.IsExternal() && !ctxt.StreamExtRelocs() {
                ctxt.loader.InitExtRelocs()
        }
index 26bad1b891f9ed19603b9b5cb044995f77caa07a..0bf6f53a463a7a8038b492c64b677868aa252915 100644 (file)
@@ -1026,9 +1026,9 @@ func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym,
                        out.WriteStringPad("", int(val-addr), pad)
                        addr = val
                }
-               out.WriteSym(ldr, s)
-               st.relocsym(s, ldr.OutData(s))
-               addr += int64(len(ldr.Data(s)))
+               P := out.WriteSym(ldr, s)
+               st.relocsym(s, P)
+               addr += int64(len(P))
                siz := ldr.SymSize(s)
                if addr < val+siz {
                        out.WriteStringPad("", int(val+siz-addr), pad)
@@ -2677,8 +2677,8 @@ func compressSyms(ctxt *Link, syms []loader.Sym) []byte {
                if relocs.Count() != 0 {
                        relocbuf = append(relocbuf[:0], P...)
                        P = relocbuf
+                       st.relocsym(s, P)
                }
-               st.relocsym(s, P)
                if _, err := z.Write(P); err != nil {
                        log.Fatalf("compression failed: %s", err)
                }
index 51ea17243f2d3614c662f90b32c8445c54c19aad..a2c8552e940be21868bcaa8110aa6c0e93d4b951 100644 (file)
@@ -159,8 +159,8 @@ func (ctxt *Link) MaxVersion() int {
 // Generator symbols shouldn't grow the symbol size, and might be called in
 // parallel in the future.
 //
-// Generator Symbols have their Data and OutData set to the mmapped area when
-// the generator is called.
+// Generator Symbols have their Data set to the mmapped area when the
+// generator is called.
 type generatorFunc func(*Link, loader.Sym)
 
 // createGeneratorSymbol is a convenience method for creating a generator
index f0178288a6b01d2e99a1d476769ec1eedf21791a..d696a68088d46ee63c2eb1de7614fe8403ff3ee4 100644 (file)
@@ -277,23 +277,24 @@ func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
        }
 }
 
-// WriteSym writes the content of a Symbol, then changes the Symbol's content
-// to point to the output buffer that we just wrote, so we can apply further
-// edit to the symbol content.
-// If the output file is not Mmap'd, just writes the content.
-func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) {
+// WriteSym writes the content of a Symbol, and returns the output buffer
+// that we just wrote, so we can apply further edit to the symbol content.
+// For generator symbols, it also sets the symbol's Data to the output
+// buffer.
+func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) []byte {
        if !ldr.IsGeneratedSym(s) {
                P := ldr.Data(s)
                n := int64(len(P))
                pos, buf := out.writeLoc(n)
                copy(buf[pos:], P)
                out.off += n
-               ldr.SetOutData(s, buf[pos:pos+n])
+               ldr.FreeData(s)
+               return buf[pos : pos+n]
        } else {
                n := ldr.SymSize(s)
                pos, buf := out.writeLoc(n)
                out.off += n
-               ldr.SetOutData(s, buf[pos:pos+n])
                ldr.MakeSymbolUpdater(s).SetData(buf[pos : pos+n])
+               return buf[pos : pos+n]
        }
 }
index 86fdbeffd8d31a03761f299eff0e8998784815ea..0a09716447191ad3a46936e37d7d0243cc45e9ef 100644 (file)
@@ -238,7 +238,6 @@ type Loader struct {
 
        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
 
        itablink         map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
@@ -1230,30 +1229,16 @@ func (l *Loader) Data(i Sym) []byte {
        return r.Data(li)
 }
 
-// Returns the data of the i-th symbol in the output buffer.
-func (l *Loader) OutData(i Sym) []byte {
-       if int(i) < len(l.outdata) && l.outdata[i] != nil {
-               return l.outdata[i]
-       }
-       return l.Data(i)
-}
-
-// SetOutData sets the position of the data of the i-th symbol in the output buffer.
+// FreeData clears the symbol data of an external symbol, allowing the memory
+// to be freed earlier. No-op for non-external symbols.
 // i is global index.
-func (l *Loader) SetOutData(i Sym, data []byte) {
+func (l *Loader) FreeData(i Sym) {
        if l.IsExternal(i) {
                pp := l.getPayload(i)
                if pp != nil {
-                       pp.data = data
-                       return
+                       pp.data = nil
                }
        }
-       l.outdata[i] = data
-}
-
-// InitOutData initializes the slice used to store symbol output data.
-func (l *Loader) InitOutData() {
-       l.outdata = make([][]byte, l.extStart)
 }
 
 // SetExtRelocs sets the external relocations of the i-th symbol. i is global index.
index 5344a72a312662ff08ee3df73abb42e1961fdc53..b8443da4ad0daa79b6bd82be132ff7a798b68102 100644 (file)
@@ -77,7 +77,7 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
 }
 
 func applyrel(arch *sys.Arch, ldr *loader.Loader, rt objabi.RelocType, off int32, s loader.Sym, val int64, t int64) int64 {
-       o := arch.ByteOrder.Uint32(ldr.OutData(s)[off:])
+       o := uint32(val)
        switch rt {
        case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
                return int64(o&0xffff0000 | uint32(t)&0xffff)
index 73b1542c84d51dc8abf36db3d66b27ad2d01db57..f4fb13f2b53eaf27b4fa99218697678d4927757f 100644 (file)
@@ -129,25 +129,22 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
        case objabi.R_ADDRMIPS,
                objabi.R_ADDRMIPSU:
                t := ldr.SymValue(rs) + r.Add()
-               o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
                if r.Type() == objabi.R_ADDRMIPS {
-                       return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
+                       return int64(val&0xffff0000 | t&0xffff), noExtReloc, isOk
                }
-               return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), noExtReloc, isOk
+               return int64(val&0xffff0000 | ((t+1<<15)>>16)&0xffff), noExtReloc, isOk
        case objabi.R_ADDRMIPSTLS:
                // thread pointer is at 0x7000 offset from the start of TLS data area
                t := ldr.SymValue(rs) + r.Add() - 0x7000
                if t < -32768 || t >= 32678 {
                        ldr.Errorf(s, "TLS offset out of range %d", t)
                }
-               o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
-               return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
+               return int64(val&0xffff0000 | t&0xffff), noExtReloc, isOk
        case objabi.R_CALLMIPS,
                objabi.R_JMPMIPS:
                // Low 26 bits = (S + A) >> 2
                t := ldr.SymValue(rs) + r.Add()
-               o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
-               return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), noExtReloc, isOk
+               return int64(val&0xfc000000 | (t>>2)&^0xfc000000), noExtReloc, isOk
        }
 
        return val, 0, false