import IR.*;
import IR.Flat.*;
+import Analysis.OoOJava.*;
+
//////////////////////////////////////////////
//
Hashtable< FlatNode, Hashtable<TempDescriptor, StateMachineForEffects> >();
}
+
protected StateMachineForEffects getStateMachine( FlatNode fn,
TempDescriptor var ) {
}
-
public void addToStateMachine( Taint t,
Effect e,
FlatNode currentProgramPoint ) {
Set<FlatNew> sitesToFlag,
RBlockRelationAnalysis rra
) {
- init( s, tu, cg, l, ar, sitesToFlag, rra, false );
+ init( s, tu, cg, l, ar, sitesToFlag, rra, null, false );
}
public DisjointAnalysis( State s,
RBlockRelationAnalysis rra,
boolean suppressOutput
) {
- init( s, tu, cg, l, ar, sitesToFlag, rra, suppressOutput );
+ init( s, tu, cg, l, ar, sitesToFlag, rra, null, suppressOutput );
+ }
+
+ public DisjointAnalysis( State s,
+ TypeUtil tu,
+ CallGraph cg,
+ Liveness l,
+ ArrayReferencees ar,
+ Set<FlatNew> sitesToFlag,
+ RBlockRelationAnalysis rra,
+ BuildStateMachines bsm,
+ boolean suppressOutput
+ ) {
+ init( s, tu, cg, l, ar, sitesToFlag, rra, bsm, suppressOutput );
}
protected void init( State state,
ArrayReferencees arrayReferencees,
Set<FlatNew> sitesToFlag,
RBlockRelationAnalysis rra,
+ BuildStateMachines bsm,
boolean suppressOutput
) {
analysisComplete = false;
- this.state = state;
- this.typeUtil = typeUtil;
- this.callGraph = callGraph;
- this.liveness = liveness;
- this.arrayReferencees = arrayReferencees;
- this.sitesToFlag = sitesToFlag;
- this.rblockRel = rra;
- this.suppressOutput = suppressOutput;
+ this.state = state;
+ this.typeUtil = typeUtil;
+ this.callGraph = callGraph;
+ this.liveness = liveness;
+ this.arrayReferencees = arrayReferencees;
+ this.sitesToFlag = sitesToFlag;
+ this.rblockRel = rra;
+ this.suppressOutput = suppressOutput;
+ this.buildStateMachines = bsm;
if( rblockRel != null ) {
doEffectsAnalysis = true;
effectsAnalysis = new EffectsAnalysis();
}
- if( state.RCR ) {
- buildStateMachines = new BuildStateMachines();
- }
-
this.allocationDepth = state.DISJOINTALLOCDEPTH;
this.releaseMode = state.DISJOINTRELEASEMODE;
this.determinismDesired = state.DISJOINTDETERMINISM;
if ((!currentNode.getID().equals(entryNodeID))
&& !(analyzedIDSet.contains(currentNode.getID() + entryNodeID) || analyzedIDSet
- .contains(entryNodeID + currentNode.getID()))) {
-
+ .contains(entryNodeID + currentNode.getID()))) {
+
conflictType = calculateConflictType(currentNode, entryNode, useReachInfo);
if (conflictType > ConflictGraph.NON_WRITE_CONFLICT) {
addConflictEdge(conflictType, currentNode, entryNode);
}
private int calculateConflictType(ConflictNode node, boolean useReachInfo) {
-
+
int conflictType = ConflictGraph.NON_WRITE_CONFLICT;
- Hashtable<Alloc, Set<Effect>> alloc2readEffects = node.getReadEffectSet();
- Hashtable<Alloc, Set<Effect>> alloc2writeEffects = node.getWriteEffectSet();
- Hashtable<Alloc, Set<Effect>> alloc2SUEffects = node.getStrongUpdateEffectSet();
+
+ Hashtable<Alloc, Set<Effect>> alloc2readEffects = node.getReadEffectSet();
+ Hashtable<Alloc, Set<Effect>> alloc2writeEffects = node.getWriteEffectSet();
+ Hashtable<Alloc, Set<Effect>> alloc2SUEffects = node.getStrongUpdateEffectSet();
conflictType =
updateConflictType(conflictType, determineConflictType(node, alloc2writeEffects, node,
package Analysis.OoOJava;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Map.Entry;
-
-import Analysis.Pointer.Pointer;
-import Analysis.ArrayReferencees;
-import Analysis.Liveness;
-import Analysis.CallGraph.CallGraph;
-import Analysis.Disjoint.HeapAnalysis;
-import Analysis.Disjoint.DisjointAnalysis;
-import Analysis.Disjoint.Effect;
-import Analysis.Disjoint.EffectsAnalysis;
-import Analysis.Disjoint.Taint;
-import IR.Descriptor;
-import IR.MethodDescriptor;
-import IR.Operation;
-import IR.State;
-import IR.TypeUtil;
-import IR.Flat.FKind;
-import IR.Flat.FlatCall;
-import IR.Flat.FlatEdge;
-import IR.Flat.FlatElementNode;
-import IR.Flat.FlatFieldNode;
-import IR.Flat.FlatMethod;
-import IR.Flat.FlatNew;
-import IR.Flat.FlatNode;
-import IR.Flat.FlatOpNode;
-import IR.Flat.FlatSESEEnterNode;
-import IR.Flat.FlatSESEExitNode;
-import IR.Flat.FlatSetElementNode;
-import IR.Flat.FlatSetFieldNode;
-import IR.Flat.FlatWriteDynamicVarNode;
-import IR.Flat.TempDescriptor;
+import java.io.*;
+import java.util.*;
+
+import Analysis.*;
+import Analysis.CallGraph.*;
+import Analysis.Disjoint.*;
+import Analysis.Pointer.*;
+import IR.*;
+import IR.Flat.*;
+
public class OoOJavaAnalysis {
private RBlockRelationAnalysis rblockRel;
private HeapAnalysis disjointAnalysisTaints;
private DisjointAnalysis disjointAnalysisReach;
+ private BuildStateMachines buildStateMachines;
private Set<MethodDescriptor> descriptorsToAnalyze;
fn2contextTaskNames = new Hashtable<FlatNode, ContextTaskNames>();
fn2fm = new Hashtable<FlatNode, FlatMethod>();
+ // state machines support heap examiners with
+ // state transitions to improve precision
+ if( state.RCR ) {
+ buildStateMachines = new BuildStateMachines();
+ }
// add all methods transitively reachable from the
// source's main to set for analysis
} else
disjointAnalysisTaints =
new DisjointAnalysis(state, typeUtil, callGraph, liveness, arrayReferencees, null,
- rblockRel,
+ rblockRel, buildStateMachines,
true ); // suppress output--this is an intermediate pass
// 6th pass, not available analysis FOR VARIABLES!
disjointAnalysisReach =
new DisjointAnalysis(state, typeUtil, callGraph, liveness,
arrayReferencees, sitesToFlag,
- null // don't do effects analysis again!
+ null, // don't do effects analysis again!
+ null, // no BuildStateMachines needed
+ false // don't suppress progress output
);
// 10th pass, calculate conflicts with reachability info
calculateConflicts(null, true);
+
+ } else {
+ // in RCR/DFJ we want to do some extra processing on the
+ // state machines before they get handed off to code gen,
+ // and we're doing the same effect-conflict traversal needed
+ // to identify heap examiners that are weakly connected, so
+ // accomplish both at the same time
+ pruneMachinesAndFindWeaklyConnectedExaminers();
}
// 11th pass, compiling memory Qs! The name "lock" is a legacy
}
+
+ // the traversal for pruning state machines and finding
+ // machines that are weakly connected BOTH consider conflicting
+ // effects between heap roots, so it is smart to compute all of
+ // this together
+ public void pruneMachinesAndFindWeaklyConnectedExaminers() {
+
+ EffectsAnalysis effectsAnalysis = disjointAnalysisTaints.getEffectsAnalysis();
+
+ // visit every conflict graph once, so iterate through the
+ // the non-leaf tasks to find them all
+ Set<FlatSESEEnterNode> allSESEs = rblockRel.getAllSESEs();
+ for( Iterator allItr = allSESEs.iterator(); allItr.hasNext(); ) {
+
+ FlatSESEEnterNode parent = (FlatSESEEnterNode) allItr.next();
+ if( parent.getIsLeafSESE() ) {
+ continue;
+ }
+
+ ConflictGraph conflictGraph = sese2conflictGraph.get( parent );
+ assert conflictGraph != null;
+
+ // from the conflict graph we want to extract all conflicting effects
+ // and use them to identify (1) weakly connected heap examiners and
+ // (2) states/examiner nodes with a conflicting effect that will later
+ // support the examiner pruning process
+ Set<ConflictEdge> conflictEdges = conflictGraph.getEdgeSet();
+ for( Iterator edgeItr = conflictEdges.iterator(); edgeItr.hasNext(); ) {
+ ConflictEdge conflictEdge = (ConflictEdge) edgeItr.next();
+
+
+ }
+
+ }
+
+ }
+
+
+
private void synthesizeLocks() {
// for every conflict graph, generate a set of memory queues
// (called SESELock in this code!) to cover the graph
- Set<Entry<FlatNode, ConflictGraph>> graphEntrySet = sese2conflictGraph.entrySet();
+ Set<Map.Entry<FlatNode, ConflictGraph>> graphEntrySet = sese2conflictGraph.entrySet();
for (Iterator iterator = graphEntrySet.iterator(); iterator.hasNext();) {
- Entry<FlatNode, ConflictGraph> graphEntry = (Entry<FlatNode, ConflictGraph>) iterator.next();
+ Map.Entry<FlatNode, ConflictGraph> graphEntry = (Map.Entry<FlatNode, ConflictGraph>) iterator.next();
FlatNode sese = graphEntry.getKey();
ConflictGraph conflictGraph = graphEntry.getValue();
calculateCovering(conflictGraph);
}
//This is Pass 1 of internal graph creation.
- private void createPrunedGraph(
- Hashtable<Integer, ConcreteRuntimeObjNode> created,
- VariableNode varNode,
- Taint t) {
- // For every inset HRN, create a graph node, and run a DFT (buildPrunedGraphFromRG)
- Iterator<RefEdge> possibleEdges = varNode.iteratorToReferencees();
- while (possibleEdges.hasNext()) {
- RefEdge edge = possibleEdges.next();
- assert edge != null;
+ private void createPrunedGraph(Hashtable<Integer, ConcreteRuntimeObjNode> created,
+ VariableNode varNode,
+ Taint t) {
+ // For every inset HRN, create a graph node, and run a DFT (buildPrunedGraphFromRG)
+ Iterator<RefEdge> possibleEdges = varNode.iteratorToReferencees();
+ while (possibleEdges.hasNext()) {
+ RefEdge edge = possibleEdges.next();
+ assert edge != null;
- ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), true);
- int rootKey = singleRoot.allocSite.getUniqueAllocSiteID();
+ ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), true);
+ int rootKey = singleRoot.allocSite.getUniqueAllocSiteID();
- if (!created.containsKey(rootKey)) {
- created.put(rootKey, singleRoot);
- buildPrunedGraphFromRG(singleRoot, edge.getDst().iteratorToReferencees(), created, t);
- }
- }
- }
+ if (!created.containsKey(rootKey)) {
+ created.put(rootKey, singleRoot);
+ buildPrunedGraphFromRG(singleRoot, edge.getDst().iteratorToReferencees(), created, t);
+ }
+ }
+ }
//Performs Depth First Traversal on the ReachGraph to build an
//internal representation of it. It prunes ptrs not reachable
//by read Effects and stores in each node the effects by it.
private void buildPrunedGraphFromRG( ConcreteRuntimeObjNode curr,
- Iterator<RefEdge> edges,
- Hashtable<Integer, ConcreteRuntimeObjNode> created,
- Taint taint) {
+ Iterator<RefEdge> edges,
+ Hashtable<Integer, ConcreteRuntimeObjNode> created,
+ Taint taint) {
EffectsGroup currEffects = effectsLookupTable.getEffects(curr.allocSite, taint);
if (currEffects == null || currEffects.isEmpty())