aboutsummaryrefslogtreecommitdiff
path: root/src/internal/pkgbits/decoder.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2022-09-22 22:27:33 -0400
committerDavid Chase <drchase@google.com>2022-09-27 20:36:31 +0000
commite8afb2911125ad65ddc02f7b83ab78a3e2f573b7 (patch)
treedd0f867e05a4f2789d5b97d70066d79f4f35a612 /src/internal/pkgbits/decoder.go
parent6485e8f50334f4ff369984759c22fba327a5d064 (diff)
downloadgo-e8afb2911125ad65ddc02f7b83ab78a3e2f573b7.tar.xz
cmd/compile: introduce "temporary" readers for more storage reuse
Change-Id: Id05d6099624284a9c1583b066d1a703e806b1e22 Reviewed-on: https://go-review.googlesource.com/c/go/+/433037 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/internal/pkgbits/decoder.go')
-rw-r--r--src/internal/pkgbits/decoder.go70
1 files changed, 62 insertions, 8 deletions
diff --git a/src/internal/pkgbits/decoder.go b/src/internal/pkgbits/decoder.go
index 357e328a3b..1a18da3301 100644
--- a/src/internal/pkgbits/decoder.go
+++ b/src/internal/pkgbits/decoder.go
@@ -52,6 +52,8 @@ type PkgDecoder struct {
// For example, section K's end positions start at elemEndsEnds[K-1]
// (or 0, if K==0) and end at elemEndsEnds[K].
elemEndsEnds [numRelocs]uint32
+
+ scratchRelocEnt []RelocEnt
}
// PkgPath returns the package path for the package
@@ -165,6 +167,21 @@ func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Deco
return r
}
+// TempDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+// If possible the Decoder should be RetireDecoder'd when it is no longer
+// needed, this will avoid heap allocations.
+func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+ r := pr.TempDecoderRaw(k, idx)
+ r.Sync(marker)
+ return r
+}
+
+func (pr *PkgDecoder) RetireDecoder(d *Decoder) {
+ pr.scratchRelocEnt = d.Relocs
+ d.Relocs = nil
+}
+
// NewDecoderRaw returns a Decoder for the given (section, index) pair.
//
// Most callers should use NewDecoder instead.
@@ -186,6 +203,30 @@ func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
return r
}
+func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder {
+ r := Decoder{
+ common: pr,
+ k: k,
+ Idx: idx,
+ }
+
+ r.Data.Reset(pr.DataIdx(k, idx))
+ r.Sync(SyncRelocs)
+ l := r.Len()
+ if cap(pr.scratchRelocEnt) >= l {
+ r.Relocs = pr.scratchRelocEnt[:l]
+ pr.scratchRelocEnt = nil
+ } else {
+ r.Relocs = make([]RelocEnt, l)
+ }
+ for i := range r.Relocs {
+ r.Sync(SyncReloc)
+ r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+ }
+
+ return r
+}
+
// A Decoder provides methods for decoding an individual element's
// bitstream data.
type Decoder struct {
@@ -408,8 +449,12 @@ func (r *Decoder) bigFloat() *big.Float {
// PeekPkgPath returns the package path for the specified package
// index.
func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
- r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef)
- path := r.String()
+ var path string
+ {
+ r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
+ path = r.String()
+ pr.RetireDecoder(&r)
+ }
if path == "" {
path = pr.pkgPath
}
@@ -419,14 +464,23 @@ func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
// PeekObj returns the package path, object name, and CodeObj for the
// specified object index.
func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
- r := pr.NewDecoder(RelocName, idx, SyncObject1)
- r.Sync(SyncSym)
- r.Sync(SyncPkg)
- path := pr.PeekPkgPath(r.Reloc(RelocPkg))
- name := r.String()
+ var ridx Index
+ var name string
+ var rcode int
+ {
+ r := pr.TempDecoder(RelocName, idx, SyncObject1)
+ r.Sync(SyncSym)
+ r.Sync(SyncPkg)
+ ridx = r.Reloc(RelocPkg)
+ name = r.String()
+ rcode = r.Code(SyncCodeObj)
+ pr.RetireDecoder(&r)
+ }
+
+ path := pr.PeekPkgPath(ridx)
assert(name != "")
- tag := CodeObj(r.Code(SyncCodeObj))
+ tag := CodeObj(rcode)
return path, name, tag
}