From: jjenista Date: Fri, 20 Mar 2009 01:10:10 +0000 (+0000) Subject: more progress toward new parameter model X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c87ae62f8ca032e0b0987b91481fb6d266dd70eb;p=IRC.git more progress toward new parameter model --- diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java index 9f5189b6..8c337758 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java @@ -54,10 +54,6 @@ public class OwnershipGraph { public Hashtable paramTokenPrimary2paramIndex; public Hashtable paramIndex2paramTokenPrimary; - public Hashtable paramTokenPrimaryPlus2paramIndex; - public Hashtable paramIndex2paramTokenPrimaryPlus; - public Hashtable paramTokenPrimaryStar2paramIndex; - public Hashtable paramIndex2paramTokenPrimaryStar; public Hashtable paramTokenSecondary2paramIndex; public Hashtable paramIndex2paramTokenSecondary; @@ -82,10 +78,6 @@ public class OwnershipGraph { paramTokenPrimary2paramIndex = new Hashtable(); paramIndex2paramTokenPrimary = new Hashtable(); - paramTokenPrimaryPlus2paramIndex = new Hashtable(); - paramIndex2paramTokenPrimaryPlus = new Hashtable(); - paramTokenPrimaryStar2paramIndex = new Hashtable(); - paramIndex2paramTokenPrimaryStar = new Hashtable(); paramTokenSecondary2paramIndex = new Hashtable(); paramIndex2paramTokenSecondary = new Hashtable(); @@ -946,9 +938,6 @@ public class OwnershipGraph { } } - // there must be at least one edge into the blob - assert primary2secondaryFields.size() > 0; - Iterator fieldItr = primary2primaryFields.iterator(); while( fieldItr.hasNext() ) { FieldDescriptor fd = fieldItr.next(); @@ -1052,10 +1041,6 @@ public class OwnershipGraph { // rewrite "with respect to no parameter" paramTokenPrimary2paramIndex.put( bogusToken, bogusIndex ); paramIndex2paramTokenPrimary.put( bogusIndex, bogusToken ); - paramTokenPrimaryPlus2paramIndex.put( bogusTokenPlus, bogusIndex ); - paramIndex2paramTokenPrimaryPlus.put( bogusIndex, bogusTokenPlus ); - paramTokenPrimaryStar2paramIndex.put( bogusTokenStar, bogusIndex ); - paramIndex2paramTokenPrimaryStar.put( bogusIndex, bogusTokenStar ); paramTokenSecondary2paramIndex.put( bogusToken, bogusIndex ); paramIndex2paramTokenSecondary.put( bogusIndex, bogusToken ); @@ -1078,19 +1063,7 @@ public class OwnershipGraph { false, // multiple-object? TokenTuple.ARITY_ONE ).makeCanonical(); paramTokenPrimary2paramIndex.put( p_i, paramIndex ); - paramIndex2paramTokenPrimary.put( paramIndex, p_i ); - - TokenTuple p_i_plus = new TokenTuple( hrnPrimary.getID(), - false, // multiple-object? - TokenTuple.ARITY_ONEORMORE ).makeCanonical(); - paramTokenPrimaryPlus2paramIndex.put( p_i_plus, paramIndex ); - paramIndex2paramTokenPrimaryPlus.put( paramIndex, p_i_plus ); - - TokenTuple p_i_star = new TokenTuple( hrnPrimary.getID(), - false, // multiple-object? - TokenTuple.ARITY_ZEROORMORE ).makeCanonical(); - paramTokenPrimaryStar2paramIndex.put( p_i_star, paramIndex ); - paramIndex2paramTokenPrimaryStar.put( paramIndex, p_i_star ); + paramIndex2paramTokenPrimary.put( paramIndex, p_i ); } // any parameter object, by type, may have no secondary region @@ -1100,23 +1073,23 @@ public class OwnershipGraph { assert id2hrn.containsKey( idSecondary ); HeapRegionNode hrnSecondary = id2hrn.get( idSecondary ); - TokenTuple r_i = new TokenTuple( hrnSecondary.getID(), + TokenTuple s_i = new TokenTuple( hrnSecondary.getID(), true, // multiple-object? TokenTuple.ARITY_ONE ).makeCanonical(); - paramTokenSecondary2paramIndex.put( r_i, paramIndex ); - paramIndex2paramTokenSecondary.put( paramIndex, r_i ); + paramTokenSecondary2paramIndex.put( s_i, paramIndex ); + paramIndex2paramTokenSecondary.put( paramIndex, s_i ); - TokenTuple r_i_plus = new TokenTuple( hrnSecondary.getID(), + TokenTuple s_i_plus = new TokenTuple( hrnSecondary.getID(), true, // multiple-object? TokenTuple.ARITY_ONEORMORE ).makeCanonical(); - paramTokenSecondaryPlus2paramIndex.put( r_i_plus, paramIndex ); - paramIndex2paramTokenSecondaryPlus.put( paramIndex, r_i_plus ); + paramTokenSecondaryPlus2paramIndex.put( s_i_plus, paramIndex ); + paramIndex2paramTokenSecondaryPlus.put( paramIndex, s_i_plus ); - TokenTuple r_i_star = new TokenTuple( hrnSecondary.getID(), + TokenTuple s_i_star = new TokenTuple( hrnSecondary.getID(), true, // multiple-object? TokenTuple.ARITY_ZEROORMORE ).makeCanonical(); - paramTokenSecondaryStar2paramIndex.put( r_i_star, paramIndex ); - paramIndex2paramTokenSecondaryStar.put( paramIndex, r_i_star ); + paramTokenSecondaryStar2paramIndex.put( s_i_star, paramIndex ); + paramIndex2paramTokenSecondaryStar.put( paramIndex, s_i_star ); } } } @@ -1715,6 +1688,8 @@ public class OwnershipGraph { MethodContext mc ) { + //String debugCaller = "foo"; + //String debugCallee = "bar"; String debugCaller = "foo"; String debugCallee = "bar"; @@ -1734,8 +1709,8 @@ public class OwnershipGraph { Hashtable paramIndex2rewriteH_p = new Hashtable(); Hashtable paramIndex2rewriteH_s = new Hashtable(); - Hashtable paramIndex2rewriteJ_p2p = new Hashtable(); // select( i, j, f ) - Hashtable paramIndex2rewriteJ_p2s = new Hashtable(); // select( i, f ) + Hashtable paramIndex2rewriteJ_p2p = new Hashtable(); // select( i, j, f ) + Hashtable paramIndex2rewriteJ_p2s = new Hashtable(); // select( i, f ) Hashtable paramIndex2rewriteJ_s2p = new Hashtable(); Hashtable paramIndex2rewriteJ_s2s = new Hashtable(); @@ -1900,90 +1875,146 @@ public class OwnershipGraph { } + // with respect to each argument, map parameter effects into caller HashSet nodesWithNewAlpha = new HashSet(); HashSet edgesWithNewBeta = new HashSet(); - Hashtable > paramIndex2directlyReachableCallerNodes = - new Hashtable >(); + Hashtable > pi2dr = + new Hashtable >(); - Hashtable > paramIndex2reachableCallerNodes = - new Hashtable >(); - - HashSet nodesDirectlyReachableAnyParam = new HashSet(); - HashSet nodesReachableAnyParam = new HashSet(); + Hashtable > pi2r = + new Hashtable >(); + + Set defParamObj = new HashSet(); + //Set drAny = new HashSet(); + //Set rAny = new HashSet(); Iterator lnArgItr = paramIndex2ln.entrySet().iterator(); while( lnArgItr.hasNext() ) { Map.Entry me = (Map.Entry) lnArgItr.next(); Integer index = (Integer) me.getKey(); LabelNode lnArg_i = (LabelNode) me.getValue(); - - HashSet nodesDirectlyReachable = new HashSet(); - HashSet nodesReachable = new HashSet(); - HashSet nodesTodo = new HashSet(); + + Set dr = new HashSet(); + Set r = new HashSet(); + Set todo = new HashSet(); // find all reachable nodes starting with label referencees Iterator edgeArgItr = lnArg_i.iteratorToReferencees(); while( edgeArgItr.hasNext() ) { ReferenceEdge edge = edgeArgItr.next(); HeapRegionNode hrn = edge.getDst(); - nodesTodo.add( hrn ); - nodesDirectlyReachable.add( hrn ); - nodesDirectlyReachableAnyParam.add( hrn ); - } - // then follow links until all reachable nodes have been found - while( !nodesTodo.isEmpty() ) { - HeapRegionNode hrn = nodesTodo.iterator().next(); - nodesTodo.remove( hrn ); - nodesReachable.add( hrn ); - nodesReachableAnyParam.add( hrn ); + dr.add( hrn ); + //drAny.add( hrn ); - Iterator edgeItr = hrn.iteratorToReferencees(); - while( edgeItr.hasNext() ) { - ReferenceEdge edge = edgeItr.next(); - if( !nodesReachable.contains( edge.getDst() ) ) { - nodesTodo.add( edge.getDst() ); + if( lnArg_i.getNumReferencees() == 1 && hrn.isSingleObject() ) { + defParamObj.add( hrn ); + } + + Iterator edgeHrnItr = hrn.iteratorToReferencees(); + while( edgeHrnItr.hasNext() ) { + ReferenceEdge edger = edgeHrnItr.next(); + todo.add( edger.getDst() ); + } + + // then follow links until all reachable nodes have been found + while( !todo.isEmpty() ) { + HeapRegionNode hrnr = todo.iterator().next(); + todo.remove( hrnr ); + + r.add( hrnr ); + //rAny.add( hrnr ); + + Iterator edgeItr = hrnr.iteratorToReferencees(); + while( edgeItr.hasNext() ) { + ReferenceEdge edger = edgeItr.next(); + if( !r.contains( edger.getDst() ) ) { + todo.add( edger.getDst() ); + } } } + + if( hrn.isSingleObject() ) { + r.remove( hrn ); + } } - paramIndex2directlyReachableCallerNodes.put( index, nodesDirectlyReachable ); - paramIndex2reachableCallerNodes .put( index, nodesReachable ); + pi2dr.put( index, dr ); + pi2r .put( index, r ); } + assert defParamObj.size() <= fm.numParameters(); + + + + System.out.println( "\n\n"+mc+" is calling "+fm+" *****" ); + + + // now iterate over reachable nodes to rewrite their alpha, and - // classify edges found for beta rewrite - HashSet edges_p2p = new HashSet(); - HashSet edges_p2s = new HashSet(); - HashSet edges_s2p = new HashSet(); - HashSet edges_s2s = new HashSet(); - HashSet edgesUpstreamDirectlyReachable = new HashSet(); - HashSet edgesUpstreamReachable = new HashSet(); + // classify edges found for beta rewrite + Hashtable tokens2states = new Hashtable(); - /* - Iterator lnArgItr = paramIndex2ln.entrySet().iterator(); + Hashtable< Integer, Set > edges_p2p = new Hashtable< Integer, Set >(); + Hashtable< Integer, Set > edges_p2s = new Hashtable< Integer, Set >(); + Hashtable< Integer, Set > edges_s2p = new Hashtable< Integer, Set >(); + Hashtable< Integer, Set > edges_s2s = new Hashtable< Integer, Set >(); + //HashSet edgesUpstreamDirectlyReachable = new HashSet(); + //HashSet edgesUpstreamReachable = new HashSet(); + + + // so again, with respect to some arg i... + lnArgItr = paramIndex2ln.entrySet().iterator(); while( lnArgItr.hasNext() ) { Map.Entry me = (Map.Entry) lnArgItr.next(); Integer index = (Integer) me.getKey(); - LabelNode lnArg_i = (LabelNode) me.getValue(); + LabelNode lnArg_i = (LabelNode) me.getValue(); + + TokenTuple p_i = ogCallee.paramIndex2paramTokenPrimary.get( index ); + TokenTuple s_i = ogCallee.paramIndex2paramTokenSecondary.get( index ); + assert p_i != null; - nodesDirectlyReachable = paramIndex2directlyReachableCallerNodes.get( index ); - Iterator hrnItr = nodesDirectlyReachable.iterator(); + + Set ei = edges_p2p.get( index ); + if( ei == null ) { ei = new HashSet(); } + edges_p2p.put( index, ei ); + + ei = edges_p2s.get( index ); + if( ei == null ) { ei = new HashSet(); } + edges_p2s.put( index, ei ); + + ei = edges_s2p.get( index ); + if( ei == null ) { ei = new HashSet(); } + edges_s2p.put( index, ei ); + + ei = edges_s2s.get( index ); + if( ei == null ) { ei = new HashSet(); } + edges_s2s.put( index, ei ); + + + System.out.println( "with respect to arg "+index ); + + + + Set dr = pi2dr.get( index ); + Iterator hrnItr = dr.iterator(); while( hrnItr.hasNext() ) { - HeapRegionNode hrn = hrnItr.next(); + // this heap region is definitely an "a_i" or primary by virtue of being in dr + HeapRegionNode hrn = hrnItr.next(); + + tokens2states.clear(); + tokens2states.put( p_i, hrn.getAlpha() ); rewriteCallerReachability( index, hrn, null, paramIndex2rewriteH_p.get( index ), + tokens2states, paramIndex2rewrite_d_p, - paramIndex2rewrite_d, + paramIndex2rewrite_d_s, paramIndex2rewriteD, - paramIndex2paramToken.get( index ), - paramToken2paramIndex, - paramTokenPlus2paramIndex, - paramTokenStar2paramIndex, + ogCallee, false, null ); @@ -1995,124 +2026,316 @@ public class OwnershipGraph { ReferenceEdge edge = edgeItr.next(); OwnershipNode on = edge.getSrc(); - if( on instanceof LabelNode ) { - LabelNode ln0 = (LabelNode) on; - if( ln0.equals( lnArg_i ) ) { - edgesReachable.add( edge ); - } else { - edgesUpstream.add( edge ); - } + //edgesUpstreamDirectlyReachable.add( edge ); - } else { + if( on instanceof HeapRegionNode ) { + // hrn0 may be "a_j" and/or "r_j" or even neither HeapRegionNode hrn0 = (HeapRegionNode) on; - if( nodesReachable.contains( hrn0 ) ) { - edgesReachable.add( edge ); - } else { - edgesUpstream.add( edge ); + + Iterator itr = pi2dr.entrySet().iterator(); + while( itr.hasNext() ) { + Map.Entry mo = (Map.Entry) itr.next(); + Integer pi = (Integer) mo.getKey(); + Set dr_i = (Set) mo.getValue(); + + if( dr_i.contains( hrn0 ) ) { + Vector v = new Vector(); v.setSize( 2 ); + v.set( 0 , edge ); + v.set( 1 , index ); + Set e = edges_p2p.get( pi ); + if( e == null ) { e = new HashSet(); } + e.add( v ); + edges_p2p.put( pi, e ); + + //System.out.println( " sorting "+edge+" with "+pi+"->"+index ); + } + } + + itr = pi2r.entrySet().iterator(); + while( itr.hasNext() ) { + Map.Entry mo = (Map.Entry) itr.next(); + Integer pi = (Integer) mo.getKey(); + Set r_i = (Set) mo.getValue(); + + if( r_i.contains( hrn0 ) ) { + Vector v = new Vector(); v.setSize( 2 ); + v.set( 0, edge ); + v.set( 1, index ); + Set e = edges_s2p.get( pi ); + if( e == null ) { e = new HashSet(); } + e.add( v ); + edges_s2p.put( pi, e ); + } } } } } - nodesReachable = paramIndex2reachableCallerNodes.get( index ); - hrnItr = nodesReachable.iterator(); + + Set r = pi2r.get( index ); + hrnItr = r.iterator(); while( hrnItr.hasNext() ) { - HeapRegionNode hrn = hrnItr.next(); + // this heap region is definitely an "r_i" or secondary by virtue of being in r + HeapRegionNode hrn = hrnItr.next(); - rewriteCallerReachability(index, - hrn, - null, - paramIndex2rewriteH.get(index), - paramIndex2rewrite_d, - paramIndex2rewriteD, - paramIndex2paramToken.get(index), - paramToken2paramIndex, - paramTokenPlus2paramIndex, - paramTokenStar2paramIndex, - false, - null); + assert s_i != null; + assert paramIndex2rewriteH_s.get( index ) != null; - nodesWithNewAlpha.add(hrn); + tokens2states.clear(); + tokens2states.put( p_i, new ReachabilitySet().makeCanonical() ); + tokens2states.put( s_i, hrn.getAlpha() ); - // look at all incoming edges to the reachable nodes - // and sort them as edges reachable from the argument - // label node, or upstream edges + rewriteCallerReachability( index, + hrn, + null, + paramIndex2rewriteH_s.get( index ), + tokens2states, + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + false, + null ); + + nodesWithNewAlpha.add( hrn ); + + // sort edges Iterator edgeItr = hrn.iteratorToReferencers(); while( edgeItr.hasNext() ) { ReferenceEdge edge = edgeItr.next(); OwnershipNode on = edge.getSrc(); - if( on instanceof LabelNode ) { - LabelNode ln0 = (LabelNode) on; - if( ln0.equals(lnArg_i) ) { - edgesReachable.add(edge); - } else { - edgesUpstream.add(edge); - } + //edgesUpstreamReachable.add( edge ); - } else { + if( on instanceof HeapRegionNode ) { + // hrn0 may be "a_j" and/or "r_j" or even neither HeapRegionNode hrn0 = (HeapRegionNode) on; - if( nodesReachable.contains(hrn0) ) { - edgesReachable.add(edge); - } else { - edgesUpstream.add(edge); + + Iterator itr = pi2dr.entrySet().iterator(); + while( itr.hasNext() ) { + Map.Entry mo = (Map.Entry) itr.next(); + Integer pi = (Integer) mo.getKey(); + Set dr_i = (Set) mo.getValue(); + + if( dr_i.contains( hrn0 ) ) { + Vector v = new Vector(); v.setSize( 2 ); + v.set( 0, edge ); + v.set( 1, index ); + Set e = edges_p2s.get( pi ); + if( e == null ) { e = new HashSet(); } + e.add( v ); + edges_p2s.put( pi, e ); + } + } + + itr = pi2r.entrySet().iterator(); + while( itr.hasNext() ) { + Map.Entry mo = (Map.Entry) itr.next(); + Integer pi = (Integer) mo.getKey(); + Set r_i = (Set) mo.getValue(); + + if( r_i.contains( hrn0 ) ) { + Vector v = new Vector(); v.setSize( 2 ); + v.set( 0, edge ); + v.set( 1, index ); + Set e = edges_s2s.get( pi ); + if( e == null ) { e = new HashSet(); } + e.add( v ); + edges_s2s.put( pi, e ); + } } } } } + } + + + // and again, with respect to some arg i... + lnArgItr = paramIndex2ln.entrySet().iterator(); + while( lnArgItr.hasNext() ) { + Map.Entry me = (Map.Entry) lnArgItr.next(); + Integer index = (Integer) me.getKey(); + LabelNode lnArg_i = (LabelNode) me.getValue(); // update reachable edges - Iterator edgeReachableItr = edgesReachable.iterator(); - while( edgeReachableItr.hasNext() ) { - ReferenceEdge edgeReachable = edgeReachableItr.next(); + Iterator edgeItr = edges_p2p.get( index ).iterator(); + while( edgeItr.hasNext() ) { + Vector mo = (Vector) edgeItr.next(); + ReferenceEdge edge = (ReferenceEdge) mo.get( 0 ); + Integer indexJ = (Integer) mo.get( 1 ); + + TokenTuple p_j = ogCallee.paramIndex2paramTokenPrimary.get( indexJ ); + assert p_j != null; - rewriteCallerReachability(index, - null, - edgeReachable, - paramIndex2rewriteJ.get(index), - paramIndex2rewrite_d, - paramIndex2rewriteD, - paramIndex2paramToken.get(index), - paramToken2paramIndex, - paramTokenPlus2paramIndex, - paramTokenStar2paramIndex, - false, - null); + + System.out.println( "Classified "+edge+" as p2p, p_j="+p_j ); + System.out.println( " and callee index2tok="+ogCallee.paramIndex2paramTokenPrimary ); + System.out.println( " and callee tok2index="+ogCallee.paramTokenPrimary2paramIndex ); + System.out.println( " paramIndex2rewriteJ_p2p="+paramIndex2rewriteJ_p2p ); + System.out.println( " key is: "+makeMapKey( index, indexJ, edge.getField() ) ); + + tokens2states.clear(); + tokens2states.put( p_j, edge.getBeta() ); + + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteJ_p2p.get( makeMapKey( index, + indexJ, + edge.getField() ) ), + tokens2states, + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + false, + null ); - edgesWithNewBeta.add(edgeReachable); + edgesWithNewBeta.add( edge ); } - // update upstream edges + + edgeItr = edges_p2s.get( index ).iterator(); + while( edgeItr.hasNext() ) { + Vector mo = (Vector) edgeItr.next(); + ReferenceEdge edge = (ReferenceEdge) mo.get( 0 ); + Integer indexJ = (Integer) mo.get( 1 ); + + TokenTuple s_j = ogCallee.paramIndex2paramTokenSecondary.get( indexJ ); + assert s_j != null; + + tokens2states.clear(); + tokens2states.put( s_j, edge.getBeta() ); + + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteJ_p2s.get( makeMapKey( index, + edge.getField() ) ), + tokens2states, + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + false, + null ); + + edgesWithNewBeta.add( edge ); + } + + + edgeItr = edges_s2p.get( index ).iterator(); + while( edgeItr.hasNext() ) { + Vector mo = (Vector) edgeItr.next(); + ReferenceEdge edge = (ReferenceEdge) mo.get( 0 ); + Integer indexJ = (Integer) mo.get( 1 ); + + TokenTuple p_j = ogCallee.paramIndex2paramTokenPrimary.get( indexJ ); + assert p_j != null; + + tokens2states.clear(); + tokens2states.put( p_j, edge.getBeta() ); + + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteJ_s2p.get( index ), + tokens2states, + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + false, + null ); + + edgesWithNewBeta.add( edge ); + } + + + edgeItr = edges_s2s.get( index ).iterator(); + while( edgeItr.hasNext() ) { + Vector mo = (Vector) edgeItr.next(); + ReferenceEdge edge = (ReferenceEdge) mo.get( 0 ); + Integer indexJ = (Integer) mo.get( 1 ); + + TokenTuple s_j = ogCallee.paramIndex2paramTokenSecondary.get( indexJ ); + assert s_j != null; + + tokens2states.clear(); + tokens2states.put( s_j, edge.getBeta() ); + + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteJ_s2s.get( index ), + tokens2states, + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + false, + null ); + + edgesWithNewBeta.add( edge ); + } + + + /* + // update directly upstream edges Hashtable edgeUpstreamPlannedChanges = new Hashtable(); - Iterator edgeUpstreamItr = edgesUpstream.iterator(); - while( edgeUpstreamItr.hasNext() ) { - ReferenceEdge edgeUpstream = edgeUpstreamItr.next(); + edgeItr = edgesUpstreamDirectlyReachable.iterator(); + while( edgeItr.hasNext() ) { + ReferenceEdge edge = edgeItr.next(); - rewriteCallerReachability(index, - null, - edgeUpstream, - paramIndex2rewriteK.get(index), - paramIndex2rewrite_d, - paramIndex2rewriteD, - paramIndex2paramToken.get(index), - paramToken2paramIndex, - paramTokenPlus2paramIndex, - paramTokenStar2paramIndex, - true, - edgeUpstreamPlannedChanges); + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteK_p.get( index ), + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + true, + edgeUpstreamPlannedChanges ); - edgesWithNewBeta.add(edgeUpstream); + edgesWithNewBeta.add( edge ); } - propagateTokensOverEdges(edgesUpstream, - edgeUpstreamPlannedChanges, - edgesWithNewBeta); + propagateTokensOverEdges( edgesUpstream, + edgeUpstreamPlannedChanges, + edgesWithNewBeta ); - } - */ + // update upstream edges + edgeUpstreamPlannedChanges = + new Hashtable(); + + edgeItr = edgesUpstreamReachable.iterator(); + while( edgeItr.hasNext() ) { + ReferenceEdge edge = edgeItr.next(); + + rewriteCallerReachability( index, + null, + edge, + paramIndex2rewriteK_s.get( index ), + paramIndex2rewrite_d_p, + paramIndex2rewrite_d_s, + paramIndex2rewriteD, + ogCallee, + true, + edgeUpstreamPlannedChanges ); + + edgesWithNewBeta.add( edge ); + } + + propagateTokensOverEdges( edgesUpstream, + edgeUpstreamPlannedChanges, + edgesWithNewBeta ); + */ + + } // end effects per argument/parameter map // commit changes to alpha and beta Iterator nodeItr = nodesWithNewAlpha.iterator(); @@ -2262,12 +2485,12 @@ public class OwnershipGraph { HashSet possibleCallerSrcs = getHRNSetThatPossiblyMapToCalleeHRN(ogCallee, (HeapRegionNode) edgeCallee.getSrc(), - paramIndex2reachableCallerNodes); + pi2r); HashSet possibleCallerDsts = getHRNSetThatPossiblyMapToCalleeHRN(ogCallee, edgeCallee.getDst(), - paramIndex2reachableCallerNodes); + pi2r); // make every possible pair of {srcSet} -> {dstSet} edges in the caller @@ -2351,7 +2574,7 @@ public class OwnershipGraph { HashSet assignCallerRhs = getHRNSetThatPossiblyMapToCalleeHRN(ogCallee, edgeCallee.getDst(), - paramIndex2reachableCallerNodes); + pi2r); Iterator itrHrn = assignCallerRhs.iterator(); while( itrHrn.hasNext() ) { @@ -2462,6 +2685,7 @@ public class OwnershipGraph { // improve reachability as much as possible globalSweep(); + */ if( mc.getDescriptor().getSymbol().equals( debugCaller ) && fm.getMethod().getSymbol().equals( debugCallee ) ) { @@ -2470,7 +2694,6 @@ public class OwnershipGraph { } catch( IOException e ) {} System.out.println( " "+mc+" done calling "+fm ); } - */ } @@ -2571,28 +2794,35 @@ public class OwnershipGraph { HeapRegionNode hrn, ReferenceEdge edge, ReachabilitySet rules, - Hashtable paramIndex2rewrite_d, - Hashtable paramIndex2rewriteD, - TokenTuple p_i, - Hashtable paramToken2paramIndex, - Hashtable paramTokenPlus2paramIndex, - Hashtable paramTokenStar2paramIndex, + Hashtable tokens2states, + Hashtable paramIndex2rewrite_d_p, + Hashtable paramIndex2rewrite_d_s, + Hashtable paramIndex2rewriteD, + OwnershipGraph ogCallee, boolean makeChangeSet, Hashtable edgePlannedChanges) { assert(hrn == null && edge != null) || (hrn != null && edge == null); - assert rules != null; - assert p_i != null; + assert rules != null; + assert tokens2states != null; + /* ReachabilitySet callerReachabilityCurrent; if( hrn == null ) { callerReachabilityCurrent = edge.getBeta(); } else { callerReachabilityCurrent = hrn.getAlpha(); } - + */ + + //System.out.println( " -------------------------" ); + //System.out.println( " rewriting "+hrn+" with reach: "+hrn.getAlpha() ); + //System.out.println( " and token2states = "+tokens2states ); + //System.out.println( " paramTokenPrimary2paramIndex = "+paramTokenPrimary2paramIndex ); + //System.out.println( " d_p = "+paramIndex2rewrite_d_p ); + ReachabilitySet callerReachabilityNew = new ReachabilitySet().makeCanonical(); // for initializing structures in this method @@ -2603,13 +2833,15 @@ public class OwnershipGraph { // caller-context token tuple sets that were used to generate it Hashtable > rewritten2source = new Hashtable >(); - rewritten2source.put(ttsEmpty, new HashSet() ); - + rewritten2source.put( ttsEmpty, new HashSet() ); + Iterator rulesItr = rules.iterator(); while(rulesItr.hasNext()) { TokenTupleSet rule = rulesItr.next(); + //System.out.println( " rule is "+rule ); + ReachabilitySet rewrittenRule = new ReachabilitySet(ttsEmpty).makeCanonical(); Iterator ruleItr = rule.iterator(); @@ -2618,41 +2850,58 @@ public class OwnershipGraph { // compute the possibilities for rewriting this callee token ReachabilitySet ttCalleeRewrites = null; - boolean callerSourceUsed = false; + boolean callerSourceUsed = false; + + if( tokens2states.containsKey( ttCallee ) ) { + // there are states for this token passed in + //ttCalleeRewrites = callerReachabilityCurrent; + //System.out.print( " using token2states, " ); - if( ttCallee.equals(p_i) ) { - // replace the arity-one token of the current parameter with the reachability - // information from the caller edge - ttCalleeRewrites = callerReachabilityCurrent; callerSourceUsed = true; + ttCalleeRewrites = tokens2states.get( ttCallee ); + assert ttCalleeRewrites != null; + + } else if( ogCallee.paramTokenPrimary2paramIndex.containsKey( ttCallee ) ) { + // use little d_p + //System.out.print( " using d_p, " ); + + Integer paramIndex_j = ogCallee.paramTokenPrimary2paramIndex.get( ttCallee ); + assert paramIndex_j != null; + ttCalleeRewrites = paramIndex2rewrite_d_p.get( paramIndex_j ); + assert ttCalleeRewrites != null; + + } else if( ogCallee.paramTokenSecondary2paramIndex.containsKey( ttCallee ) ) { + // use little d_s + //System.out.print( " using d_s, " ); - } else if( paramToken2paramIndex.containsKey(ttCallee) ) { - // use little d - Integer paramIndex_j = paramToken2paramIndex.get(ttCallee); - assert paramIndex_j != null; - ttCalleeRewrites = paramIndex2rewrite_d.get(paramIndex_j); + Integer paramIndex_j = ogCallee.paramTokenSecondary2paramIndex.get( ttCallee ); + assert paramIndex_j != null; + ttCalleeRewrites = paramIndex2rewrite_d_s.get( paramIndex_j ); assert ttCalleeRewrites != null; - } else if( paramTokenPlus2paramIndex.containsKey(ttCallee) ) { + } else if( ogCallee.paramTokenSecondaryPlus2paramIndex.containsKey( ttCallee ) ) { // worse, use big D - Integer paramIndex_j = paramTokenPlus2paramIndex.get(ttCallee); - assert paramIndex_j != null; - ttCalleeRewrites = paramIndex2rewriteD.get(paramIndex_j); + Integer paramIndex_j = ogCallee.paramTokenSecondaryPlus2paramIndex.get( ttCallee ); + assert paramIndex_j != null; + ttCalleeRewrites = paramIndex2rewriteD.get( paramIndex_j ); assert ttCalleeRewrites != null; - } else if( paramTokenStar2paramIndex.containsKey(ttCallee) ) { + } else if( ogCallee.paramTokenSecondaryStar2paramIndex.containsKey( ttCallee ) ) { // worse, use big D - Integer paramIndex_j = paramTokenStar2paramIndex.get(ttCallee); - assert paramIndex_j != null; - ttCalleeRewrites = paramIndex2rewriteD.get(paramIndex_j); + Integer paramIndex_j = ogCallee.paramTokenSecondaryStar2paramIndex.get( ttCallee ); + assert paramIndex_j != null; + ttCalleeRewrites = paramIndex2rewriteD.get( paramIndex_j ); assert ttCalleeRewrites != null; } else { // otherwise there's no need for a rewrite, just pass this one on - TokenTupleSet ttsCaller = new TokenTupleSet(ttCallee).makeCanonical(); - ttCalleeRewrites = new ReachabilitySet(ttsCaller).makeCanonical(); + //System.out.print( " just pass, " ); + TokenTupleSet ttsCaller = new TokenTupleSet( ttCallee ).makeCanonical(); + ttCalleeRewrites = new ReachabilitySet( ttsCaller ).makeCanonical(); } + //System.out.println( " "+ttCallee+" to "+ttCalleeRewrites ); + // branch every version of the working rewritten rule with // the possibilities for rewriting the current callee token ReachabilitySet rewrittenRuleWithTTCallee = new ReachabilitySet().makeCanonical(); @@ -2665,29 +2914,29 @@ public class OwnershipGraph { while( ttCalleeRewritesItr.hasNext() ) { TokenTupleSet ttsBranch = ttCalleeRewritesItr.next(); - TokenTupleSet ttsRewrittenNext = ttsRewritten.unionUpArity(ttsBranch); + TokenTupleSet ttsRewrittenNext = ttsRewritten.unionUpArity( ttsBranch ); if( makeChangeSet ) { // in order to keep the list of source token tuple sets // start with the sets used to make the partially rewritten // rule up to this point - HashSet sourceSets = rewritten2source.get(ttsRewritten); + HashSet sourceSets = rewritten2source.get( ttsRewritten ); assert sourceSets != null; // make a shallow copy for possible modification - sourceSets = (HashSet)sourceSets.clone(); + sourceSets = (HashSet) sourceSets.clone(); // if we used something from the caller to rewrite it, remember if( callerSourceUsed ) { - sourceSets.add(ttsBranch); + sourceSets.add( ttsBranch ); } // set mapping for the further rewritten rule - rewritten2source.put(ttsRewrittenNext, sourceSets); + rewritten2source.put( ttsRewrittenNext, sourceSets ); } rewrittenRuleWithTTCallee = - rewrittenRuleWithTTCallee.union(ttsRewrittenNext); + rewrittenRuleWithTTCallee.union( ttsRewrittenNext ); } } @@ -2699,7 +2948,7 @@ public class OwnershipGraph { // the rule has been entirely rewritten into the caller context // now, so add it to the new reachability information callerReachabilityNew = - callerReachabilityNew.union(rewrittenRule); + callerReachabilityNew.union( rewrittenRule ); } if( makeChangeSet ) { @@ -2710,7 +2959,7 @@ public class OwnershipGraph { Iterator callerReachabilityItr = callerReachabilityNew.iterator(); while( callerReachabilityItr.hasNext() ) { TokenTupleSet ttsRewrittenFinal = callerReachabilityItr.next(); - HashSet sourceSets = rewritten2source.get(ttsRewrittenFinal); + HashSet sourceSets = rewritten2source.get( ttsRewrittenFinal ); assert sourceSets != null; Iterator sourceSetsItr = sourceSets.iterator(); @@ -2718,19 +2967,21 @@ public class OwnershipGraph { TokenTupleSet ttsSource = sourceSetsItr.next(); callerChangeSet = - callerChangeSet.union(new ChangeTuple(ttsSource, ttsRewrittenFinal) ); + callerChangeSet.union( new ChangeTuple( ttsSource, ttsRewrittenFinal ) ); } } assert edgePlannedChanges != null; - edgePlannedChanges.put(edge, callerChangeSet); + edgePlannedChanges.put( edge, callerChangeSet ); } if( hrn == null ) { - edge.setBetaNew(edge.getBetaNew().union(callerReachabilityNew) ); + edge.setBetaNew( edge.getBetaNew().union( callerReachabilityNew ) ); } else { - hrn.setAlphaNew(hrn.getAlphaNew().union(callerReachabilityNew) ); + hrn.setAlphaNew( hrn.getAlphaNew().union( callerReachabilityNew ) ); } + + //System.out.println( " -------------------------" ); } @@ -3255,26 +3506,42 @@ public class OwnershipGraph { paramTokenPrimary2paramIndex = og.paramTokenPrimary2paramIndex; paramIndex2paramTokenPrimary = og.paramIndex2paramTokenPrimary; - paramTokenPrimaryPlus2paramIndex = og.paramTokenPrimaryPlus2paramIndex; - paramIndex2paramTokenPrimaryPlus = og.paramIndex2paramTokenPrimaryPlus; - paramTokenPrimaryStar2paramIndex = og.paramTokenPrimaryStar2paramIndex; - paramIndex2paramTokenPrimaryStar = og.paramIndex2paramTokenPrimaryStar; paramTokenSecondary2paramIndex = og.paramTokenSecondary2paramIndex; paramIndex2paramTokenSecondary = og.paramIndex2paramTokenSecondary; paramTokenSecondaryPlus2paramIndex = og.paramTokenSecondaryPlus2paramIndex; paramIndex2paramTokenSecondaryPlus = og.paramIndex2paramTokenSecondaryPlus; paramTokenSecondaryStar2paramIndex = og.paramTokenSecondaryStar2paramIndex; - paramIndex2paramTokenSecondaryStar = og.paramIndex2paramTokenSecondaryStar; - + paramIndex2paramTokenSecondaryStar = og.paramIndex2paramTokenSecondaryStar; + return; } if( og.idPrimary2paramIndexSet.size() == 0 ) { + + og.idPrimary2paramIndexSet = idPrimary2paramIndexSet; + og.paramIndex2idPrimary = paramIndex2idPrimary; + + og.idSecondary2paramIndexSet = idSecondary2paramIndexSet; + og.paramIndex2idSecondary = paramIndex2idSecondary; + + og.paramIndex2tdQ = paramIndex2tdQ; + og.paramIndex2tdR = paramIndex2tdR; + + og.paramTokenPrimary2paramIndex = paramTokenPrimary2paramIndex; + og.paramIndex2paramTokenPrimary = paramIndex2paramTokenPrimary; + + og.paramTokenSecondary2paramIndex = paramTokenSecondary2paramIndex; + og.paramIndex2paramTokenSecondary = paramIndex2paramTokenSecondary; + og.paramTokenSecondaryPlus2paramIndex = paramTokenSecondaryPlus2paramIndex; + og.paramIndex2paramTokenSecondaryPlus = paramIndex2paramTokenSecondaryPlus; + og.paramTokenSecondaryStar2paramIndex = paramTokenSecondaryStar2paramIndex; + og.paramIndex2paramTokenSecondaryStar = paramIndex2paramTokenSecondaryStar; + return; } - assert idPrimary2paramIndexSet.size() == og.idPrimary2paramIndexSet.size(); + assert idPrimary2paramIndexSet.size() == og.idPrimary2paramIndexSet.size(); assert idSecondary2paramIndexSet.size() == og.idSecondary2paramIndexSet.size(); } diff --git a/Robust/src/Tests/OwnershipAnalysisTest/test07/makefile b/Robust/src/Tests/OwnershipAnalysisTest/test07/makefile new file mode 100644 index 00000000..fdfcf351 --- /dev/null +++ b/Robust/src/Tests/OwnershipAnalysisTest/test07/makefile @@ -0,0 +1,27 @@ +PROGRAM=test + +SOURCE_FILES=$(PROGRAM).java + +BUILDSCRIPT=~/research/Robust/src/buildscript +BSFLAGS= -mainclass Test -justanalyze -ownership -ownallocdepth 1 -ownwritedots final -ownaliasfile aliases.txt -enable-assertions + +all: $(PROGRAM).bin + +view: PNGs + eog *.png & + +PNGs: DOTs + d2p *COMPLETE*.dot + +DOTs: $(PROGRAM).bin + +$(PROGRAM).bin: $(SOURCE_FILES) + $(BUILDSCRIPT) $(BSFLAGS) -o $(PROGRAM) $(SOURCE_FILES) + +clean: + rm -f $(PROGRAM).bin + rm -fr tmpbuilddirectory + rm -f *~ + rm -f *.dot + rm -f *.png + rm -f aliases.txt diff --git a/Robust/src/Tests/OwnershipAnalysisTest/test07/test.java b/Robust/src/Tests/OwnershipAnalysisTest/test07/test.java new file mode 100644 index 00000000..70227dd5 --- /dev/null +++ b/Robust/src/Tests/OwnershipAnalysisTest/test07/test.java @@ -0,0 +1,25 @@ +public class Foo { + public Foo() {} + + public Bar b; +} + +public class Bar { + public Bar() {} +} + +public class Test { + + static public void main( String[] args ) { + Foo x = disjoint foo new Foo(); + Bar y = disjoint bar new Bar(); + + x.b = y; + + virginia( x, y ); + } + + static public void virginia( Foo x, Bar y ) { + //x.b = y; + } +}