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:
parent
d23cd597aa
commit
5aa59c6a99
@ -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 {
|
||||
|
@ -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 !=
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user