@VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; }
public ProgramState cleanupDeadSymbols(Set<Symbol> liveVariables) { PMap<Symbol, SymbolicValue> newValues = values; PMap<SymbolicValue, Integer> newReferences = references; PMap<SymbolicValue, Constraint> newConstraints = constraints; boolean newProgramState = false; for (Iterator<Map.Entry<Symbol, SymbolicValue>> iter = newValues.entriesIterator(); iter.hasNext();) { Map.Entry<Symbol, SymbolicValue> next = iter.next(); Symbol symbol = next.getKey(); if (isLocalVariable(symbol) && !liveVariables.contains(symbol)) { if (!newProgramState) { newProgramState = true; } SymbolicValue symbolicValue = next.getValue(); newValues = newValues.remove(symbol); newReferences = decreaseReference(newReferences, symbolicValue); if (!isReachable(symbolicValue, newReferences) && isDisposable(symbolicValue, newConstraints.get(symbolicValue)) && !inStack(stack, symbolicValue)) { newConstraints = newConstraints.remove(symbolicValue); newReferences = newReferences.remove(symbolicValue); } } } return newProgramState ? new ProgramState(newValues, newReferences, newConstraints, visitedPoints, stack) : this; }
@VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; }
ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown()) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack); } return this; }
public ProgramState resetFieldValues(ConstraintManager constraintManager) { final List<VariableTree> variableTrees = new ArrayList<>(); values.forEach(new PMap.Consumer<Symbol, SymbolicValue>() { @Override public void accept(Symbol symbol, SymbolicValue value) { if (isField(symbol)) { VariableTree variable = ((Symbol.VariableSymbol) symbol).declaration(); if (variable != null) { variableTrees.add(variable); } } } }); if (variableTrees.isEmpty()) { return this; } PMap<Symbol, SymbolicValue> newValues = values; PMap<SymbolicValue, Integer> newReferences = references; for (VariableTree variableTree : variableTrees) { Symbol symbol = variableTree.symbol(); SymbolicValue oldValue = newValues.get(symbol); if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } SymbolicValue newValue = constraintManager.createSymbolicValue(variableTree); newValues = newValues.put(symbol, newValue); newReferences = increaseReference(newReferences, newValue); } return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack); }