diff options
author | Matthew Dempsky <mdempsky@google.com> | 2021-06-04 10:26:40 -0700 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2021-06-05 23:28:52 +0000 |
commit | 4c072c94dc2ffedd29d51d04aba2e1a6f2afd93f (patch) | |
tree | 76ca779ea2b36b741515d744a21b7cb7eafdedb0 /src/cmd/compile/internal/importer | |
parent | 4e001a8d9eec1ec165b45a37e804c2cf42351bc5 (diff) | |
download | go-4c072c94dc2ffedd29d51d04aba2e1a6f2afd93f.tar.gz go-4c072c94dc2ffedd29d51d04aba2e1a6f2afd93f.zip |
[dev.typeparams] cmd/compile: refactor import reading
This CL restructures the gcimports importer to mmap the export data
into memory as a string, and then pass that same string to both the
typecheck and types2 importers.
This is primarily motivated by preparation for unified IR; but it
should also improve performance (fewer string copies) and reduces
divergance between the two importers.
Passes toolstash -cmp.
Change-Id: I397f720693e9e6360bfcb5acb12609ab339d251f
Reviewed-on: https://go-review.googlesource.com/c/go/+/325210
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/importer')
-rw-r--r-- | src/cmd/compile/internal/importer/gcimporter.go | 2 | ||||
-rw-r--r-- | src/cmd/compile/internal/importer/iimport.go | 34 |
2 files changed, 15 insertions, 21 deletions
diff --git a/src/cmd/compile/internal/importer/gcimporter.go b/src/cmd/compile/internal/importer/gcimporter.go index 6c5458fad1..ff40be65bb 100644 --- a/src/cmd/compile/internal/importer/gcimporter.go +++ b/src/cmd/compile/internal/importer/gcimporter.go @@ -155,7 +155,7 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. if len(data) > 0 && data[0] == 'i' { - _, pkg, err = iImportData(packages, data[1:], id) + pkg, err = ImportData(packages, string(data[1:]), id) } else { err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path) } diff --git a/src/cmd/compile/internal/importer/iimport.go b/src/cmd/compile/internal/importer/iimport.go index fb39e93073..14e64891b8 100644 --- a/src/cmd/compile/internal/importer/iimport.go +++ b/src/cmd/compile/internal/importer/iimport.go @@ -8,7 +8,6 @@ package importer import ( - "bytes" "cmd/compile/internal/syntax" "cmd/compile/internal/types2" "encoding/binary" @@ -18,10 +17,11 @@ import ( "io" "math/big" "sort" + "strings" ) type intReader struct { - *bytes.Reader + *strings.Reader path string } @@ -82,7 +82,7 @@ const io_SeekCurrent = 1 // io.SeekCurrent (not defined in Go 1.4) // and returns the number of bytes consumed and a reference to the package. // If the export data version is not recognized or the format is otherwise // compromised, an error is returned. -func iImportData(imports map[string]*types2.Package, data []byte, path string) (_ int, pkg *types2.Package, err error) { +func ImportData(imports map[string]*types2.Package, data, path string) (pkg *types2.Package, err error) { const currentVersion = iexportVersionCurrent version := int64(-1) defer func() { @@ -95,7 +95,7 @@ func iImportData(imports map[string]*types2.Package, data []byte, path string) ( } }() - r := &intReader{bytes.NewReader(data), path} + r := &intReader{strings.NewReader(data), path} version = int64(r.uint64()) switch version { @@ -122,7 +122,6 @@ func iImportData(imports map[string]*types2.Package, data []byte, path string) ( version: int(version), stringData: stringData, - stringCache: make(map[uint64]string), pkgCache: make(map[uint64]*types2.Package), posBaseCache: make(map[uint64]*syntax.PosBase), @@ -196,8 +195,7 @@ func iImportData(imports map[string]*types2.Package, data []byte, path string) ( // package was imported completely and without errors localpkg.MarkComplete() - consumed, _ := r.Seek(0, io_SeekCurrent) - return int(consumed), localpkg, nil + return localpkg, nil } type iimporter struct { @@ -205,12 +203,11 @@ type iimporter struct { ipath string version int - stringData []byte - stringCache map[uint64]string + stringData string pkgCache map[uint64]*types2.Package posBaseCache map[uint64]*syntax.PosBase - declData []byte + declData string pkgIndex map[*types2.Package]map[string]uint64 typCache map[uint64]types2.Type tparamIndex map[ident]types2.Type @@ -233,24 +230,21 @@ func (p *iimporter) doDecl(pkg *types2.Package, name string) { // Reader.Reset is not available in Go 1.4. // Use bytes.NewReader for now. // r.declReader.Reset(p.declData[off:]) - r.declReader = *bytes.NewReader(p.declData[off:]) + r.declReader = *strings.NewReader(p.declData[off:]) r.obj(name) } func (p *iimporter) stringAt(off uint64) string { - if s, ok := p.stringCache[off]; ok { - return s - } + var x [binary.MaxVarintLen64]byte + n := copy(x[:], p.stringData[off:]) - slen, n := binary.Uvarint(p.stringData[off:]) + slen, n := binary.Uvarint(x[:n]) if n <= 0 { errorf("varint failed") } spos := off + uint64(n) - s := string(p.stringData[spos : spos+slen]) - p.stringCache[off] = s - return s + return p.stringData[spos : spos+slen] } func (p *iimporter) pkgAt(off uint64) *types2.Package { @@ -285,7 +279,7 @@ func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type { // Reader.Reset is not available in Go 1.4. // Use bytes.NewReader for now. // r.declReader.Reset(p.declData[off-predeclReserved:]) - r.declReader = *bytes.NewReader(p.declData[off-predeclReserved:]) + r.declReader = *strings.NewReader(p.declData[off-predeclReserved:]) t := r.doType(base) if base == nil || !isInterface(t) { @@ -296,7 +290,7 @@ func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type { type importReader struct { p *iimporter - declReader bytes.Reader + declReader strings.Reader currPkg *types2.Package prevPosBase *syntax.PosBase prevLine int64 |