From 3886c642471aa68f44503cd6ec57ca9f46de4731 Mon Sep 17 00:00:00 2001 From: jjenista <jjenista> Date: Tue, 16 Mar 2010 00:32:31 +0000 Subject: [PATCH] updating the global sweep and some related code--this currently bombs, only update if you must, it will compile though --- Robust/src/Analysis/Disjoint/ReachGraph.java | 216 +++++++++++++----- Robust/src/Analysis/Disjoint/ReachState.java | 4 + .../Tests/disjoint/predicateTest3/test.java | 4 +- 3 files changed, 161 insertions(+), 63 deletions(-) diff --git a/Robust/src/Analysis/Disjoint/ReachGraph.java b/Robust/src/Analysis/Disjoint/ReachGraph.java index 30e9ddb1..07552410 100644 --- a/Robust/src/Analysis/Disjoint/ReachGraph.java +++ b/Robust/src/Analysis/Disjoint/ReachGraph.java @@ -10,7 +10,7 @@ public class ReachGraph { // use to disable improvements for comparison protected static final boolean DISABLE_STRONG_UPDATES = false; - protected static final boolean DISABLE_GLOBAL_SWEEP = true; + protected static final boolean DISABLE_GLOBAL_SWEEP = false; // a special out-of-scope temp protected static final TempDescriptor tdReturn = new TempDescriptor( "_Return___" ); @@ -2486,7 +2486,9 @@ public class ReachGraph { // 5. - globalSweep(); + if( !DISABLE_GLOBAL_SWEEP ) { + globalSweep(); + } @@ -2622,10 +2624,25 @@ public class ReachGraph { public void globalSweep() { // boldB is part of the phase 1 sweep - Hashtable< Integer, Hashtable<RefEdge, ReachSet> > boldB = + // it has an in-context table and an out-of-context table + Hashtable< Integer, Hashtable<RefEdge, ReachSet> > boldBic = + new Hashtable< Integer, Hashtable<RefEdge, ReachSet> >(); + + Hashtable< Integer, Hashtable<RefEdge, ReachSet> > boldBooc = new Hashtable< Integer, Hashtable<RefEdge, ReachSet> >(); - // visit every heap region to initialize alphaNew and calculate boldB + // visit every heap region to initialize alphaNew and betaNew, + // and make a map of every hrnID to the source nodes it should + // propagate forward from. In-context flagged hrnID's propagate + // from only the in-context node they name, but out-of-context + // ID's may propagate from several out-of-context nodes + Hashtable< Integer, Set<HeapRegionNode> > icID2srcs = + new Hashtable< Integer, Set<HeapRegionNode> >(); + + Hashtable< Integer, Set<HeapRegionNode> > oocID2srcs = + new Hashtable< Integer, Set<HeapRegionNode> >(); + + Iterator itrHrns = id2hrn.entrySet().iterator(); while( itrHrns.hasNext() ) { Map.Entry me = (Map.Entry) itrHrns.next(); @@ -2642,64 +2659,129 @@ public class ReachGraph { assert rsetEmpty.equals( edge.getBetaNew() ); } - // calculate boldB for this flagged node + // calculate boldB for this flagged node, or out-of-context node if( hrn.isFlagged() ) { - - Hashtable<RefEdge, ReachSet> boldB_f = - new Hashtable<RefEdge, ReachSet>(); - - Set<RefEdge> workSetEdges = new HashSet<RefEdge>(); + assert !hrn.isOutOfContext(); + assert !icID2srcs.containsKey( hrn.getID() ); + Set<HeapRegionNode> srcs = new HashSet<HeapRegionNode>(); + srcs.add( hrn ); + icID2srcs.put( hrn.getID(), srcs ); + } - // initial boldB_f constraints - Iterator<RefEdge> itrRees = hrn.iteratorToReferencees(); - while( itrRees.hasNext() ) { - RefEdge edge = itrRees.next(); + if( hrn.isOutOfContext() ) { + assert !hrn.isFlagged(); - assert !boldB.containsKey( edge ); - boldB_f.put( edge, edge.getBeta() ); + Iterator<ReachState> stateItr = hrn.getAlpha().iterator(); + while( stateItr.hasNext() ) { + ReachState state = stateItr.next(); - assert !workSetEdges.contains( edge ); - workSetEdges.add( edge ); - } + Iterator<ReachTuple> rtItr = state.iterator(); + while( rtItr.hasNext() ) { + ReachTuple rt = rtItr.next(); + assert rt.isOutOfContext(); - // enforce the boldB_f constraint at edges until we reach a fixed point - while( !workSetEdges.isEmpty() ) { - RefEdge edge = workSetEdges.iterator().next(); - workSetEdges.remove( edge ); - - Iterator<RefEdge> itrPrime = edge.getDst().iteratorToReferencees(); - while( itrPrime.hasNext() ) { - RefEdge edgePrime = itrPrime.next(); + Set<HeapRegionNode> srcs = oocID2srcs.get( rt.getHrnID() ); + if( srcs == null ) { + srcs = new HashSet<HeapRegionNode>(); + } + srcs.add( hrn ); + oocID2srcs.put( rt.getHrnID(), srcs ); + } + } + } + } + + // calculate boldB for all hrnIDs identified by the above + // node traversal, propagating from every source + while( !icID2srcs.isEmpty() || !oocID2srcs.isEmpty() ) { + + Integer hrnID; + Set<HeapRegionNode> srcs; + boolean inContext; + + if( !icID2srcs.isEmpty() ) { + Map.Entry me = (Map.Entry) icID2srcs.entrySet().iterator().next(); + hrnID = (Integer) me.getKey(); + srcs = (Set<HeapRegionNode>) me.getValue(); + inContext = true; + icID2srcs.remove( hrnID ); + + } else { + assert !oocID2srcs.isEmpty(); + + Map.Entry me = (Map.Entry) oocID2srcs.entrySet().iterator().next(); + hrnID = (Integer) me.getKey(); + srcs = (Set<HeapRegionNode>) me.getValue(); + inContext = false; + oocID2srcs.remove( hrnID ); + } + + + Hashtable<RefEdge, ReachSet> boldB_f = + new Hashtable<RefEdge, ReachSet>(); + + Set<RefEdge> workSetEdges = new HashSet<RefEdge>(); - ReachSet prevResult = boldB_f.get( edgePrime ); - ReachSet intersection = Canonical.intersection( boldB_f.get( edge ), + Iterator<HeapRegionNode> hrnItr = srcs.iterator(); + while( hrnItr.hasNext() ) { + HeapRegionNode hrn = hrnItr.next(); + + assert workSetEdges.isEmpty(); + + // initial boldB_f constraints + Iterator<RefEdge> itrRees = hrn.iteratorToReferencees(); + while( itrRees.hasNext() ) { + RefEdge edge = itrRees.next(); + + assert !boldB_f.containsKey( edge ); + boldB_f.put( edge, edge.getBeta() ); + + assert !workSetEdges.contains( edge ); + workSetEdges.add( edge ); + } + + // enforce the boldB_f constraint at edges until we reach a fixed point + while( !workSetEdges.isEmpty() ) { + RefEdge edge = workSetEdges.iterator().next(); + workSetEdges.remove( edge ); + + Iterator<RefEdge> itrPrime = edge.getDst().iteratorToReferencees(); + while( itrPrime.hasNext() ) { + RefEdge edgePrime = itrPrime.next(); + + ReachSet prevResult = boldB_f.get( edgePrime ); + ReachSet intersection = Canonical.intersection( boldB_f.get( edge ), edgePrime.getBeta() ); - - if( prevResult == null || - Canonical.union( prevResult, + + if( prevResult == null || + Canonical.union( prevResult, intersection ).size() > prevResult.size() ) { - - if( prevResult == null ) { - boldB_f.put( edgePrime, + + if( prevResult == null ) { + boldB_f.put( edgePrime, Canonical.union( edgePrime.getBeta(), intersection ) ); - } else { - boldB_f.put( edgePrime, + } else { + boldB_f.put( edgePrime, Canonical.union( prevResult, intersection ) ); - } - workSetEdges.add( edgePrime ); - } - } - } - - boldB.put( hrnID, boldB_f ); - } + } + workSetEdges.add( edgePrime ); + } + } + } + } + + if( inContext ) { + boldBic.put( hrnID, boldB_f ); + } else { + boldBooc.put( hrnID, boldB_f ); + } } @@ -2717,14 +2799,20 @@ public class ReachGraph { Integer hrnID = (Integer) me.getKey(); HeapRegionNode hrn = (HeapRegionNode) me.getValue(); - // create the inherent hrnID from a flagged region - // as an exception to removal below - ReachTuple rtException = - ReachTuple.factory( hrnID, - !hrn.isSingleObject(), - ReachTuple.ARITY_ONE, - false // out-of-context - ); + // out-of-context nodes don't participate in the + // global sweep, they serve as sources for the pass + // performed above + if( hrn.isOutOfContext() ) { + continue; + } + + // the inherent states of a region are the exception + // to removal as the global sweep prunes + ReachTuple rtException = ReachTuple.factory( hrnID, + !hrn.isSingleObject(), + ReachTuple.ARITY_ONE, + false // out-of-context + ); ChangeSet cts = ChangeSet.factory(); @@ -2747,23 +2835,27 @@ public class ReachGraph { } } - // does boldB_ttOld allow this hrnID? + // does boldB allow this hrnID? boolean foundState = false; Iterator<RefEdge> incidentEdgeItr = hrn.iteratorToReferencers(); while( incidentEdgeItr.hasNext() ) { RefEdge incidentEdge = incidentEdgeItr.next(); - // if it isn't allowed, mark for removal - Integer idOld = rtOld.getHrnID(); - assert id2hrn.containsKey( idOld ); - Hashtable<RefEdge, ReachSet> B = boldB.get( idOld ); - ReachSet boldB_ttOld_incident = B.get( incidentEdge ); - if( boldB_ttOld_incident != null && - boldB_ttOld_incident.contains( stateOld ) ) { + Hashtable<RefEdge, ReachSet> B; + if( rtOld.isOutOfContext() ) { + B = boldBooc.get( rtOld.getHrnID() ); + } else { + assert id2hrn.containsKey( rtOld.getHrnID() ); + B = boldBic.get( rtOld.getHrnID() ); + } + + ReachSet boldB_rtOld_incident = B.get( incidentEdge ); + if( boldB_rtOld_incident != null && + boldB_rtOld_incident.contains( stateOld ) ) { foundState = true; } } - + if( !foundState ) { markedHrnIDs = Canonical.add( markedHrnIDs, rtOld ); } diff --git a/Robust/src/Analysis/Disjoint/ReachState.java b/Robust/src/Analysis/Disjoint/ReachState.java index 732054a3..21fc2811 100644 --- a/Robust/src/Analysis/Disjoint/ReachState.java +++ b/Robust/src/Analysis/Disjoint/ReachState.java @@ -121,6 +121,10 @@ public class ReachState extends Canonical { public String toString() { + return reachTuples.toString(); + } + + public String toStringPreds() { return reachTuples+":"+preds; } } diff --git a/Robust/src/Tests/disjoint/predicateTest3/test.java b/Robust/src/Tests/disjoint/predicateTest3/test.java index f8b640b9..00c84f4e 100644 --- a/Robust/src/Tests/disjoint/predicateTest3/test.java +++ b/Robust/src/Tests/disjoint/predicateTest3/test.java @@ -7,7 +7,9 @@ public class Test { static public void main( String[] args ) { Foo top = disjoint inMain new Foo(); - addSomething( top ); + Foo bot = new Foo(); + top.f = bot; + addSomething( bot ); } public static void addSomething( Foo x ) { -- 2.34.1