mirror of
https://github.com/golang/go
synced 2024-11-23 20:00:04 -07:00
cmd/compile: move more compiler specifics into compiler specific export section
Instead of indicating with each function signature if it has an inlineable body, collect all functions in order and export function bodies with function index in platform-specific section. Moves this compiler specific information out of the platform-independent export data section, and removes an int value for all functions w/o body. Also simplifies the code a bit. Change-Id: I8b2d7299dbe81f2706be49ecfb9d9f7da85fd854 Reviewed-on: https://go-review.googlesource.com/21939 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
d8e8fc292a
commit
7d0d122247
@ -124,10 +124,11 @@ const exportVersion = "v0"
|
||||
const exportInlined = true // default: true
|
||||
|
||||
type exporter struct {
|
||||
out *bufio.Writer
|
||||
pkgIndex map[*Pkg]int
|
||||
typIndex map[*Type]int
|
||||
inlined []*Func
|
||||
out *bufio.Writer
|
||||
|
||||
pkgIndex map[*Pkg]int // pkg -> pkg index in order of appearance
|
||||
typIndex map[*Type]int // type -> type index in order of appearance
|
||||
funcList []*Func // in order of appearance
|
||||
|
||||
// debugging support
|
||||
written int // bytes written
|
||||
@ -322,26 +323,38 @@ func export(out *bufio.Writer, trace bool) int {
|
||||
// --- inlined function bodies ---
|
||||
|
||||
if p.trace {
|
||||
p.tracef("\n--- inlined function bodies ---\n[ ")
|
||||
p.tracef("\n--- inlined function bodies ---\n")
|
||||
if p.indent != 0 {
|
||||
Fatalf("exporter: incorrect indentation")
|
||||
}
|
||||
}
|
||||
|
||||
// write inlined function bodies
|
||||
p.int(len(p.inlined))
|
||||
// write inlineable function bodies
|
||||
objcount = 0
|
||||
for i, f := range p.funcList {
|
||||
if f != nil {
|
||||
// function has inlineable body:
|
||||
// write index and body
|
||||
if p.trace {
|
||||
p.tracef("\n----\nfunc { %s }\n", Hconv(f.Inl, FmtSharp))
|
||||
}
|
||||
p.int(i)
|
||||
p.stmtList(f.Inl)
|
||||
if p.trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
objcount++
|
||||
}
|
||||
}
|
||||
|
||||
// indicate end of list
|
||||
if p.trace {
|
||||
p.tracef("]\n")
|
||||
}
|
||||
for _, f := range p.inlined {
|
||||
if p.trace {
|
||||
p.tracef("\n----\nfunc { %s }\n", Hconv(f.Inl, FmtSharp))
|
||||
}
|
||||
p.stmtList(f.Inl)
|
||||
if p.trace {
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.tracef("\n")
|
||||
}
|
||||
p.tag(-1) // invalid index terminates list
|
||||
|
||||
// for self-verification only (redundant)
|
||||
p.int(objcount)
|
||||
|
||||
if p.trace {
|
||||
p.tracef("\n--- end ---\n")
|
||||
@ -443,10 +456,9 @@ func (p *exporter) obj(sym *Sym) {
|
||||
p.paramList(sig.Params(), inlineable)
|
||||
p.paramList(sig.Results(), inlineable)
|
||||
|
||||
index := -1
|
||||
var f *Func
|
||||
if inlineable {
|
||||
index = len(p.inlined)
|
||||
p.inlined = append(p.inlined, sym.Def.Func)
|
||||
f = sym.Def.Func
|
||||
// TODO(gri) re-examine reexportdeplist:
|
||||
// Because we can trivially export types
|
||||
// in-place, we don't need to collect types
|
||||
@ -454,9 +466,9 @@ func (p *exporter) obj(sym *Sym) {
|
||||
// With an adjusted reexportdeplist used only
|
||||
// by the binary exporter, we can also avoid
|
||||
// the global exportlist.
|
||||
reexportdeplist(sym.Def.Func.Inl)
|
||||
reexportdeplist(f.Inl)
|
||||
}
|
||||
p.int(index)
|
||||
p.funcList = append(p.funcList, f)
|
||||
} else {
|
||||
// variable
|
||||
p.tag(varTag)
|
||||
@ -563,13 +575,12 @@ func (p *exporter) typ(t *Type) {
|
||||
p.paramList(sig.Params(), inlineable)
|
||||
p.paramList(sig.Results(), inlineable)
|
||||
|
||||
index := -1
|
||||
var f *Func
|
||||
if inlineable {
|
||||
index = len(p.inlined)
|
||||
p.inlined = append(p.inlined, mfn.Func)
|
||||
f = mfn.Func
|
||||
reexportdeplist(mfn.Func.Inl)
|
||||
}
|
||||
p.int(index)
|
||||
p.funcList = append(p.funcList, f)
|
||||
}
|
||||
|
||||
if p.trace && len(methods) > 0 {
|
||||
|
@ -23,9 +23,10 @@ type importer struct {
|
||||
in *bufio.Reader
|
||||
buf []byte // for reading strings
|
||||
bufarray [64]byte // initial underlying array for buf, large enough to avoid allocation when compiling std lib
|
||||
pkgList []*Pkg
|
||||
typList []*Type
|
||||
inlined []*Node // functions with pending inlined function bodies
|
||||
|
||||
pkgList []*Pkg // in order of appearance
|
||||
typList []*Type // in order of appearance
|
||||
funcList []*Node // in order of appearance; nil entry means already declared
|
||||
|
||||
// debugging support
|
||||
debugFormat bool
|
||||
@ -107,21 +108,35 @@ func Import(in *bufio.Reader) {
|
||||
Fatalf("importer: got %d objects; want %d", objcount, count)
|
||||
}
|
||||
|
||||
// read inlined functions bodies
|
||||
// read inlineable functions bodies
|
||||
if dclcontext != PEXTERN {
|
||||
Fatalf("importer: unexpected context %d", dclcontext)
|
||||
}
|
||||
|
||||
bcount := p.int() // consistency check only
|
||||
if bcount != len(p.inlined) {
|
||||
Fatalf("importer: expected %d inlined function bodies; got %d", bcount, len(p.inlined))
|
||||
}
|
||||
for _, f := range p.inlined {
|
||||
objcount = 0
|
||||
for i0 := -1; ; {
|
||||
i := p.int() // index of function with inlineable body
|
||||
if i < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// don't process the same function twice
|
||||
if i <= i0 {
|
||||
Fatalf("importer: index not increasing: %d <= %d", i, i0)
|
||||
}
|
||||
i0 = i
|
||||
|
||||
if Funcdepth != 0 {
|
||||
Fatalf("importer: unexpected Funcdepth %d", Funcdepth)
|
||||
}
|
||||
if f != nil {
|
||||
// function body not yet imported - read body and set it
|
||||
|
||||
// Note: In the original code, funchdr and funcbody are called for
|
||||
// all functions (that were not yet imported). Now, we are calling
|
||||
// them only for functions with inlineable bodies. funchdr does
|
||||
// parameter renaming which doesn't matter if we don't have a body.
|
||||
|
||||
if f := p.funcList[i]; f != nil {
|
||||
// function not yet imported - read body and set it
|
||||
funchdr(f)
|
||||
f.Func.Inl.Set(p.stmtList())
|
||||
funcbody(f)
|
||||
@ -131,6 +146,13 @@ func Import(in *bufio.Reader) {
|
||||
p.stmtList()
|
||||
dclcontext = PEXTERN
|
||||
}
|
||||
|
||||
objcount++
|
||||
}
|
||||
|
||||
// self-verification
|
||||
if count := p.int(); count != objcount {
|
||||
Fatalf("importer: got %d functions; want %d", objcount, count)
|
||||
}
|
||||
|
||||
if dclcontext != PEXTERN {
|
||||
@ -214,47 +236,23 @@ func (p *importer) obj(tag int) {
|
||||
sym := p.qualifiedName()
|
||||
params := p.paramList()
|
||||
result := p.paramList()
|
||||
inl := p.int()
|
||||
|
||||
sig := functype(nil, params, result)
|
||||
importsym(sym, ONAME)
|
||||
if sym.Def != nil && sym.Def.Op == ONAME {
|
||||
if Eqtype(sig, sym.Def.Type) {
|
||||
// function was imported before (via another import)
|
||||
dclcontext = PDISCARD // since we skip funchdr below
|
||||
} else {
|
||||
// function was imported before (via another import)
|
||||
if !Eqtype(sig, sym.Def.Type) {
|
||||
Fatalf("importer: inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, sig)
|
||||
}
|
||||
}
|
||||
|
||||
var n *Node
|
||||
if dclcontext != PDISCARD {
|
||||
n = newfuncname(sym)
|
||||
n.Type = sig
|
||||
declare(n, PFUNC)
|
||||
if inl < 0 {
|
||||
funchdr(n)
|
||||
}
|
||||
}
|
||||
|
||||
if inl >= 0 {
|
||||
// function has inlined body - collect for later
|
||||
if inl != len(p.inlined) {
|
||||
Fatalf("importer: inlined index = %d; want %d", inl, len(p.inlined))
|
||||
}
|
||||
p.inlined = append(p.inlined, n)
|
||||
}
|
||||
|
||||
// parser.go:hidden_import
|
||||
if dclcontext == PDISCARD {
|
||||
dclcontext = PEXTERN // since we skip the funcbody below
|
||||
p.funcList = append(p.funcList, nil)
|
||||
break
|
||||
}
|
||||
|
||||
if inl < 0 {
|
||||
funcbody(n)
|
||||
}
|
||||
importlist = append(importlist, n) // TODO(gri) may only be needed for inlineable functions
|
||||
n := newfuncname(sym)
|
||||
n.Type = sig
|
||||
declare(n, PFUNC)
|
||||
p.funcList = append(p.funcList, n)
|
||||
importlist = append(importlist, n)
|
||||
|
||||
if Debug['E'] > 0 {
|
||||
fmt.Printf("import [%q] func %v \n", importpkg.Path, n)
|
||||
@ -316,23 +314,13 @@ func (p *importer) typ() *Type {
|
||||
recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
|
||||
params := p.paramList()
|
||||
result := p.paramList()
|
||||
inl := p.int()
|
||||
|
||||
n := methodname1(newname(sym), recv[0].Right)
|
||||
n.Type = functype(recv[0], params, result)
|
||||
checkwidth(n.Type)
|
||||
addmethod(sym, n.Type, tsym.Pkg, false, false)
|
||||
if inl < 0 {
|
||||
funchdr(n)
|
||||
}
|
||||
|
||||
if inl >= 0 {
|
||||
// method has inlined body - collect for later
|
||||
if inl != len(p.inlined) {
|
||||
Fatalf("importer: inlined index = %d; want %d", inl, len(p.inlined))
|
||||
}
|
||||
p.inlined = append(p.inlined, n)
|
||||
}
|
||||
p.funcList = append(p.funcList, n)
|
||||
importlist = append(importlist, n)
|
||||
|
||||
// (comment from parser.go)
|
||||
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
|
||||
@ -341,12 +329,6 @@ func (p *importer) typ() *Type {
|
||||
// this back link here we avoid special casing there.
|
||||
n.Type.SetNname(n)
|
||||
|
||||
// parser.go:hidden_import
|
||||
if inl < 0 {
|
||||
funcbody(n)
|
||||
}
|
||||
importlist = append(importlist, n) // TODO(gri) may only be needed for inlineable functions
|
||||
|
||||
if Debug['E'] > 0 {
|
||||
fmt.Printf("import [%q] meth %v \n", importpkg.Path, n)
|
||||
if Debug['m'] > 2 && len(n.Func.Inl.Slice()) != 0 {
|
||||
|
@ -186,7 +186,6 @@ func (p *importer) obj(tag int) {
|
||||
params, isddd := p.paramList()
|
||||
result, _ := p.paramList()
|
||||
sig := types.NewSignature(nil, params, result, isddd)
|
||||
p.int() // read and discard index of inlined function body
|
||||
p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
|
||||
|
||||
default:
|
||||
@ -269,7 +268,6 @@ func (p *importer) typ(parent *types.Package) types.Type {
|
||||
recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
|
||||
params, isddd := p.paramList()
|
||||
result, _ := p.paramList()
|
||||
p.int() // read and discard index of inlined function body
|
||||
|
||||
sig := types.NewSignature(recv.At(0), params, result, isddd)
|
||||
t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
|
||||
|
Loading…
Reference in New Issue
Block a user