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/typecheck | |
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/typecheck')
-rw-r--r-- | src/cmd/compile/internal/typecheck/iimport.go | 39 | ||||
-rw-r--r-- | src/cmd/compile/internal/typecheck/mapfile_mmap.go | 49 | ||||
-rw-r--r-- | src/cmd/compile/internal/typecheck/mapfile_read.go | 22 |
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 -} |