1
0
mirror of https://github.com/golang/go synced 2024-11-26 02:47:58 -07:00

[dev.regabi] cmd/compile: change iexport to avoid map[ir.Node]

In the past, we had a lot of trouble with misusing *types.Sym
throughout the frontend, so I tried to push us towards always passing
around ONAMEs instead. But for constructing and writing out the symbol
indexes for the indexed export data, keying by *types.Sym is exactly
what we want.

Passes buildall w/ toolstash -cmp.

Updates #42982.

Change-Id: Idd8f1fb057d75a52a34ebc7788d9332fb49caf8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/275755
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2020-12-06 12:14:46 -08:00
parent 2d4c95565a
commit e885df2731

View File

@ -259,8 +259,8 @@ func iexport(out *bufio.Writer) {
p := iexporter{
allPkgs: map[*types.Pkg]bool{},
stringIndex: map[string]uint64{},
declIndex: map[ir.Node]uint64{},
inlineIndex: map[ir.Node]uint64{},
declIndex: map[*types.Sym]uint64{},
inlineIndex: map[*types.Sym]uint64{},
typIndex: map[*types.Type]uint64{},
}
@ -310,37 +310,34 @@ func iexport(out *bufio.Writer) {
out.Write(base.Ctxt.Fingerprint[:])
}
// writeIndex writes out an object index. mainIndex indicates whether
// writeIndex writes out a symbol index. mainIndex indicates whether
// we're writing out the main index, which is also read by
// non-compiler tools and includes a complete package description
// (i.e., name and height).
func (w *exportWriter) writeIndex(index map[ir.Node]uint64, mainIndex bool) {
// Build a map from packages to objects from that package.
pkgObjs := map[*types.Pkg][]ir.Node{}
func (w *exportWriter) writeIndex(index map[*types.Sym]uint64, mainIndex bool) {
// Build a map from packages to symbols from that package.
pkgSyms := map[*types.Pkg][]*types.Sym{}
// For the main index, make sure to include every package that
// we reference, even if we're not exporting (or reexporting)
// any symbols from it.
if mainIndex {
pkgObjs[ir.LocalPkg] = nil
pkgSyms[ir.LocalPkg] = nil
for pkg := range w.p.allPkgs {
pkgObjs[pkg] = nil
pkgSyms[pkg] = nil
}
}
for n := range index {
pkgObjs[n.Sym().Pkg] = append(pkgObjs[n.Sym().Pkg], n)
// Group symbols by package.
for sym := range index {
pkgSyms[sym.Pkg] = append(pkgSyms[sym.Pkg], sym)
}
// Sort packages by path.
var pkgs []*types.Pkg
for pkg, objs := range pkgObjs {
for pkg := range pkgSyms {
pkgs = append(pkgs, pkg)
sort.Slice(objs, func(i, j int) bool {
return objs[i].Sym().Name < objs[j].Sym().Name
})
}
sort.Slice(pkgs, func(i, j int) bool {
return pkgs[i].Path < pkgs[j].Path
})
@ -353,11 +350,16 @@ func (w *exportWriter) writeIndex(index map[ir.Node]uint64, mainIndex bool) {
w.uint64(uint64(pkg.Height))
}
objs := pkgObjs[pkg]
w.uint64(uint64(len(objs)))
for _, n := range objs {
w.string(n.Sym().Name)
w.uint64(index[n])
// Sort symbols within a package by name.
syms := pkgSyms[pkg]
sort.Slice(syms, func(i, j int) bool {
return syms[i].Name < syms[j].Name
})
w.uint64(uint64(len(syms)))
for _, sym := range syms {
w.string(sym.Name)
w.uint64(index[sym])
}
}
}
@ -374,8 +376,8 @@ type iexporter struct {
stringIndex map[string]uint64
data0 intWriter
declIndex map[ir.Node]uint64
inlineIndex map[ir.Node]uint64
declIndex map[*types.Sym]uint64
inlineIndex map[*types.Sym]uint64
typIndex map[*types.Type]uint64
}
@ -404,11 +406,11 @@ func (p *iexporter) pushDecl(n *ir.Name) {
return
}
if _, ok := p.declIndex[n]; ok {
if _, ok := p.declIndex[n.Sym()]; ok {
return
}
p.declIndex[n] = ^uint64(0) // mark n present in work queue
p.declIndex[n.Sym()] = ^uint64(0) // mark n present in work queue
p.declTodo.PushRight(n)
}
@ -423,13 +425,12 @@ type exportWriter struct {
prevColumn int64
}
func (p *iexporter) doDecl(n ir.Node) {
func (p *iexporter) doDecl(n *ir.Name) {
w := p.newWriter()
w.setPkg(n.Sym().Pkg, false)
switch n.Op() {
case ir.ONAME:
n := n.(*ir.Name)
switch n.Class() {
case ir.PEXTERN:
// Variable.
@ -455,7 +456,8 @@ func (p *iexporter) doDecl(n ir.Node) {
case ir.OLITERAL:
// Constant.
n = typecheck(n, ctxExpr)
// TODO(mdempsky): Do we still need this typecheck? If so, why?
n = typecheck(n, ctxExpr).(*ir.Name)
w.tag('C')
w.pos(n.Pos())
w.value(n.Type(), n.Val())
@ -509,7 +511,7 @@ func (p *iexporter) doDecl(n ir.Node) {
base.Fatalf("unexpected node: %v", n)
}
p.declIndex[n] = w.flush()
p.declIndex[n.Sym()] = w.flush()
}
func (w *exportWriter) tag(tag byte) {
@ -522,7 +524,7 @@ func (p *iexporter) doInline(f *ir.Name) {
w.stmtList(ir.AsNodes(f.Func().Inl.Body))
p.inlineIndex[f] = w.flush()
p.inlineIndex[f.Sym()] = w.flush()
}
func (w *exportWriter) pos(pos src.XPos) {