1
0
mirror of https://github.com/golang/go synced 2024-11-18 12:04:57 -07:00

[dev.link] cmd/link: unescape relocs passed to Archreloc2

Archreloc2 is a function pointer. It will escape its pointer
arguments. In relocsym, as we pass &r and &rr to Archreloc2, it
causes them to escape, even if Archreloc2 is not actually called.

Instead, pass r by value. loader.Reloc2 is a small structure
which is intended to be passed by value.

For rr, as Archreloc2 will likely return true, we speculatively
add it to extRelocs slice and use that space to pass to
Archreloc2.

Linking cmd/compile,

name              old alloc/op   new alloc/op   delta
Dwarfcompress_GC     110MB ± 0%      24MB ± 0%   -78.34%  (p=0.008 n=5+5)
Reloc_GC            24.6MB ± 0%     0.0MB ± 0%  -100.00%  (p=0.029 n=4+4)

Linking cmd/compile using external linking

name              old alloc/op   new alloc/op   delta
Reloc_GC             152MB ± 0%      36MB ± 0%   -76.07%  (p=0.008 n=5+5)

Change-Id: I1415479e0c17ea9787f9a62453dce00ad9ea792f
Reviewed-on: https://go-review.googlesource.com/c/go/+/231077
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Cherry Zhang 2020-04-29 23:53:33 -04:00
parent d23cd597aa
commit 5aa59c6a99
3 changed files with 17 additions and 5 deletions

View File

@ -253,9 +253,21 @@ func relocsym(target *Target, ldr *loader.Loader, err *ErrorReporter, syms *Arch
case 8:
o = int64(target.Arch.ByteOrder.Uint64(P[off:]))
}
var out int64
var ok bool
out, needExtReloc, ok = thearch.Archreloc2(target, ldr, syms, &r, &rr, s, o)
var rp *loader.ExtReloc
if target.IsExternal() {
// Don't pass &rr directly to Archreloc2, which will escape rr
// even if this case is not taken. Instead, as Archreloc2 will
// likely return true, we speculatively add rr to extRelocs
// and use that space to pass to Archreloc2.
extRelocs = append(extRelocs, rr)
rp = &extRelocs[len(extRelocs)-1]
}
out, needExtReloc1, ok := thearch.Archreloc2(target, ldr, syms, r, rp, s, o)
if target.IsExternal() && !needExtReloc1 {
// Speculation failed. Undo the append.
extRelocs = extRelocs[:len(extRelocs)-1]
}
needExtReloc = false // already appended
if ok {
o = out
} else {

View File

@ -246,7 +246,7 @@ type Arch struct {
// indicates a fatal error).
Archreloc func(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
offset int64) (relocatedOffset int64, success bool)
Archreloc2 func(*Target, *loader.Loader, *ArchSyms, *loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool)
Archreloc2 func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool)
// Archrelocvariant is a second arch-specific hook used for
// relocation processing; it handles relocations where r.Type is
// insufficient to describe the relocation (r.Variant !=

View File

@ -435,7 +435,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
return true
}
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r *loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
return val, false, false
}