aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck
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/typecheck
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/typecheck')
-rw-r--r--src/cmd/compile/internal/typecheck/iimport.go39
-rw-r--r--src/cmd/compile/internal/typecheck/mapfile_mmap.go49
-rw-r--r--src/cmd/compile/internal/typecheck/mapfile_read.go22
3 files changed, 11 insertions, 99 deletions
diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go
index 45a177951e..cafb18d7a8 100644
--- a/src/cmd/compile/internal/typecheck/iimport.go
+++ b/src/cmd/compile/internal/typecheck/iimport.go
@@ -12,7 +12,6 @@ import (
"encoding/binary"
"fmt"
"go/constant"
- "io"
"math/big"
"os"
"strings"
@@ -20,8 +19,6 @@ import (
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
- "cmd/internal/bio"
- "cmd/internal/goobj"
"cmd/internal/obj"
"cmd/internal/src"
)
@@ -95,7 +92,7 @@ func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset
}
type intReader struct {
- *bio.Reader
+ *strings.Reader
pkg *types.Pkg
}
@@ -117,8 +114,8 @@ func (r *intReader) uint64() uint64 {
return i
}
-func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType) {
- ird := &intReader{in, pkg}
+func ReadImports(pkg *types.Pkg, data string) {
+ ird := &intReader{strings.NewReader(data), pkg}
version := ird.uint64()
switch version {
@@ -132,21 +129,15 @@ func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintT
base.ErrorExit()
}
- sLen := ird.uint64()
- dLen := ird.uint64()
+ sLen := int64(ird.uint64())
+ dLen := int64(ird.uint64())
- // Map string (and data) section into memory as a single large
- // string. This reduces heap fragmentation and allows
- // returning individual substrings very efficiently.
- data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
- if err != nil {
- base.Errorf("import %q: mapping input: %v", pkg.Path, err)
- base.ErrorExit()
- }
- stringData := data[:sLen]
- declData := data[sLen:]
-
- in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
+ // TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after
+ // #44505 is fixed.
+ whence, _ := ird.Seek(0, os.SEEK_CUR)
+ stringData := data[whence : whence+sLen]
+ declData := data[whence+sLen : whence+sLen+dLen]
+ ird.Seek(sLen+dLen, os.SEEK_CUR)
p := &iimporter{
exportVersion: version,
@@ -208,14 +199,6 @@ func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintT
}
}
}
-
- // Fingerprint.
- _, err = io.ReadFull(in, fingerprint[:])
- if err != nil {
- base.Errorf("import %s: error reading fingerprint", pkg.Path)
- base.ErrorExit()
- }
- return fingerprint
}
type iimporter struct {
diff --git a/src/cmd/compile/internal/typecheck/mapfile_mmap.go b/src/cmd/compile/internal/typecheck/mapfile_mmap.go
deleted file mode 100644
index 298b385bcb..0000000000
--- a/src/cmd/compile/internal/typecheck/mapfile_mmap.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-package typecheck
-
-import (
- "os"
- "reflect"
- "syscall"
- "unsafe"
-)
-
-// TODO(mdempsky): Is there a higher-level abstraction that still
-// works well for iimport?
-
-// mapFile returns length bytes from the file starting at the
-// specified offset as a string.
-func mapFile(f *os.File, offset, length int64) (string, error) {
- // POSIX mmap: "The implementation may require that off is a
- // multiple of the page size."
- x := offset & int64(os.Getpagesize()-1)
- offset -= x
- length += x
-
- buf, err := syscall.Mmap(int(f.Fd()), offset, int(length), syscall.PROT_READ, syscall.MAP_SHARED)
- keepAlive(f)
- if err != nil {
- return "", err
- }
-
- buf = buf[x:]
- pSlice := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
-
- var res string
- pString := (*reflect.StringHeader)(unsafe.Pointer(&res))
-
- pString.Data = pSlice.Data
- pString.Len = pSlice.Len
-
- return res, nil
-}
-
-// keepAlive is a reimplementation of runtime.KeepAlive, which wasn't
-// added until Go 1.7, whereas we need to compile with Go 1.4.
-var keepAlive = func(interface{}) {}
diff --git a/src/cmd/compile/internal/typecheck/mapfile_read.go b/src/cmd/compile/internal/typecheck/mapfile_read.go
deleted file mode 100644
index 9637ab97ab..0000000000
--- a/src/cmd/compile/internal/typecheck/mapfile_read.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
-
-package typecheck
-
-import (
- "io"
- "os"
-)
-
-func mapFile(f *os.File, offset, length int64) (string, error) {
- buf := make([]byte, length)
- _, err := io.ReadFull(io.NewSectionReader(f, offset, length), buf)
- if err != nil {
- return "", err
- }
- return string(buf), nil
-}