mirror of
https://github.com/golang/go
synced 2024-11-23 00:40:08 -07:00
cmd/link: remove allocation in decoding type name
The type name symbol is always from a Go object file and we never change it. Convert the data to string using unsafe conversion without allocation. Linking cmd/go (on macOS/amd64), name old alloc/op new alloc/op delta Deadcode_GC 1.25MB ± 0% 1.17MB ± 0% -6.29% (p=0.000 n=20+20) name old allocs/op new allocs/op delta Deadcode_GC 8.98k ± 0% 0.10k ± 3% -98.91% (p=0.000 n=20+20) Change-Id: I33117ad1f991e4f14ce0b38cceec50b041e3c0a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/490915 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
fa4781a415
commit
630ef2edc2
@ -853,6 +853,15 @@ func (r *Reader) Data(i uint32) []byte {
|
|||||||
return r.BytesAt(base+off, int(end-off))
|
return r.BytesAt(base+off, int(end-off))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataString returns the i-th symbol's data as a string.
|
||||||
|
func (r *Reader) DataString(i uint32) string {
|
||||||
|
dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
|
||||||
|
base := r.h.Offsets[BlkData]
|
||||||
|
off := r.uint32At(dataIdxOff)
|
||||||
|
end := r.uint32At(dataIdxOff + 4)
|
||||||
|
return r.StringAt(base+off, end-off)
|
||||||
|
}
|
||||||
|
|
||||||
// NRefName returns the number of referenced symbol names.
|
// NRefName returns the number of referenced symbol names.
|
||||||
func (r *Reader) NRefName() int {
|
func (r *Reader) NRefName() int {
|
||||||
return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize
|
return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize
|
||||||
|
@ -487,7 +487,7 @@ func (d *deadcodePass) decodeIfaceMethod(ldr *loader.Loader, arch *sys.Arch, sym
|
|||||||
|
|
||||||
// Decode the method name stored in symbol symIdx. The symbol should contain just the bytes of a method name.
|
// Decode the method name stored in symbol symIdx. The symbol should contain just the bytes of a method name.
|
||||||
func (d *deadcodePass) decodeGenericIfaceMethod(ldr *loader.Loader, symIdx loader.Sym) string {
|
func (d *deadcodePass) decodeGenericIfaceMethod(ldr *loader.Loader, symIdx loader.Sym) string {
|
||||||
return string(ldr.Data(symIdx))
|
return ldr.DataString(symIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deadcodePass) decodetypeMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
func (d *deadcodePass) decodetypeMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
||||||
|
@ -127,9 +127,13 @@ func decodetypeName(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
data := ldr.Data(r)
|
data := ldr.DataString(r)
|
||||||
nameLen, nameLenLen := binary.Uvarint(data[1:])
|
n := 1 + binary.MaxVarintLen64
|
||||||
return string(data[1+nameLenLen : 1+nameLenLen+int(nameLen)])
|
if len(data) < n {
|
||||||
|
n = len(data)
|
||||||
|
}
|
||||||
|
nameLen, nameLenLen := binary.Uvarint([]byte(data[1:n]))
|
||||||
|
return data[1+nameLenLen : 1+nameLenLen+int(nameLen)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodetypeNameEmbedded(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) bool {
|
func decodetypeNameEmbedded(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) bool {
|
||||||
|
@ -1247,6 +1247,16 @@ func (l *Loader) Data(i Sym) []byte {
|
|||||||
return r.Data(li)
|
return r.Data(li)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the symbol content of the i-th symbol as a string. i is global index.
|
||||||
|
func (l *Loader) DataString(i Sym) string {
|
||||||
|
if l.IsExternal(i) {
|
||||||
|
pp := l.getPayload(i)
|
||||||
|
return string(pp.data)
|
||||||
|
}
|
||||||
|
r, li := l.toLocal(i)
|
||||||
|
return r.DataString(li)
|
||||||
|
}
|
||||||
|
|
||||||
// FreeData clears the symbol data of an external symbol, allowing the memory
|
// FreeData clears the symbol data of an external symbol, allowing the memory
|
||||||
// to be freed earlier. No-op for non-external symbols.
|
// to be freed earlier. No-op for non-external symbols.
|
||||||
// i is global index.
|
// i is global index.
|
||||||
|
Loading…
Reference in New Issue
Block a user