]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make funccompile non-reentrant
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 14 Sep 2020 03:38:45 +0000 (10:38 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 15 Sep 2020 02:05:31 +0000 (02:05 +0000)
Currently, there's awkward reentrancy issue with funccompile:

    funccompile -> compile -> dtypesym -> geneq/genhash/genwrapper -> funccompile

Though it's not a problem at this moment, some attempts by @mdempsky to
move order/walk/instrument into buildssa was failed, due to SSA cache
corruption.

This commit fixes that reentrancy issue, by making generated functions
to be pumped through the same compile workqueue that normal functions
are compiled. We do this by adding them to xtop, instead of calling
funccompile directly in geneq/genhash/genwrapper. In dumpdata, we look
for uncompiled functions in xtop instead of compilequeue, then finish
compiling them.

Updates #38463
Fixes #33485

Change-Id: Ic9f0ce45b56ae2ff3862f17fd979253ddc144bb5
Reviewed-on: https://go-review.googlesource.com/c/go/+/254617
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Keith Randall <khr@golang.org>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>

src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/gc/subr.go

index c9d71ea00b44f68524d0102c26cf420f8488e9b5..6302b88f597ef64772b6a25ad8c5bc7924be7bba 100644 (file)
@@ -392,7 +392,7 @@ func genhash(t *types.Type) *obj.LSym {
        }
 
        fn.Func.SetNilCheckDisabled(true)
-       funccompile(fn)
+       xtop = append(xtop, fn)
 
        // Build closure. It doesn't close over any variables, so
        // it contains just the function pointer.
@@ -754,7 +754,7 @@ func geneq(t *types.Type) *obj.LSym {
        // neither of which can be nil, and our comparisons
        // are shallow.
        fn.Func.SetNilCheckDisabled(true)
-       funccompile(fn)
+       xtop = append(xtop, fn)
 
        // Generate a closure which points at the function we just generated.
        dsymptr(closure, 0, sym.Linksym(), 0)
index af5037c5a8bdcacd43df87ba4831d59042937879..b55331a948f4ee26ff21b8054834a75fcd2882ec 100644 (file)
@@ -113,12 +113,16 @@ func dumpCompilerObj(bout *bio.Writer) {
 
 func dumpdata() {
        externs := len(externdcl)
+       xtops := len(xtop)
 
        dumpglobls()
        addptabs()
+       exportlistLen := len(exportlist)
        addsignats(externdcl)
        dumpsignats()
        dumptabs()
+       ptabsLen := len(ptabs)
+       itabsLen := len(itabs)
        dumpimportstrings()
        dumpbasictypes()
 
@@ -129,9 +133,19 @@ func dumpdata() {
        // number of types in a finite amount of code.
        // In the typical case, we loop 0 or 1 times.
        // It was not until issue 24761 that we found any code that required a loop at all.
-       for len(compilequeue) > 0 {
+       for {
+               for i := xtops; i < len(xtop); i++ {
+                       n := xtop[i]
+                       if n.Op == ODCLFUNC {
+                               funccompile(n)
+                       }
+               }
+               xtops = len(xtop)
                compileFunctions()
                dumpsignats()
+               if xtops == len(xtop) {
+                       break
+               }
        }
 
        // Dump extra globals.
@@ -149,6 +163,16 @@ func dumpdata() {
        }
 
        addGCLocals()
+
+       if exportlistLen != len(exportlist) {
+               Fatalf("exportlist changed after compile functions loop")
+       }
+       if ptabsLen != len(ptabs) {
+               Fatalf("ptabs changed after compile functions loop")
+       }
+       if itabsLen != len(itabs) {
+               Fatalf("itabs changed after compile functions loop")
+       }
 }
 
 func dumpLinkerObj(bout *bio.Writer) {
index d3ba53ff0c03c478cbf4c68aef824d650a861a90..5a5833d19f6b70f31367b42838f5bfea14ed4913 100644 (file)
@@ -1615,7 +1615,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
        escapeFuncs([]*Node{fn}, false)
 
        Curfn = nil
-       funccompile(fn)
+       xtop = append(xtop, fn)
 }
 
 func paramNnames(ft *types.Type) []*Node {