From 9ae8f71c9431d287893443fa2b7fbdb72a9b56a2 Mon Sep 17 00:00:00 2001 From: Jeremy Faller Date: Mon, 3 Aug 2020 13:19:46 -0400 Subject: [dev.link] cmd/link: stop renumbering files for pclntab generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creates two new symbols: runtime.cutab, and runtime.filetab, and strips the filenames out of runtime.pclntab_old. All stats are for cmd/compile. Time: Pclntab_GC 48.2ms ± 3% 45.5ms ± 9% -5.47% (p=0.004 n=9+9) Alloc/op: Pclntab_GC 30.0MB ± 0% 29.5MB ± 0% -1.88% (p=0.000 n=10+10) Allocs/op: Pclntab_GC 90.4k ± 0% 73.1k ± 0% -19.11% (p=0.000 n=10+10) live-B: Pclntab_GC 29.1M ± 0% 29.2M ± 0% +0.10% (p=0.000 n=10+10) binary sizes: NEW: 18565600 OLD: 18532768 The size differences in the binary are caused by the increased size of the Func objects, and (less likely) some extra alignment padding needed as a result. This is probably the maximum increase in size we'll size from the pclntab reworking. Change-Id: Idd95a9b159fea46f7701cfe6506813b88257fbea Reviewed-on: https://go-review.googlesource.com/c/go/+/246497 Run-TryBot: Jeremy Faller TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh Reviewed-by: Austin Clements --- src/debug/gosym/pclntab.go | 52 +++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'src/debug') diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go index e5c50520fc..e383ea460a 100644 --- a/src/debug/gosym/pclntab.go +++ b/src/debug/gosym/pclntab.go @@ -53,6 +53,7 @@ type LineTable struct { quantum uint32 ptrsize uint32 funcnametab []byte + cutab []byte funcdata []byte functab []byte nfunctab uint32 @@ -223,17 +224,18 @@ func (t *LineTable) parsePclnTab() { switch possibleVersion { case ver116: t.nfunctab = uint32(t.uintptr(t.Data[8:])) - offset := t.uintptr(t.Data[8+t.ptrsize:]) + t.nfiletab = uint32(t.uintptr(t.Data[8+t.ptrsize:])) + offset := t.uintptr(t.Data[8+2*t.ptrsize:]) t.funcnametab = t.Data[offset:] - offset = t.uintptr(t.Data[8+2*t.ptrsize:]) + offset = t.uintptr(t.Data[8+3*t.ptrsize:]) + t.cutab = t.Data[offset:] + offset = t.uintptr(t.Data[8+4*t.ptrsize:]) + t.filetab = t.Data[offset:] + offset = t.uintptr(t.Data[8+5*t.ptrsize:]) t.funcdata = t.Data[offset:] t.functab = t.Data[offset:] functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize - fileoff := t.binary.Uint32(t.functab[functabsize:]) - t.filetab = t.functab[fileoff:] t.functab = t.functab[:functabsize] - t.nfiletab = t.binary.Uint32(t.filetab) - t.filetab = t.filetab[:t.nfiletab*4] case ver12: t.nfunctab = uint32(t.uintptr(t.Data[8:])) t.funcdata = t.Data @@ -330,17 +332,22 @@ func (t *LineTable) funcName(off uint32) string { return s } -// string returns a Go string found at off. -func (t *LineTable) string(off uint32) string { +// stringFrom returns a Go string found at off from a position. +func (t *LineTable) stringFrom(arr []byte, off uint32) string { if s, ok := t.strings[off]; ok { return s } - i := bytes.IndexByte(t.funcdata[off:], 0) - s := string(t.funcdata[off : off+uint32(i)]) + i := bytes.IndexByte(arr[off:], 0) + s := string(arr[off : off+uint32(i)]) t.strings[off] = s return s } +// string returns a Go string found at off. +func (t *LineTable) string(off uint32) string { + return t.stringFrom(t.funcdata, off) +} + // step advances to the next pc, value pair in the encoded table. func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool { uvdelta := t.readvarint(p) @@ -453,7 +460,15 @@ func (t *LineTable) go12PCToFile(pc uint64) (file string) { if fno <= 0 { return "" } - return t.string(t.binary.Uint32(t.filetab[4*fno:])) + if t.version == ver12 { + return t.string(t.binary.Uint32(t.filetab[4*fno:])) + } + // Go ≥ 1.16 + cuoff := t.binary.Uint32(f[t.ptrsize+7*4:]) + if fnoff := t.binary.Uint32(t.cutab[(cuoff+uint32(fno))*4:]); fnoff != ^uint32(0) { + return t.stringFrom(t.filetab, fnoff) + } + return "" } // go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table. @@ -496,9 +511,18 @@ func (t *LineTable) initFileMap() { } m := make(map[string]uint32) - for i := uint32(1); i < t.nfiletab; i++ { - s := t.string(t.binary.Uint32(t.filetab[4*i:])) - m[s] = i + if t.version == ver12 { + for i := uint32(1); i < t.nfiletab; i++ { + s := t.string(t.binary.Uint32(t.filetab[4*i:])) + m[s] = i + } + } else { + var pos uint32 + for i := uint32(1); i < t.nfiletab; i++ { + s := t.stringFrom(t.filetab, pos) + pos += uint32(len(s) + 1) + m[s] = i + } } t.fileMap = m } -- cgit v1.3-5-g9baa