cmd/internal/objfile: cache computation of goobj.Arch
Change-Id: I23774cf185e5fa6b89398001cd0655fb0c5bdb46
GitHub-Last-Rev: ca8cae2469b5fad84bd636a3305a484dfdcb0db2
GitHub-Pull-Request: golang/go#40877
Reviewed-on: https://go-review.googlesource.com/c/go/+/249180
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/internal/archive/archive.go b/src/cmd/internal/archive/archive.go
index db67ce4..c1661d7 100644
--- a/src/cmd/internal/archive/archive.go
+++ b/src/cmd/internal/archive/archive.go
@@ -17,6 +17,7 @@
"log"
"os"
"strconv"
+ "strings"
"time"
"unicode/utf8"
)
@@ -83,6 +84,7 @@
type GoObj struct {
TextHeader []byte
+ Arch string
Data
}
@@ -404,6 +406,10 @@
}
}
o.TextHeader = h
+ hs := strings.Fields(string(h))
+ if len(hs) >= 4 {
+ o.Arch = hs[3]
+ }
o.Offset = r.offset
o.Size = size - int64(len(h))
diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go
index e838f58..af9ada3 100644
--- a/src/cmd/internal/objfile/goobj.go
+++ b/src/cmd/internal/objfile/goobj.go
@@ -17,13 +17,13 @@
"fmt"
"io"
"os"
- "strings"
)
type goobjFile struct {
goobj *archive.GoObj
r *goobj.Reader
f *os.File
+ arch *sys.Arch
}
func openGoFile(f *os.File) (*File, error) {
@@ -45,9 +45,16 @@
return nil, err
}
r := goobj.NewReaderFromBytes(b, false)
+ var arch *sys.Arch
+ for _, a := range sys.Archs {
+ if a.Name == e.Obj.Arch {
+ arch = a
+ break
+ }
+ }
entries = append(entries, &Entry{
name: e.Name,
- raw: &goobjFile{e.Obj, r, f},
+ raw: &goobjFile{e.Obj, r, f, arch},
})
continue
case archive.EntryNativeObj:
@@ -223,17 +230,8 @@
// Returns "",0,nil if unknown.
// This function implements the Liner interface in preference to pcln() above.
func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
- // TODO: this is really inefficient. Binary search? Memoize last result?
r := f.r
- var arch *sys.Arch
- archname := f.goarch()
- for _, a := range sys.Archs {
- if a.Name == archname {
- arch = a
- break
- }
- }
- if arch == nil {
+ if f.arch == nil {
return "", 0, nil
}
pcdataBase := r.PcdataBase()
@@ -264,10 +262,10 @@
lengths := info.ReadFuncInfoLengths(b)
off, end := info.ReadPcline(b)
pcline := r.BytesAt(pcdataBase+off, int(end-off))
- line := int(pcValue(pcline, pc-addr, arch))
+ line := int(pcValue(pcline, pc-addr, f.arch))
off, end = info.ReadPcfile(b)
pcfile := r.BytesAt(pcdataBase+off, int(end-off))
- fileID := pcValue(pcfile, pc-addr, arch)
+ fileID := pcValue(pcfile, pc-addr, f.arch)
globalFileID := info.ReadFile(b, lengths.FileOff, uint32(fileID))
fileName := r.File(int(globalFileID))
// Note: we provide only the name in the Func structure.
@@ -332,11 +330,7 @@
}
func (f *goobjFile) goarch() string {
- hs := strings.Fields(string(f.goobj.TextHeader))
- if len(hs) >= 4 {
- return hs[3]
- }
- return ""
+ return f.goobj.Arch
}
func (f *goobjFile) loadAddress() (uint64, error) {