mirror of
https://github.com/golang/go
synced 2024-11-24 15:40:09 -07:00
cmd/link: skip allocation when reading symbol name
The object file reader in cmd/link reads the symbol name into a scratch []byte, converts it to a string, and then does a substring replacement. Instead, this CL does the replacement on the []byte into the scratch space and then creates the final string. Linking godoc without DWARF, best of ten, shows a ~10% improvement. tip: real 0m1.099s user 0m1.541s this: real 0m0.990s user 0m1.280s This is part of an attempt to make suffixarray string deduping come out as a wash, but it's not there yet: cl/19987: real 0m1.335s user 0m1.794s cl/19987+this: real 0m1.225s user 0m1.540s Change-Id: Idf061fdfbd7f08aa3a1f5933d3f111fdd1659210 Reviewed-on: https://go-review.googlesource.com/20025 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: David Crawshaw <crawshaw@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
6d0b551931
commit
07ccc21295
@ -165,7 +165,7 @@ func readsym(ctxt *Link, f *obj.Biobuf, pkg string, pn string) {
|
||||
log.Fatalf("readsym out of sync")
|
||||
}
|
||||
t := rdint(f)
|
||||
name := expandpkg(rdstring(f), pkg)
|
||||
name := rdsymName(f, pkg)
|
||||
v := rdint(f)
|
||||
if v != 0 && v != 1 {
|
||||
log.Fatalf("invalid symbol version %d", v)
|
||||
@ -424,11 +424,17 @@ func rduint8(f *obj.Biobuf) uint8 {
|
||||
return uint8(n)
|
||||
}
|
||||
|
||||
// rdBuf is used by rdstring and rdsymName as scratch for reading strings.
|
||||
var rdBuf []byte
|
||||
var emptyPkg = []byte(`"".`)
|
||||
|
||||
func rdstring(f *obj.Biobuf) string {
|
||||
n := rdint64(f)
|
||||
p := make([]byte, n)
|
||||
obj.Bread(f, p)
|
||||
return string(p)
|
||||
n := rdint(f)
|
||||
if len(rdBuf) < n {
|
||||
rdBuf = make([]byte, n)
|
||||
}
|
||||
obj.Bread(f, rdBuf[:n])
|
||||
return string(rdBuf[:n])
|
||||
}
|
||||
|
||||
var (
|
||||
@ -452,25 +458,48 @@ func rddata(f *obj.Biobuf) []byte {
|
||||
return p
|
||||
}
|
||||
|
||||
var symbuf []byte
|
||||
|
||||
func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
|
||||
// rdsymName reads a symbol name, replacing all "". with pkg.
|
||||
func rdsymName(f *obj.Biobuf, pkg string) string {
|
||||
n := rdint(f)
|
||||
if n == 0 {
|
||||
rdint64(f)
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
if len(symbuf) < n {
|
||||
symbuf = make([]byte, n)
|
||||
if len(rdBuf) < n {
|
||||
rdBuf = make([]byte, n, 2*n)
|
||||
}
|
||||
origName := rdBuf[:n]
|
||||
obj.Bread(f, origName)
|
||||
adjName := rdBuf[n:n]
|
||||
for {
|
||||
i := bytes.Index(origName, emptyPkg)
|
||||
if i == -1 {
|
||||
adjName = append(adjName, origName...)
|
||||
break
|
||||
}
|
||||
adjName = append(adjName, origName[:i]...)
|
||||
adjName = append(adjName, pkg...)
|
||||
adjName = append(adjName, '.')
|
||||
origName = origName[i+len(emptyPkg):]
|
||||
}
|
||||
name := string(adjName)
|
||||
if len(adjName) > len(rdBuf) {
|
||||
rdBuf = adjName // save the larger buffer for reuse
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
|
||||
name := rdsymName(f, pkg)
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
obj.Bread(f, symbuf[:n])
|
||||
p := string(symbuf[:n])
|
||||
v := rdint(f)
|
||||
if v != 0 {
|
||||
v = ctxt.Version
|
||||
}
|
||||
s := Linklookup(ctxt, expandpkg(p, pkg), v)
|
||||
s := Linklookup(ctxt, name, v)
|
||||
|
||||
if v == 0 && s.Name[0] == '$' && s.Type == 0 {
|
||||
if strings.HasPrefix(s.Name, "$f32.") {
|
||||
|
Loading…
Reference in New Issue
Block a user