aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/importer
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-06-04 10:26:40 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-06-05 23:28:52 +0000
commit4c072c94dc2ffedd29d51d04aba2e1a6f2afd93f (patch)
tree76ca779ea2b36b741515d744a21b7cb7eafdedb0 /src/cmd/compile/internal/importer
parent4e001a8d9eec1ec165b45a37e804c2cf42351bc5 (diff)
downloadgo-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.go2
-rw-r--r--src/cmd/compile/internal/importer/iimport.go34
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