@@ -257,6 +257,49 @@ func (f *Func) LogStat(key string, args ...interface{}) {
257
257
f .Warnl (f .Entry .Pos , "\t %s\t %s%s\t %s" , n , key , value , f .Name )
258
258
}
259
259
260
+ // unCacheLine removes v from f's constant cache "line" for aux,
261
+ // resets v.InCache when it is found (and removed),
262
+ // and returns whether v was found in that line.
263
+ func (f * Func ) unCacheLine (v * Value , aux int64 ) bool {
264
+ vv := f .constants [aux ]
265
+ for i , cv := range vv {
266
+ if v == cv {
267
+ vv [i ] = vv [len (vv )- 1 ]
268
+ vv [len (vv )- 1 ] = nil
269
+ f .constants [aux ] = vv [0 : len (vv )- 1 ]
270
+ v .InCache = false
271
+ return true
272
+ }
273
+ }
274
+ return false
275
+ }
276
+
277
+ // unCache removes v from f's constant cache.
278
+ func (f * Func ) unCache (v * Value ) {
279
+ if v .InCache {
280
+ aux := v .AuxInt
281
+ if f .unCacheLine (v , aux ) {
282
+ return
283
+ }
284
+ if aux == 0 {
285
+ switch v .Op {
286
+ case OpConstNil :
287
+ aux = constNilMagic
288
+ case OpConstSlice :
289
+ aux = constSliceMagic
290
+ case OpConstString :
291
+ aux = constEmptyStringMagic
292
+ case OpConstInterface :
293
+ aux = constInterfaceMagic
294
+ }
295
+ if aux != 0 && f .unCacheLine (v , aux ) {
296
+ return
297
+ }
298
+ }
299
+ f .Fatalf ("unCached value %s not found in cache, auxInt=0x%x, adjusted aux=0x%x" , v .LongString (), v .AuxInt , aux )
300
+ }
301
+ }
302
+
260
303
// freeValue frees a value. It must no longer be referenced or have any args.
261
304
func (f * Func ) freeValue (v * Value ) {
262
305
if v .Block == nil {
@@ -270,19 +313,8 @@ func (f *Func) freeValue(v *Value) {
270
313
}
271
314
// Clear everything but ID (which we reuse).
272
315
id := v .ID
273
-
274
- // Values with zero arguments and OpOffPtr values might be cached, so remove them there.
275
- nArgs := opcodeTable [v .Op ].argLen
276
- if nArgs == 0 || v .Op == OpOffPtr {
277
- vv := f .constants [v .AuxInt ]
278
- for i , cv := range vv {
279
- if v == cv {
280
- vv [i ] = vv [len (vv )- 1 ]
281
- vv [len (vv )- 1 ] = nil
282
- f .constants [v .AuxInt ] = vv [0 : len (vv )- 1 ]
283
- break
284
- }
285
- }
316
+ if v .InCache {
317
+ f .unCache (v )
286
318
}
287
319
* v = Value {}
288
320
v .ID = id
@@ -548,6 +580,7 @@ func (f *Func) constVal(op Op, t *types.Type, c int64, setAuxInt bool) *Value {
548
580
v = f .Entry .NewValue0 (src .NoXPos , op , t )
549
581
}
550
582
f .constants [c ] = append (vv , v )
583
+ v .InCache = true
551
584
return v
552
585
}
553
586
0 commit comments