diff options
Diffstat (limited to 'src/cmd/compile/internal/noder/unified.go')
-rw-r--r-- | src/cmd/compile/internal/noder/unified.go | 110 |
1 files changed, 83 insertions, 27 deletions
diff --git a/src/cmd/compile/internal/noder/unified.go b/src/cmd/compile/internal/noder/unified.go index 46acdab79e..1ded367383 100644 --- a/src/cmd/compile/internal/noder/unified.go +++ b/src/cmd/compile/internal/noder/unified.go @@ -1,5 +1,3 @@ -// UNREVIEWED - // Copyright 2021 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. @@ -82,13 +80,12 @@ func unified(noders []*noder) { base.Flag.Lang = fmt.Sprintf("go1.%d", goversion.Version) types.ParseLangFlag() - types.LocalPkg.Height = 0 // reset so pkgReader.pkgIdx doesn't complain target := typecheck.Target typecheck.TypecheckAllowed = true localPkgReader = newPkgReader(pkgbits.NewPkgDecoder(types.LocalPkg.Path, data)) - readPackage(localPkgReader, types.LocalPkg) + readPackage(localPkgReader, types.LocalPkg, true) r := localPkgReader.newReader(pkgbits.RelocMeta, pkgbits.PrivateRootIdx, pkgbits.SyncPrivate) r.pkgInit(types.LocalPkg, target) @@ -164,7 +161,7 @@ func writePkgStub(noders []*noder) string { { w := publicRootWriter w.pkg(pkg) - w.Bool(false) // has init; XXX + w.Bool(false) // TODO(mdempsky): Remove; was "has init" scope := pkg.Scope() names := scope.Names() @@ -227,42 +224,76 @@ func freePackage(pkg *types2.Package) { base.Fatalf("package never finalized") } -func readPackage(pr *pkgReader, importpkg *types.Pkg) { - r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) +// readPackage reads package export data from pr to populate +// importpkg. +// +// localStub indicates whether pr is reading the stub export data for +// the local package, as opposed to relocated export data for an +// import. +func readPackage(pr *pkgReader, importpkg *types.Pkg, localStub bool) { + { + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + + pkg := r.pkg() + base.Assertf(pkg == importpkg, "have package %q (%p), want package %q (%p)", pkg.Path, pkg, importpkg.Path, importpkg) + + r.Bool() // TODO(mdempsky): Remove; was "has init" - pkg := r.pkg() - base.Assertf(pkg == importpkg, "have package %q (%p), want package %q (%p)", pkg.Path, pkg, importpkg.Path, importpkg) + for i, n := 0, r.Len(); i < n; i++ { + r.Sync(pkgbits.SyncObject) + assert(!r.Bool()) + idx := r.Reloc(pkgbits.RelocObj) + assert(r.Len() == 0) - if r.Bool() { - sym := pkg.Lookup(".inittask") - task := ir.NewNameAt(src.NoXPos, sym) - task.Class = ir.PEXTERN - sym.Def = task + path, name, code := r.p.PeekObj(idx) + if code != pkgbits.ObjStub { + objReader[types.NewPkg(path, "").Lookup(name)] = pkgReaderIndex{pr, idx, nil, nil} + } + } + + r.Sync(pkgbits.SyncEOF) } - for i, n := 0, r.Len(); i < n; i++ { - r.Sync(pkgbits.SyncObject) - assert(!r.Bool()) - idx := r.Reloc(pkgbits.RelocObj) - assert(r.Len() == 0) + if !localStub { + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PrivateRootIdx, pkgbits.SyncPrivate) - path, name, code := r.p.PeekObj(idx) - if code != pkgbits.ObjStub { - objReader[types.NewPkg(path, "").Lookup(name)] = pkgReaderIndex{pr, idx, nil} + if r.Bool() { + sym := importpkg.Lookup(".inittask") + task := ir.NewNameAt(src.NoXPos, sym) + task.Class = ir.PEXTERN + sym.Def = task + } + + for i, n := 0, r.Len(); i < n; i++ { + path := r.String() + name := r.String() + idx := r.Reloc(pkgbits.RelocBody) + + sym := types.NewPkg(path, "").Lookup(name) + if _, ok := importBodyReader[sym]; !ok { + importBodyReader[sym] = pkgReaderIndex{pr, idx, nil, nil} + } } + + r.Sync(pkgbits.SyncEOF) } } +// writeUnifiedExport writes to `out` the finalized, self-contained +// Unified IR export data file for the current compilation unit. func writeUnifiedExport(out io.Writer) { l := linker{ pw: pkgbits.NewPkgEncoder(base.Debug.SyncFrames), - pkgs: make(map[string]pkgbits.Index), - decls: make(map[*types.Sym]pkgbits.Index), + pkgs: make(map[string]pkgbits.Index), + decls: make(map[*types.Sym]pkgbits.Index), + bodies: make(map[*types.Sym]pkgbits.Index), } publicRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPublic) + privateRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPrivate) assert(publicRootWriter.Idx == pkgbits.PublicRootIdx) + assert(privateRootWriter.Idx == pkgbits.PrivateRootIdx) var selfPkgIdx pkgbits.Index @@ -273,7 +304,7 @@ func writeUnifiedExport(out io.Writer) { r.Sync(pkgbits.SyncPkg) selfPkgIdx = l.relocIdx(pr, pkgbits.RelocPkg, r.Reloc(pkgbits.RelocPkg)) - r.Bool() // has init + r.Bool() // TODO(mdempsky): Remove; was "has init" for i, n := 0, r.Len(); i < n; i++ { r.Sync(pkgbits.SyncObject) @@ -304,8 +335,7 @@ func writeUnifiedExport(out io.Writer) { w.Sync(pkgbits.SyncPkg) w.Reloc(pkgbits.RelocPkg, selfPkgIdx) - - w.Bool(typecheck.Lookup(".inittask").Def != nil) + w.Bool(false) // TODO(mdempsky): Remove; was "has init" w.Len(len(idxs)) for _, idx := range idxs { @@ -319,5 +349,31 @@ func writeUnifiedExport(out io.Writer) { w.Flush() } + { + type symIdx struct { + sym *types.Sym + idx pkgbits.Index + } + var bodies []symIdx + for sym, idx := range l.bodies { + bodies = append(bodies, symIdx{sym, idx}) + } + sort.Slice(bodies, func(i, j int) bool { return bodies[i].idx < bodies[j].idx }) + + w := privateRootWriter + + w.Bool(typecheck.Lookup(".inittask").Def != nil) + + w.Len(len(bodies)) + for _, body := range bodies { + w.String(body.sym.Pkg.Path) + w.String(body.sym.Name) + w.Reloc(pkgbits.RelocBody, body.idx) + } + + w.Sync(pkgbits.SyncEOF) + w.Flush() + } + base.Ctxt.Fingerprint = l.pw.DumpTo(out) } |