]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove values from const cache upon free
authorTodd Neal <todd@tneal.org>
Wed, 9 Mar 2016 04:13:20 +0000 (22:13 -0600)
committerTodd Neal <tolchz@gmail.com>
Thu, 10 Mar 2016 10:28:05 +0000 (10:28 +0000)
When calling freeValue for possible const values, remove them from the
cache as well.

Change-Id: I087ed592243e33c58e5db41700ab266fc70196d9
Reviewed-on: https://go-review.googlesource.com/20481
Run-TryBot: Todd Neal <tolchz@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/func_test.go

index e3e4b08af11d31fe712b459e4b7165c13d2f7b11..19b825a1205802ea38c36ccf4220642743290af9 100644 (file)
@@ -116,6 +116,19 @@ func (f *Func) freeValue(v *Value) {
        }
        // Clear everything but ID (which we reuse).
        id := v.ID
+
+       // Zero argument values might be cached, so remove them there.
+       nArgs := opcodeTable[v.Op].argLen
+       if nArgs == 0 {
+               vv := f.constants[v.AuxInt]
+               for i, cv := range vv {
+                       if v == cv {
+                               vv[i] = vv[len(vv)-1]
+                               f.constants[v.AuxInt] = vv[0 : len(vv)-1]
+                               break
+                       }
+               }
+       }
        *v = Value{}
        v.ID = id
        v.argstorage[0] = f.freeValues
@@ -280,6 +293,9 @@ func (f *Func) constVal(line int32, op Op, t Type, c int64, setAux bool) *Value
        vv := f.constants[c]
        for _, v := range vv {
                if v.Op == op && v.Type.Equal(t) {
+                       if setAux && v.AuxInt != c {
+                               panic(fmt.Sprintf("cached const %s should have AuxInt of %d", v.LongString(), c))
+                       }
                        return v
                }
        }
index fa6a1a8751b07e7e18819a6f974811e36cc74e03..4fef782afc0b740b53e64f83040abeca2bc73fce 100644 (file)
@@ -421,6 +421,28 @@ func TestEquiv(t *testing.T) {
        }
 }
 
+// TestConstCache ensures that the cache will not return
+// reused free'd values with a non-matching AuxInt
+func TestConstCache(t *testing.T) {
+       f := Fun(testConfig(t), "entry",
+               Bloc("entry",
+                       Valu("mem", OpInitMem, TypeMem, 0, nil),
+                       Exit("mem")))
+       v1 := f.f.ConstBool(0, TypeBool, false)
+       v2 := f.f.ConstBool(0, TypeBool, true)
+       f.f.freeValue(v1)
+       f.f.freeValue(v2)
+       v3 := f.f.ConstBool(0, TypeBool, false)
+       v4 := f.f.ConstBool(0, TypeBool, true)
+       if v3.AuxInt != 0 {
+               t.Errorf("expected %s to have auxint of 0\n", v3.LongString())
+       }
+       if v4.AuxInt != 1 {
+               t.Errorf("expected %s to have auxint of 1\n", v4.LongString())
+       }
+
+}
+
 // opcodeMap returns a map from opcode to the number of times that opcode
 // appears in the function.
 func opcodeMap(f *Func) map[Op]int {