mirror of https://github.com/golang/go.git
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>
This commit is contained in:
parent
6485e8f503
commit
e8afb29111
|
|
@ -83,6 +83,17 @@ func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
|
||||||
|
return &reader{
|
||||||
|
Decoder: pr.TempDecoder(k, idx, marker),
|
||||||
|
p: pr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *pkgReader) retireReader(r *reader) {
|
||||||
|
pr.RetireDecoder(&r.Decoder)
|
||||||
|
}
|
||||||
|
|
||||||
// @@@ Positions
|
// @@@ Positions
|
||||||
|
|
||||||
func (r *reader) pos() syntax.Pos {
|
func (r *reader) pos() syntax.Pos {
|
||||||
|
|
@ -106,9 +117,9 @@ func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *syntax.PosBase {
|
||||||
if b := pr.posBases[idx]; b != nil {
|
if b := pr.posBases[idx]; b != nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
|
|
||||||
var b *syntax.PosBase
|
var b *syntax.PosBase
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
|
||||||
|
|
||||||
filename := r.String()
|
filename := r.String()
|
||||||
|
|
||||||
|
|
@ -120,6 +131,8 @@ func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *syntax.PosBase {
|
||||||
col := r.Uint()
|
col := r.Uint()
|
||||||
b = syntax.NewLineBase(pos, filename, true, line, col)
|
b = syntax.NewLineBase(pos, filename, true, line, col)
|
||||||
}
|
}
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
|
|
||||||
pr.posBases[idx] = b
|
pr.posBases[idx] = b
|
||||||
return b
|
return b
|
||||||
|
|
@ -202,11 +215,15 @@ func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types2.Type {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
|
var typ types2.Type
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
|
||||||
r.dict = dict
|
r.dict = dict
|
||||||
|
|
||||||
typ := r.doTyp()
|
typ = r.doTyp()
|
||||||
assert(typ != nil)
|
assert(typ != nil)
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
|
|
||||||
// See comment in pkgReader.typIdx explaining how this happens.
|
// See comment in pkgReader.typIdx explaining how this happens.
|
||||||
if prev := *where; prev != nil {
|
if prev := *where; prev != nil {
|
||||||
|
|
@ -361,12 +378,18 @@ func (r *reader) obj() (types2.Object, []types2.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
|
func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
|
||||||
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
|
var objPkg *types2.Package
|
||||||
|
var objName string
|
||||||
|
var tag pkgbits.CodeObj
|
||||||
|
{
|
||||||
|
rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
|
||||||
|
|
||||||
objPkg, objName := rname.qualifiedIdent()
|
objPkg, objName = rname.qualifiedIdent()
|
||||||
assert(objName != "")
|
assert(objName != "")
|
||||||
|
|
||||||
tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
|
tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
|
||||||
|
pr.retireReader(rname)
|
||||||
|
}
|
||||||
|
|
||||||
if tag == pkgbits.ObjStub {
|
if tag == pkgbits.ObjStub {
|
||||||
base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg)
|
base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg)
|
||||||
|
|
@ -431,9 +454,9 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
||||||
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
|
|
||||||
|
|
||||||
var dict readerDict
|
var dict readerDict
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
|
||||||
|
|
||||||
if implicits := r.Len(); implicits != 0 {
|
if implicits := r.Len(); implicits != 0 {
|
||||||
base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
|
base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
|
||||||
|
|
@ -450,6 +473,8 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
||||||
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
// function references follow, but reader doesn't need those
|
// function references follow, but reader doesn't need those
|
||||||
|
|
||||||
return &dict
|
return &dict
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,17 @@ func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
|
||||||
|
return &reader{
|
||||||
|
Decoder: pr.TempDecoder(k, idx, marker),
|
||||||
|
p: pr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *pkgReader) retireReader(r *reader) {
|
||||||
|
pr.RetireDecoder(&r.Decoder)
|
||||||
|
}
|
||||||
|
|
||||||
// @@@ Positions
|
// @@@ Positions
|
||||||
|
|
||||||
func (r *reader) pos() token.Pos {
|
func (r *reader) pos() token.Pos {
|
||||||
|
|
@ -155,14 +166,16 @@ func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
|
var filename string
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
|
||||||
|
|
||||||
// Within types2, position bases have a lot more details (e.g.,
|
// Within types2, position bases have a lot more details (e.g.,
|
||||||
// keeping track of where //line directives appeared exactly).
|
// keeping track of where //line directives appeared exactly).
|
||||||
//
|
//
|
||||||
// For go/types, we just track the file name.
|
// For go/types, we just track the file name.
|
||||||
|
|
||||||
filename := r.String()
|
filename = r.String()
|
||||||
|
|
||||||
if r.Bool() { // file base
|
if r.Bool() { // file base
|
||||||
// Was: "b = token.NewTrimmedFileBase(filename, true)"
|
// Was: "b = token.NewTrimmedFileBase(filename, true)"
|
||||||
|
|
@ -174,7 +187,8 @@ func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
|
||||||
// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
|
// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
|
||||||
_, _, _ = pos, line, col
|
_, _, _ = pos, line, col
|
||||||
}
|
}
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
b := filename
|
b := filename
|
||||||
pr.posBases[idx] = b
|
pr.posBases[idx] = b
|
||||||
return b
|
return b
|
||||||
|
|
@ -286,12 +300,15 @@ func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
|
var typ types.Type
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
|
||||||
r.dict = dict
|
r.dict = dict
|
||||||
|
|
||||||
typ := r.doTyp()
|
typ = r.doTyp()
|
||||||
assert(typ != nil)
|
assert(typ != nil)
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
// See comment in pkgReader.typIdx explaining how this happens.
|
// See comment in pkgReader.typIdx explaining how this happens.
|
||||||
if prev := *where; prev != nil {
|
if prev := *where; prev != nil {
|
||||||
return prev
|
return prev
|
||||||
|
|
@ -457,12 +474,19 @@ func (r *reader) obj() (types.Object, []types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||||
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
|
|
||||||
|
|
||||||
objPkg, objName := rname.qualifiedIdent()
|
var objPkg *types.Package
|
||||||
|
var objName string
|
||||||
|
var tag pkgbits.CodeObj
|
||||||
|
{
|
||||||
|
rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
|
||||||
|
|
||||||
|
objPkg, objName = rname.qualifiedIdent()
|
||||||
assert(objName != "")
|
assert(objName != "")
|
||||||
|
|
||||||
tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
|
tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
|
||||||
|
pr.retireReader(rname)
|
||||||
|
}
|
||||||
|
|
||||||
if tag == pkgbits.ObjStub {
|
if tag == pkgbits.ObjStub {
|
||||||
assert(objPkg == nil || objPkg == types.Unsafe)
|
assert(objPkg == nil || objPkg == types.Unsafe)
|
||||||
|
|
@ -567,10 +591,11 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
||||||
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
|
|
||||||
|
|
||||||
var dict readerDict
|
var dict readerDict
|
||||||
|
|
||||||
|
{
|
||||||
|
r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
|
||||||
if implicits := r.Len(); implicits != 0 {
|
if implicits := r.Len(); implicits != 0 {
|
||||||
errorf("unexpected object with %v implicit type parameter(s)", implicits)
|
errorf("unexpected object with %v implicit type parameter(s)", implicits)
|
||||||
}
|
}
|
||||||
|
|
@ -586,6 +611,8 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
||||||
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr.retireReader(r)
|
||||||
|
}
|
||||||
// function references follow, but reader doesn't need those
|
// function references follow, but reader doesn't need those
|
||||||
|
|
||||||
return &dict
|
return &dict
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ type PkgDecoder struct {
|
||||||
// For example, section K's end positions start at elemEndsEnds[K-1]
|
// For example, section K's end positions start at elemEndsEnds[K-1]
|
||||||
// (or 0, if K==0) and end at elemEndsEnds[K].
|
// (or 0, if K==0) and end at elemEndsEnds[K].
|
||||||
elemEndsEnds [numRelocs]uint32
|
elemEndsEnds [numRelocs]uint32
|
||||||
|
|
||||||
|
scratchRelocEnt []RelocEnt
|
||||||
}
|
}
|
||||||
|
|
||||||
// PkgPath returns the package path for the package
|
// 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
|
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.
|
// NewDecoderRaw returns a Decoder for the given (section, index) pair.
|
||||||
//
|
//
|
||||||
// Most callers should use NewDecoder instead.
|
// Most callers should use NewDecoder instead.
|
||||||
|
|
@ -186,6 +203,30 @@ func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
|
||||||
return r
|
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
|
// A Decoder provides methods for decoding an individual element's
|
||||||
// bitstream data.
|
// bitstream data.
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
|
|
@ -408,8 +449,12 @@ func (r *Decoder) bigFloat() *big.Float {
|
||||||
// PeekPkgPath returns the package path for the specified package
|
// PeekPkgPath returns the package path for the specified package
|
||||||
// index.
|
// index.
|
||||||
func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
|
func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
|
||||||
r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef)
|
var path string
|
||||||
path := r.String()
|
{
|
||||||
|
r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
|
||||||
|
path = r.String()
|
||||||
|
pr.RetireDecoder(&r)
|
||||||
|
}
|
||||||
if path == "" {
|
if path == "" {
|
||||||
path = pr.pkgPath
|
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
|
// PeekObj returns the package path, object name, and CodeObj for the
|
||||||
// specified object index.
|
// specified object index.
|
||||||
func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
|
func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
|
||||||
r := pr.NewDecoder(RelocName, idx, SyncObject1)
|
var ridx Index
|
||||||
|
var name string
|
||||||
|
var rcode int
|
||||||
|
{
|
||||||
|
r := pr.TempDecoder(RelocName, idx, SyncObject1)
|
||||||
r.Sync(SyncSym)
|
r.Sync(SyncSym)
|
||||||
r.Sync(SyncPkg)
|
r.Sync(SyncPkg)
|
||||||
path := pr.PeekPkgPath(r.Reloc(RelocPkg))
|
ridx = r.Reloc(RelocPkg)
|
||||||
name := r.String()
|
name = r.String()
|
||||||
|
rcode = r.Code(SyncCodeObj)
|
||||||
|
pr.RetireDecoder(&r)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := pr.PeekPkgPath(ridx)
|
||||||
assert(name != "")
|
assert(name != "")
|
||||||
|
|
||||||
tag := CodeObj(r.Code(SyncCodeObj))
|
tag := CodeObj(rcode)
|
||||||
|
|
||||||
return path, name, tag
|
return path, name, tag
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue