mirror of
https://github.com/golang/go.git
synced 2025-05-29 03:11:26 +00: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:
parent
dbe54d23fe
commit
6cb2e1d015
@ -116,6 +116,19 @@ func (f *Func) freeValue(v *Value) {
|
|||||||
}
|
}
|
||||||
// Clear everything but ID (which we reuse).
|
// Clear everything but ID (which we reuse).
|
||||||
id := v.ID
|
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 = Value{}
|
||||||
v.ID = id
|
v.ID = id
|
||||||
v.argstorage[0] = f.freeValues
|
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]
|
vv := f.constants[c]
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
if v.Op == op && v.Type.Equal(t) {
|
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
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
// opcodeMap returns a map from opcode to the number of times that opcode
|
||||||
// appears in the function.
|
// appears in the function.
|
||||||
func opcodeMap(f *Func) map[Op]int {
|
func opcodeMap(f *Func) map[Op]int {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user