From 7f177752b9a970178343b51ed0c0ff2aee21b0da Mon Sep 17 00:00:00 2001 From: rtrimana Date: Tue, 14 Apr 2020 23:53:59 -0700 Subject: [PATCH] Fixing a bug: separating the state tracking for cycle analysis. --- .../nasa/jpf/listener/DPORStateReducer.java | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/src/main/gov/nasa/jpf/listener/DPORStateReducer.java b/src/main/gov/nasa/jpf/listener/DPORStateReducer.java index c8c7806..0c513f2 100644 --- a/src/main/gov/nasa/jpf/listener/DPORStateReducer.java +++ b/src/main/gov/nasa/jpf/listener/DPORStateReducer.java @@ -76,7 +76,8 @@ public class DPORStateReducer extends ListenerAdapter { private HashMap> conflictPairMap; // Record conflicting events private HashSet doneBacktrackSet; // Record state ID and trace already constructed private HashMap readWriteFieldsMap; // Record fields that are accessed - private HashMap restorableStateMap; // Maps state IDs to the restorable state object + private HashMap restorableStateMap; // Maps state IDs to the restorable state object + private HashMap stateToChoiceCounterMap; // Maps state IDs to the choice counter // Boolean states private boolean isBooleanCGFlipped; @@ -365,25 +366,6 @@ public class DPORStateReducer extends ListenerAdapter { } } - // This class compactly stores: 1) restorable VM state, and 2) global choice counter - private class RestorableState { - private RestorableVMState restorableState; - private int choiceCounter; - - public RestorableState (RestorableVMState restState, int choCtr) { - restorableState = restState; - choiceCounter = choCtr; - } - - public RestorableVMState getRestorableState() { - return restorableState; - } - - public int getChoiceCounter() { - return choiceCounter; - } - } - // -- CONSTANTS private final static String DO_CALL_METHOD = "doCall"; // We exclude fields that come from libraries (Java and Groovy), and also the infrastructure @@ -421,7 +403,11 @@ public class DPORStateReducer extends ListenerAdapter { backtrackPointList.add(new BacktrackPoint(icsCG, stateId, refChoices[choiceIndex])); // Store restorable state object for this state (always store the latest) RestorableVMState restorableState = vm.getRestorableState(); - restorableStateMap.put(stateId, new RestorableState(restorableState, choiceCounter)); + restorableStateMap.put(stateId, restorableState); + // Map multiple state IDs to a choice counter + for (Integer stId : justVisitedStates) { + stateToChoiceCounterMap.put(stId, choiceCounter); + } } private Integer[] copyChoices(Integer[] choicesToCopy) { @@ -474,6 +460,7 @@ public class DPORStateReducer extends ListenerAdapter { conflictPairMap = new HashMap<>(); doneBacktrackSet = new HashSet<>(); readWriteFieldsMap = new HashMap<>(); + stateToChoiceCounterMap = new HashMap<>(); // Booleans isEndOfExecution = false; } @@ -683,7 +670,7 @@ public class DPORStateReducer extends ListenerAdapter { int hiStateId = backtrackStateQ.peek(); // Restore the state first if necessary if (vm.getStateId() != hiStateId) { - RestorableVMState restorableState = restorableStateMap.get(hiStateId).getRestorableState(); + RestorableVMState restorableState = restorableStateMap.get(hiStateId); vm.restoreState(restorableState); } // Set the backtrack CG @@ -848,21 +835,19 @@ public class DPORStateReducer extends ListenerAdapter { // 2) We need to analyze and find conflicts for the reachable choices/events in the cycle // 3) Then we create a new backtrack point for every new conflict private void analyzeReachabilityAndCreateBacktrackPoints(VM vm, int stateId) { - // Perform this analysis only when there is a state match - if (!vm.isNewState()) { - if (restorableStateMap.containsKey(stateId)) { - // Find the choice/event that marks the start of this cycle: first choice we explore for conflicts - int conflictChoice = restorableStateMap.get(stateId).getChoiceCounter(); - int currentChoice = choiceCounter - 1; - // Find conflicts between choices/events in this cycle (we scan forward in the cycle, not backward) - while (conflictChoice < currentChoice) { - for (int eventCounter = conflictChoice + 1; eventCounter <= currentChoice; eventCounter++) { - if (isConflictFound(eventCounter, conflictChoice) && isNewConflict(conflictChoice, eventCounter)) { - createBacktrackingPoint(conflictChoice, eventCounter); - } + // Perform this analysis only when there is a state match and state > 0 (state 0 is for boolean CG) + if (!vm.isNewState() && (stateId > 0)) { + // Find the choice/event that marks the start of this cycle: first choice we explore for conflicts + int conflictChoice = stateToChoiceCounterMap.get(stateId); + int currentChoice = choiceCounter - 1; + // Find conflicts between choices/events in this cycle (we scan forward in the cycle, not backward) + while (conflictChoice < currentChoice) { + for (int eventCounter = conflictChoice + 1; eventCounter <= currentChoice; eventCounter++) { + if (isConflictFound(eventCounter, conflictChoice) && isNewConflict(conflictChoice, eventCounter)) { + createBacktrackingPoint(conflictChoice, eventCounter); } - conflictChoice++; } + conflictChoice++; } } } -- 2.34.1