1
0
mirror of https://github.com/golang/go synced 2024-11-24 12:00:14 -07:00

cmd/compile: remove values from const cache upon free

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>
This commit is contained in:
Todd Neal 2016-03-08 22:13:20 -06:00 committed by Todd Neal
parent dbe54d23fe
commit 6cb2e1d015
2 changed files with 38 additions and 0 deletions

View 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
}
}

View 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 {