state.changedVars = make([]bool, len(state.vars))
// A pending entry per user variable, with space to track each of its pieces.
- if want := len(state.vars) * len(state.slots); cap(state.cache.pendingSlotLocs) < want {
- state.cache.pendingSlotLocs = make([]VarLoc, want)
+ nPieces := 0
+ for i := range state.varSlots {
+ nPieces += len(state.varSlots[i])
}
- psl := state.cache.pendingSlotLocs[:len(state.vars)*len(state.slots)]
+ if cap(state.cache.pendingSlotLocs) < nPieces {
+ state.cache.pendingSlotLocs = make([]VarLoc, nPieces)
+ }
+ psl := state.cache.pendingSlotLocs[:nPieces]
for i := range psl {
psl[i] = VarLoc{}
}
state.cache.pendingEntries = make([]pendingEntry, len(state.vars))
}
pe := state.cache.pendingEntries[:len(state.vars)]
- for varID := range pe {
+ freePieceIdx := 0
+ for varID, slots := range state.varSlots {
pe[varID] = pendingEntry{
- pieces: state.cache.pendingSlotLocs[varID*len(state.slots) : (varID+1)*len(state.slots)],
+ pieces: state.cache.pendingSlotLocs[freePieceIdx : freePieceIdx+len(slots)],
}
+ freePieceIdx += len(slots)
}
}
type pendingEntry struct {
present bool
startBlock, startValue ID
- // The location of each piece of the variable, indexed by *SlotID*,
- // even though only a few slots are used in each entry. This could be
- // improved by only storing the relevant slots.
+ // The location of each piece of the variable, in the same order as the
+ // SlotIDs in varParts.
pieces []VarLoc
}
if state.loggingEnabled {
var partStrs []string
- for _, slot := range state.varSlots[varID] {
- partStrs = append(partStrs, fmt.Sprintf("%v@%v", state.slots[slot], state.LocString(pending.pieces[slot])))
+ for i, slot := range state.varSlots[varID] {
+ partStrs = append(partStrs, fmt.Sprintf("%v@%v", state.slots[slot], state.LocString(pending.pieces[i])))
}
state.logf("Add entry for %v: \tb%vv%v-b%vv%v = \t%v\n", state.vars[varID], pending.startBlock, pending.startValue, endBlock, endValue, strings.Join(partStrs, " "))
}
- for _, slotID := range state.varSlots[varID] {
- loc := pending.pieces[slotID]
+ for i, slotID := range state.varSlots[varID] {
+ loc := pending.pieces[i]
slot := state.slots[slotID]
if !loc.absent() {
// Extend the previous entry if possible.
if pending.present {
merge := true
- for _, slotID := range state.varSlots[varID] {
- if !canMerge(pending.pieces[slotID], curLoc[slotID]) {
+ for i, slotID := range state.varSlots[varID] {
+ if !canMerge(pending.pieces[i], curLoc[slotID]) {
merge = false
break
}
pending.present = true
pending.startBlock = v.Block.ID
pending.startValue = v.ID
- copy(pending.pieces, curLoc)
+ for i, slot := range state.varSlots[varID] {
+ pending.pieces[i] = curLoc[slot]
+ }
return
}