mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: separate exportsym more cleanly
Clean up a TODO (and make the package gc split easier) by moving the exportsym walk out of iexport proper. Also move exportsym call out of fninit. Change-Id: Ie5887a68d325f7154201f4a35b9b4be4bf4b48dd Reviewed-on: https://go-review.googlesource.com/c/go/+/279298 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
1a3b036b83
commit
85ce6ecfe3
4 changed files with 18 additions and 21 deletions
|
|
@ -60,6 +60,11 @@ func autoexport(n *ir.Name, ctxt ir.Class) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpexport(bout *bio.Writer) {
|
func dumpexport(bout *bio.Writer) {
|
||||||
|
p := &exporter{marked: make(map[*types.Type]bool)}
|
||||||
|
for _, n := range Target.Exports {
|
||||||
|
p.markObject(n)
|
||||||
|
}
|
||||||
|
|
||||||
// The linker also looks for the $$ marker - use char after $$ to distinguish format.
|
// The linker also looks for the $$ marker - use char after $$ to distinguish format.
|
||||||
exportf(bout, "\n$$B\n") // indicate binary export format
|
exportf(bout, "\n$$B\n") // indicate binary export format
|
||||||
off := bout.Offset()
|
off := bout.Offset()
|
||||||
|
|
|
||||||
|
|
@ -246,16 +246,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func iexport(out *bufio.Writer) {
|
func iexport(out *bufio.Writer) {
|
||||||
// Mark inline bodies that are reachable through exported objects.
|
|
||||||
// (Phase 0 of bexport.go.)
|
|
||||||
{
|
|
||||||
// TODO(mdempsky): Separate from bexport logic.
|
|
||||||
p := &exporter{marked: make(map[*types.Type]bool)}
|
|
||||||
for _, n := range Target.Exports {
|
|
||||||
p.markObject(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p := iexporter{
|
p := iexporter{
|
||||||
allPkgs: map[*types.Pkg]bool{},
|
allPkgs: map[*types.Pkg]bool{},
|
||||||
stringIndex: map[string]uint64{},
|
stringIndex: map[string]uint64{},
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,21 @@ func renameinit() *types.Sym {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// fninit makes an initialization record for the package.
|
// fninit makes and returns an initialization record for the package.
|
||||||
// See runtime/proc.go:initTask for its layout.
|
// See runtime/proc.go:initTask for its layout.
|
||||||
// The 3 tasks for initialization are:
|
// The 3 tasks for initialization are:
|
||||||
// 1) Initialize all of the packages the current package depends on.
|
// 1) Initialize all of the packages the current package depends on.
|
||||||
// 2) Initialize all the variables that have initializers.
|
// 2) Initialize all the variables that have initializers.
|
||||||
// 3) Run any init functions.
|
// 3) Run any init functions.
|
||||||
func fninit(n []ir.Node) {
|
func fninit() *ir.Name {
|
||||||
nf := initOrder(n)
|
nf := initOrder(Target.Decls)
|
||||||
|
|
||||||
var deps []*obj.LSym // initTask records for packages the current package depends on
|
var deps []*obj.LSym // initTask records for packages the current package depends on
|
||||||
var fns []*obj.LSym // functions to call for package initialization
|
var fns []*obj.LSym // functions to call for package initialization
|
||||||
|
|
||||||
// Find imported packages with init tasks.
|
// Find imported packages with init tasks.
|
||||||
for _, pkg := range Target.Imports {
|
for _, pkg := range Target.Imports {
|
||||||
n := resolve(oldname(pkg.Lookup(".inittask")))
|
n := resolve(ir.NewIdent(base.Pos, pkg.Lookup(".inittask")))
|
||||||
if n.Op() == ir.ONONAME {
|
if n.Op() == ir.ONONAME {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -92,16 +92,15 @@ func fninit(n []ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Name != "main" && types.LocalPkg.Name != "runtime" {
|
if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Name != "main" && types.LocalPkg.Name != "runtime" {
|
||||||
return // nothing to initialize
|
return nil // nothing to initialize
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make an .inittask structure.
|
// Make an .inittask structure.
|
||||||
sym := lookup(".inittask")
|
sym := lookup(".inittask")
|
||||||
nn := NewName(sym)
|
task := NewName(sym)
|
||||||
nn.SetType(types.Types[types.TUINT8]) // fake type
|
task.SetType(types.Types[types.TUINT8]) // fake type
|
||||||
nn.SetClass(ir.PEXTERN)
|
task.SetClass(ir.PEXTERN)
|
||||||
sym.Def = nn
|
sym.Def = task
|
||||||
exportsym(nn)
|
|
||||||
lsym := sym.Linksym()
|
lsym := sym.Linksym()
|
||||||
ot := 0
|
ot := 0
|
||||||
ot = duintptr(lsym, ot, 0) // state: not initialized yet
|
ot = duintptr(lsym, ot, 0) // state: not initialized yet
|
||||||
|
|
@ -116,4 +115,5 @@ func fninit(n []ir.Node) {
|
||||||
// An initTask has pointers, but none into the Go heap.
|
// An initTask has pointers, but none into the Go heap.
|
||||||
// It's not quite read only, the state field must be modifiable.
|
// It's not quite read only, the state field must be modifiable.
|
||||||
ggloblsym(lsym, int32(ot), obj.NOPTR)
|
ggloblsym(lsym, int32(ot), obj.NOPTR)
|
||||||
|
return task
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -306,7 +306,9 @@ func Main(archInit func(*Arch)) {
|
||||||
|
|
||||||
timings.AddEvent(fcount, "funcs")
|
timings.AddEvent(fcount, "funcs")
|
||||||
|
|
||||||
fninit(Target.Decls)
|
if initTask := fninit(); initTask != nil {
|
||||||
|
exportsym(initTask)
|
||||||
|
}
|
||||||
|
|
||||||
// Phase 4: Decide how to capture closed variables.
|
// Phase 4: Decide how to capture closed variables.
|
||||||
// This needs to run before escape analysis,
|
// This needs to run before escape analysis,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue