]> Cypherpunks repositories - gostls13.git/commitdiff
debug/gosym: intern LineTable strings
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 12 Apr 2018 14:42:20 +0000 (07:42 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 13 Apr 2018 19:52:07 +0000 (19:52 +0000)
This cuts the allocated space while executing

go tool objdump -S `go tool -n compile`

by over 10%.

It also speeds it up slightly:

name              old time/op       new time/op       delta
ObjdumpSCompiler        9.03s ± 1%        8.88s ± 1%  -1.59%  (p=0.000 n=20+20)

Updates #24725

Change-Id: Ic6ef8e273ede589334ab6e07099ac2e5bdf990c9
Reviewed-on: https://go-review.googlesource.com/106798
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/debug/gosym/pclntab.go

index ba1cf8b699afa5911b9e02597eb3e884a46ac3d0..ad99b4dc5a6168d278efef6a92a6b33ea5d333c9 100644 (file)
@@ -9,6 +9,7 @@
 package gosym
 
 import (
+       "bytes"
        "encoding/binary"
        "sync"
 )
@@ -42,6 +43,7 @@ type LineTable struct {
        filetab  []byte
        nfiletab uint32
        fileMap  map[string]uint32
+       strings  map[uint32]string // interned substrings of Data, keyed by offset
 }
 
 // NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4,
@@ -120,7 +122,7 @@ func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
 // Text must be the start address of the
 // corresponding text segment.
 func NewLineTable(data []byte, text uint64) *LineTable {
-       return &LineTable{Data: data, PC: text, Line: 0}
+       return &LineTable{Data: data, PC: text, Line: 0, strings: make(map[uint32]string)}
 }
 
 // Go 1.2 symbol table format.
@@ -266,11 +268,13 @@ func (t *LineTable) readvarint(pp *[]byte) uint32 {
 
 // string returns a Go string found at off.
 func (t *LineTable) string(off uint32) string {
-       for i := off; ; i++ {
-               if t.Data[i] == 0 {
-                       return string(t.Data[off:i])
-               }
+       if s, ok := t.strings[off]; ok {
+               return s
        }
+       i := bytes.IndexByte(t.Data[off:], 0)
+       s := string(t.Data[off : off+uint32(i)])
+       t.strings[off] = s
+       return s
 }
 
 // step advances to the next pc, value pair in the encoded table.