Skip to content

Instantly share code, notes, and snippets.

@chadwhitacre
Last active October 31, 2017 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chadwhitacre/c09acf8b57892367ce4bd82e0eeac537 to your computer and use it in GitHub Desktop.
Save chadwhitacre/c09acf8b57892367ce4bd82e0eeac537 to your computer and use it in GitHub Desktop.
package main
var (
a = c + b
b = f()
c = f()
)
func f() int {
return 1
}
func main() {
}
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index 3af2460..b0f5607 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -27,30 +27,50 @@ type InitPlan struct {
}
var (
- initlist []*Node
- initplans map[*Node]*InitPlan
- inittemps = make(map[*Node]*Node)
+ initlist []*Node
+ initplans map[*Node]*InitPlan
+ inittemps = make(map[*Node]*Node)
+ traceLevel = 0
)
+func trace(callee string, fromOn string, n *Node) {
+ var on string
+ if n == nil {
+ on = "nil"
+ } else if n.Sym == nil {
+ on = fmt.Sprint(int(n.Op), " (", n.Op, ")")
+ } else {
+ on = fmt.Sprint(int(n.Op), " (", n.Op, ") ", n.Sym.Name)
+ }
+ for i := 0; i < traceLevel; i++ {
+ print("·")
+ }
+ println(callee, "called from", fromOn, "which is", on)
+ traceLevel++
+}
+
// init1 walks the AST starting at n, and accumulates in out
// the list of definitions needing init code in dependency order.
-func init1(n *Node, out *[]*Node) {
+func init1(n *Node, out *[]*Node, fromOn string) {
+ trace("init1", fromOn, n)
if n == nil {
+ traceLevel -= 1
return
}
- init1(n.Left, out)
- init1(n.Right, out)
+ init1(n.Left, out, "init1 on n.Left")
+ init1(n.Right, out, "init1 on n.Right")
for _, n1 := range n.List.Slice() {
- init1(n1, out)
+ init1(n1, out, "init1 on n.List")
}
if n.isMethodExpression() {
// Methods called as Type.Method(receiver, ...).
// Definitions for method expressions are stored in type->nname.
- init1(asNode(n.Type.FuncType().Nname), out)
+ init1(asNode(n.Type.FuncType().Nname), out, "init1 on n.isMethodExpression")
}
if n.Op != ONAME {
+ traceLevel -= 1
return
}
switch n.Class() {
@@ -61,10 +81,12 @@ func init1(n *Node, out *[]*Node) {
// when they are inside a function.
break
}
+ traceLevel -= 1
return
}
if n.Initorder() == InitDone {
+ traceLevel -= 1
return
}
if n.Initorder() == InitPending {
@@ -92,6 +114,7 @@ func init1(n *Node, out *[]*Node) {
}
// The loop involves only functions, ok.
+ traceLevel -= 1
return
}
@@ -108,7 +131,7 @@ func init1(n *Node, out *[]*Node) {
Fatalf("init1: bad defn")
case ODCLFUNC:
- init2list(defn.Nbody, out)
+ init2list(defn.Nbody, out, "init1 on defn.Nbody")
case OAS:
if defn.Left != n {
@@ -122,7 +145,7 @@ func init1(n *Node, out *[]*Node) {
break
}
- init2(defn.Right, out)
+ init2(defn.Right, out, "init1 on defn.Right")
if Debug['j'] != 0 {
fmt.Printf("%v\n", n.Sym)
}
@@ -130,6 +153,10 @@ func init1(n *Node, out *[]*Node) {
if Debug['%'] != 0 {
Dump("nonstatic", defn)
}
+ for i := 0; i < traceLevel; i++ {
+ print("·")
+ }
+ println("appending", n.Sym.Name)
*out = append(*out, defn)
}
@@ -139,7 +166,7 @@ func init1(n *Node, out *[]*Node) {
}
defn.SetInitorder(InitPending)
for _, n2 := range defn.Rlist.Slice() {
- init1(n2, out)
+ init1(n2, out, "init2 on defn.Rlist")
}
if Debug['%'] != 0 {
Dump("nonstatic", defn)
@@ -157,6 +184,7 @@ func init1(n *Node, out *[]*Node) {
initlist = initlist[:last]
n.SetInitorder(InitDone)
+ traceLevel -= 1
}
// foundinitloop prints an init loop error and exits.
@@ -196,8 +224,10 @@ func foundinitloop(node, visited *Node) {
}
// recurse over n, doing init1 everywhere.
-func init2(n *Node, out *[]*Node) {
+func init2(n *Node, out *[]*Node, fromOn string) {
+ trace("init2", fromOn, n)
if n == nil || n.Initorder() == InitDone {
+ traceLevel -= 1
return
}
@@ -205,26 +235,29 @@ func init2(n *Node, out *[]*Node) {
Fatalf("name %v with ninit: %+v\n", n.Sym, n)
}
- init1(n, out)
- init2(n.Left, out)
- init2(n.Right, out)
- init2list(n.Ninit, out)
- init2list(n.List, out)
- init2list(n.Rlist, out)
- init2list(n.Nbody, out)
+ init1(n, out, "init2 on n")
+ init2(n.Left, out, "init2 on n.Left")
+ init2(n.Right, out, "init2 on n.Right")
+ init2list(n.Ninit, out, "init2 on n.Ninit")
+ init2list(n.List, out, "init2 on n.List")
+ init2list(n.Rlist, out, "init2 on n.Rlist")
+ init2list(n.Nbody, out, "init2 on n.Nbody")
switch n.Op {
case OCLOSURE:
- init2list(n.Func.Closure.Nbody, out)
+ init2list(n.Func.Closure.Nbody, out, "init2 on a closure")
case ODOTMETH, OCALLPART:
- init2(asNode(n.Type.FuncType().Nname), out)
+ init2(asNode(n.Type.FuncType().Nname), out, "init2 on a callable")
}
+ traceLevel -= 1
}
-func init2list(l Nodes, out *[]*Node) {
+func init2list(l Nodes, out *[]*Node, fromOn string) {
+ trace("init2list", fromOn, nil)
for _, n := range l.Slice() {
- init2(n, out)
+ init2(n, out, "init2list on n")
}
+ traceLevel -= 1
}
func initreorder(l []*Node, out *[]*Node) {
@@ -236,7 +269,7 @@ func initreorder(l []*Node, out *[]*Node) {
initreorder(n.Ninit.Slice(), out)
n.Ninit.Set(nil)
- init1(n, out)
+ init1(n, out, "initreorder on n")
}
}
# command-line-arguments
init1 called from initreorder on n which is 20 (=)
·init1 called from init1 on n.Left which is 1 (NAME) a
··init1 called from init1 on n.Left which is nil
··init1 called from init1 on n.Right which is nil
··init2 called from init1 on defn.Right which is 6 (+)
···init1 called from init2 on n which is 6 (+)
····init1 called from init1 on n.Left which is 1 (NAME) c
·····init1 called from init1 on n.Left which is nil
·····init1 called from init1 on n.Right which is nil
·····init2 called from init1 on defn.Right which is 28 (CALLFUNC)
······init1 called from init2 on n which is 28 (CALLFUNC)
·······init1 called from init1 on n.Left which is 1 (NAME) f
········init1 called from init1 on n.Left which is nil
········init1 called from init1 on n.Right which is nil
········init2list called from init1 on defn.Nbody which is nil
·········init2 called from init2list on n which is 126 (return)
··········init1 called from init2 on n which is 126 (return)
···········init1 called from init1 on n.Left which is nil
···········init1 called from init1 on n.Right which is nil
···········init1 called from init1 on n.List which is 20 (=)
············init1 called from init1 on n.Left which is 1 (NAME) ~r0
·············init1 called from init1 on n.Left which is nil
·············init1 called from init1 on n.Right which is nil
············init1 called from init1 on n.Right which is 5 (LITERAL)
·············init1 called from init1 on n.Left which is nil
·············init1 called from init1 on n.Right which is nil
··········init2 called from init2 on n.Left which is nil
··········init2 called from init2 on n.Right which is nil
··········init2list called from init2 on n.Ninit which is nil
··········init2list called from init2 on n.List which is nil
···········init2 called from init2list on n which is 20 (=)
············init1 called from init2 on n which is 20 (=)
·············init1 called from init1 on n.Left which is 1 (NAME) ~r0
··············init1 called from init1 on n.Left which is nil
··············init1 called from init1 on n.Right which is nil
·············init1 called from init1 on n.Right which is 5 (LITERAL)
··············init1 called from init1 on n.Left which is nil
··············init1 called from init1 on n.Right which is nil
············init2 called from init2 on n.Left which is 1 (NAME) ~r0
·············init1 called from init2 on n which is 1 (NAME) ~r0
··············init1 called from init1 on n.Left which is nil
··············init1 called from init1 on n.Right which is nil
·············init2 called from init2 on n.Left which is nil
·············init2 called from init2 on n.Right which is nil
·············init2list called from init2 on n.Ninit which is nil
·············init2list called from init2 on n.List which is nil
·············init2list called from init2 on n.Rlist which is nil
·············init2list called from init2 on n.Nbody which is nil
············init2 called from init2 on n.Right which is 5 (LITERAL)
·············init1 called from init2 on n which is 5 (LITERAL)
··············init1 called from init1 on n.Left which is nil
··············init1 called from init1 on n.Right which is nil
·············init2 called from init2 on n.Left which is nil
·············init2 called from init2 on n.Right which is nil
·············init2list called from init2 on n.Ninit which is nil
·············init2list called from init2 on n.List which is nil
·············init2list called from init2 on n.Rlist which is nil
·············init2list called from init2 on n.Nbody which is nil
············init2list called from init2 on n.Ninit which is nil
············init2list called from init2 on n.List which is nil
············init2list called from init2 on n.Rlist which is nil
············init2list called from init2 on n.Nbody which is nil
··········init2list called from init2 on n.Rlist which is nil
··········init2list called from init2 on n.Nbody which is nil
·······init1 called from init1 on n.Right which is nil
······init2 called from init2 on n.Left which is 1 (NAME) f
······init2 called from init2 on n.Right which is nil
······init2list called from init2 on n.Ninit which is nil
······init2list called from init2 on n.List which is nil
······init2list called from init2 on n.Rlist which is nil
······init2list called from init2 on n.Nbody which is nil
·····appending c
····init1 called from init1 on n.Right which is 1 (NAME) b
·····init1 called from init1 on n.Left which is nil
·····init1 called from init1 on n.Right which is nil
·····init2 called from init1 on defn.Right which is 28 (CALLFUNC)
······init1 called from init2 on n which is 28 (CALLFUNC)
·······init1 called from init1 on n.Left which is 1 (NAME) f
········init1 called from init1 on n.Left which is nil
········init1 called from init1 on n.Right which is nil
·······init1 called from init1 on n.Right which is nil
······init2 called from init2 on n.Left which is 1 (NAME) f
······init2 called from init2 on n.Right which is nil
······init2list called from init2 on n.Ninit which is nil
······init2list called from init2 on n.List which is nil
······init2list called from init2 on n.Rlist which is nil
······init2list called from init2 on n.Nbody which is nil
·····appending b
···init2 called from init2 on n.Left which is 1 (NAME) c
···init2 called from init2 on n.Right which is 1 (NAME) b
···init2list called from init2 on n.Ninit which is nil
···init2list called from init2 on n.List which is nil
···init2list called from init2 on n.Rlist which is nil
···init2list called from init2 on n.Nbody which is nil
··appending a
·init1 called from init1 on n.Right which is 6 (+)
··init1 called from init1 on n.Left which is 1 (NAME) c
···init1 called from init1 on n.Left which is nil
···init1 called from init1 on n.Right which is nil
··init1 called from init1 on n.Right which is 1 (NAME) b
···init1 called from init1 on n.Left which is nil
···init1 called from init1 on n.Right which is nil
init1 called from initreorder on n which is 20 (=)
·init1 called from init1 on n.Left which is 1 (NAME) b
··init1 called from init1 on n.Left which is nil
··init1 called from init1 on n.Right which is nil
·init1 called from init1 on n.Right which is 28 (CALLFUNC)
··init1 called from init1 on n.Left which is 1 (NAME) f
···init1 called from init1 on n.Left which is nil
···init1 called from init1 on n.Right which is nil
··init1 called from init1 on n.Right which is nil
init1 called from initreorder on n which is 20 (=)
·init1 called from init1 on n.Left which is 1 (NAME) c
··init1 called from init1 on n.Left which is nil
··init1 called from init1 on n.Right which is nil
·init1 called from init1 on n.Right which is 28 (CALLFUNC)
··init1 called from init1 on n.Left which is 1 (NAME) f
···init1 called from init1 on n.Left which is nil
···init1 called from init1 on n.Right which is nil
··init1 called from init1 on n.Right which is nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment