]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: improve undo of poset
authorGiovanni Bajo <rasky@develer.com>
Sat, 12 May 2018 20:13:44 +0000 (22:13 +0200)
committerDavid Chase <drchase@google.com>
Mon, 14 May 2018 14:31:48 +0000 (14:31 +0000)
prove uses the poset datastructure in a DFS walk, and always undoes
it back to its pristine status. Before this CL, poset's undo of
a new node creation didn't fully deallocate the node, which means
that at the end of prove there was still some allocated memory pending.

This was not a problem until now because the posets used by prove
were discarded after each function, but it would prevent recycling
them between functions (as a followup CL does).

Change-Id: I1c1c99c03fe19ad765395a43958cb256f686765a
Reviewed-on: https://go-review.googlesource.com/112976
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/fmt_test.go
src/cmd/compile/internal/ssa/poset.go
src/cmd/compile/internal/ssa/poset_test.go

index 5dd2fa50be8bcbcd7b2cca20d55f436cb83b82af..d224e67ea4be2f97bbbe667deb401098693fe201 100644 (file)
@@ -608,6 +608,8 @@ var knownFormats = map[string]string{
        "[]byte %x":                                       "",
        "[]cmd/compile/internal/ssa.Edge %v":              "",
        "[]cmd/compile/internal/ssa.ID %v":                "",
+       "[]cmd/compile/internal/ssa.posetNode %v":         "",
+       "[]cmd/compile/internal/ssa.posetUndo %v":         "",
        "[]cmd/compile/internal/syntax.token %s":          "",
        "[]string %v":                                     "",
        "[]uint32 %v":                                     "",
@@ -718,6 +720,7 @@ var knownFormats = map[string]string{
        "uint16 %v":                                                            "",
        "uint16 %x":                                                            "",
        "uint32 %d":                                                            "",
+       "uint32 %v":                                                            "",
        "uint32 %x":                                                            "",
        "uint64 %08x":                                                          "",
        "uint64 %d":                                                            "",
index 22826b92bba2f33e0eaa8e869bba85ff27c0f117..26a689404dc52afdc12a0e04e17732cf55475dbe 100644 (file)
@@ -679,13 +679,24 @@ func (po *poset) CheckIntegrity() (err error) {
 // It can be used for debugging purposes, as a poset is supposed to
 // be empty after it's fully rolled back through Undo.
 func (po *poset) CheckEmpty() error {
-       // Check that the poset is completely empty
+       if len(po.nodes) != 1 {
+               return fmt.Errorf("non-empty nodes list: %v", po.nodes)
+       }
        if len(po.values) != 0 {
                return fmt.Errorf("non-empty value map: %v", po.values)
        }
        if len(po.roots) != 0 {
                return fmt.Errorf("non-empty root list: %v", po.roots)
        }
+       if len(po.constants) != 0 {
+               return fmt.Errorf("non-empty constants: %v", po.constants)
+       }
+       if len(po.undo) != 0 {
+               return fmt.Errorf("non-empty undo list: %v", po.undo)
+       }
+       if po.lastidx != 0 {
+               return fmt.Errorf("lastidx index is not zero: %v", po.lastidx)
+       }
        for _, bs := range po.noneq {
                for _, x := range bs {
                        if x != 0 {
@@ -693,14 +704,6 @@ func (po *poset) CheckEmpty() error {
                        }
                }
        }
-       for idx, n := range po.nodes {
-               if n.l|n.r != 0 {
-                       return fmt.Errorf("non-empty node %v->[%d,%d]", idx, n.l.Target(), n.r.Target())
-               }
-       }
-       if len(po.constants) != 0 {
-               return fmt.Errorf("non-empty constant")
-       }
        return nil
 }
 
@@ -1123,6 +1126,9 @@ func (po *poset) Undo() {
                        po.noneq[pass.ID].Clear(pass.idx)
 
                case undoNewNode:
+                       if pass.idx != po.lastidx {
+                               panic("invalid newnode index")
+                       }
                        if pass.ID != 0 {
                                if po.values[pass.ID] != pass.idx {
                                        panic("invalid newnode undo pass")
@@ -1131,6 +1137,8 @@ func (po *poset) Undo() {
                        }
                        po.setchl(pass.idx, 0)
                        po.setchr(pass.idx, 0)
+                       po.nodes = po.nodes[:pass.idx]
+                       po.lastidx--
 
                        // If it was the last inserted constant, remove it
                        nc := len(po.constants)
index 899ac1ba06b5fb6cfa03bbd1be23e332daa5d261..89635ce54d1b0e5331058f1f947a78adf2668d78 100644 (file)
@@ -626,7 +626,6 @@ func TestPosetConst(t *testing.T) {
 
 func TestPosetNonEqual(t *testing.T) {
        testPosetOps(t, false, []posetTestOp{
-               {Checkpoint, 0, 0},
                {Equal_Fail, 10, 20},
                {NonEqual_Fail, 10, 20},