mirror of
https://github.com/golang/go
synced 2024-11-24 20:00:10 -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")
|
log.Fatalf("readsym out of sync")
|
||||||
}
|
}
|
||||||
t := rdint(f)
|
t := rdint(f)
|
||||||
name := expandpkg(rdstring(f), pkg)
|
name := rdsymName(f, pkg)
|
||||||
v := rdint(f)
|
v := rdint(f)
|
||||||
if v != 0 && v != 1 {
|
if v != 0 && v != 1 {
|
||||||
log.Fatalf("invalid symbol version %d", v)
|
log.Fatalf("invalid symbol version %d", v)
|
||||||
@ -424,11 +424,17 @@ func rduint8(f *obj.Biobuf) uint8 {
|
|||||||
return uint8(n)
|
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 {
|
func rdstring(f *obj.Biobuf) string {
|
||||||
n := rdint64(f)
|
n := rdint(f)
|
||||||
p := make([]byte, n)
|
if len(rdBuf) < n {
|
||||||
obj.Bread(f, p)
|
rdBuf = make([]byte, n)
|
||||||
return string(p)
|
}
|
||||||
|
obj.Bread(f, rdBuf[:n])
|
||||||
|
return string(rdBuf[:n])
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -452,25 +458,48 @@ func rddata(f *obj.Biobuf) []byte {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
var symbuf []byte
|
// rdsymName reads a symbol name, replacing all "". with pkg.
|
||||||
|
func rdsymName(f *obj.Biobuf, pkg string) string {
|
||||||
func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
|
|
||||||
n := rdint(f)
|
n := rdint(f)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
rdint64(f)
|
rdint64(f)
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(symbuf) < n {
|
if len(rdBuf) < n {
|
||||||
symbuf = make([]byte, 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)
|
v := rdint(f)
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
v = ctxt.Version
|
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 v == 0 && s.Name[0] == '$' && s.Type == 0 {
|
||||||
if strings.HasPrefix(s.Name, "$f32.") {
|
if strings.HasPrefix(s.Name, "$f32.") {
|
||||||
|
Loading…
Reference in New Issue
Block a user