From: jjenista Date: Thu, 11 Mar 2010 20:08:50 +0000 (+0000) Subject: caller local variables to in-context regions are modeled as out-of-context edges... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=21d9fc5d50b0d45094a62252b5ad8e96c4967869;p=IRC.git caller local variables to in-context regions are modeled as out-of-context edges in callee to preserve info, then matched in call site transform. This approach is running and stable, but the answer doesn't look right with respect to the age of nodes in caller --- diff --git a/Robust/src/Analysis/Disjoint/ExistPred.java b/Robust/src/Analysis/Disjoint/ExistPred.java index c008a842..88267e1d 100644 --- a/Robust/src/Analysis/Disjoint/ExistPred.java +++ b/Robust/src/Analysis/Disjoint/ExistPred.java @@ -56,6 +56,8 @@ public class ExistPred extends Canonical { // satisfied when the edge exists AND it has the state. // the source of an edge is *either* a variable // node or a heap region node + protected boolean e_srcOutContext; + protected TempDescriptor e_tdSrc; protected Integer e_hrnSrcID; @@ -85,6 +87,7 @@ public class ExistPred extends Canonical { e_hrnDstID = null; e_type = null; e_field = null; + e_srcOutContext = false; } // node predicates @@ -108,6 +111,7 @@ public class ExistPred extends Canonical { e_hrnDstID = null; e_type = null; e_field = null; + e_srcOutContext = false; } // edge predicates @@ -116,14 +120,16 @@ public class ExistPred extends Canonical { Integer hrnDstID, TypeDescriptor type, String field, - ReachState state ) { + ReachState state, + boolean srcOutContext ) { ExistPred out = new ExistPred( tdSrc, hrnSrcID, hrnDstID, type, field, - state ); + state, + srcOutContext ); out = (ExistPred) Canonical.makeCanonical( out ); return out; @@ -134,7 +140,8 @@ public class ExistPred extends Canonical { Integer hrnDstID, TypeDescriptor type, String field, - ReachState state ) { + ReachState state, + boolean srcOutContext ) { assert (tdSrc == null) || (hrnSrcID == null); assert hrnDstID != null; @@ -143,7 +150,8 @@ public class ExistPred extends Canonical { // fields can be null when the edge is from // a variable node to a heap region! // assert field != null; - + this.e_srcOutContext = srcOutContext; + this.e_tdSrc = tdSrc; this.e_hrnSrcID = hrnSrcID; this.e_hrnDstID = hrnDstID; @@ -215,7 +223,10 @@ public class ExistPred extends Canonical { if( vnSrc != null ) { rsn = vnSrc; } else { - if( !calleeReachableNodes.contains( e_hrnSrcID ) ) { + if( !calleeReachableNodes.contains( e_hrnSrcID ) && !e_srcOutContext ) { + return null; + } + if( calleeReachableNodes.contains( e_hrnSrcID ) && e_srcOutContext ) { return null; } rsn = hrnSrc; @@ -332,6 +343,10 @@ public class ExistPred extends Canonical { return false; } + // if the identifiers match, this should + // always match + assert e_srcOutContext == pred.e_srcOutContext; + return true; } @@ -401,6 +416,10 @@ public class ExistPred extends Canonical { s += e_hrnSrcID.toString(); } + if( e_srcOutContext ) { + s += "(ooc)"; + } + s += "-->"+e_hrnDstID+")"; if( ne_state != null ) { diff --git a/Robust/src/Analysis/Disjoint/ReachGraph.java b/Robust/src/Analysis/Disjoint/ReachGraph.java index 9c838529..7f75a6bf 100644 --- a/Robust/src/Analysis/Disjoint/ReachGraph.java +++ b/Robust/src/Analysis/Disjoint/ReachGraph.java @@ -1419,7 +1419,8 @@ public class ReachGraph { hrnDstID, reCaller.getType(), reCaller.getField(), - null ); + null, + rsnCaller instanceof VariableNode ); // out-of-context ExistPredSet preds = ExistPredSet.factory( pred ); @@ -1468,10 +1469,15 @@ public class ReachGraph { TypeDescriptor oocNodeType; ReachSet oocReach; + TempDescriptor oocPredSrcTemp = null; + Integer oocPredSrcID = null; + if( rsnCallerAndOutContext instanceof VariableNode ) { // variables are always out-of-context oocNodeType = null; oocReach = rsetEmpty; + oocPredSrcTemp = + ((VariableNode)rsnCallerAndOutContext).getTempDescriptor(); } else { @@ -1484,10 +1490,25 @@ public class ReachGraph { continue; } - oocNodeType = hrnCallerAndOutContext.getType(); - oocReach = hrnCallerAndOutContext.getAlpha(); + oocNodeType = hrnCallerAndOutContext.getType(); + oocReach = hrnCallerAndOutContext.getAlpha(); + oocPredSrcID = hrnCallerAndOutContext.getID(); } + // if we're here we've found an out-of-context edge + + ExistPred pred = + ExistPred.factory( oocPredSrcTemp, + oocPredSrcID, + hrnID, + edgeMightCross.getType(), + edgeMightCross.getField(), + null, + true ); // out-of-context + + ExistPredSet preds = + ExistPredSet.factory( pred ); + HeapRegionNode hrnCalleeAndInContext = rg.id2hrn.get( hrnCallerAndInContext.getID() ); @@ -1528,7 +1549,7 @@ public class ReachGraph { null, // alloc site, shouldn't be used /*toShadowTokens( this,*/ oocReach /*)*/, // inherent /*toShadowTokens( this,*/ oocReach /*)*/, // alpha - predsEmpty, + preds, "out-of-context" ); @@ -1545,7 +1566,7 @@ public class ReachGraph { null, // alloc site, shouldn't be used /*toShadowTokens( this,*/ oocReach /*)*/, // inherent /*toShadowTokens( this,*/ oocReach /*)*/, // alpha - predsEmpty, + preds, "out-of-context" ); } @@ -1557,7 +1578,7 @@ public class ReachGraph { edgeMightCross.getType(), edgeMightCross.getField(), /*toShadowTokens( this,*/ edgeMightCross.getBeta() /*)*/, - predsEmpty + preds ) ); @@ -1785,19 +1806,35 @@ public class ReachGraph { } - // 3.b) callee -> callee edges + // 3.b) callee -> callee edges AND out-of-context -> callee satisItr = calleeEdgesSatisfied.entrySet().iterator(); while( satisItr.hasNext() ) { Map.Entry me = (Map.Entry) satisItr.next(); RefEdge reCallee = (RefEdge) me.getKey(); ExistPredSet preds = (ExistPredSet) me.getValue(); - RefSrcNode rsnCallee = reCallee.getSrc(); - RefSrcNode rsnCaller; + RefSrcNode rsnCallee = reCallee.getSrc(); + HeapRegionNode hrnDstCallee = reCallee.getDst(); + + // even though we don't know yet what we're doing with + // this edge, do this translation from callee dst to + // caller dst a little early so we can use the result + // for out-of-context matching below + AllocSite asDst = + hrnDstCallee.getAllocSite(); + Integer hrnIDDstShadow = + asDst.getShadowIDfromID( hrnDstCallee.getID() ); + HeapRegionNode hrnDstCaller = + id2hrn.get( hrnIDDstShadow ); + + // we'll find the set of sources in the caller that + // this callee source could be (out-of-context node + // can potentially map to multiple caller nodes) + Set rsnCallers = new HashSet(); if( rsnCallee instanceof VariableNode ) { - continue; - /* + // variable -> node in the callee should only + // come into the caller if its from a param var VariableNode vnCallee = (VariableNode) rsnCallee; TempDescriptor tdParam = vnCallee.getTempDescriptor(); TempDescriptor tdArg = fc.getArgMatchingParam( fm, @@ -1807,75 +1844,107 @@ public class ReachGraph { // to the callee so we ignore it in call site transfer continue; } - - System.out.println( "going with "+tdParam+" to "+tdArg ); - rsnCaller = this.getVariableNodeFromTemp( tdArg ); - */ + rsnCallers.add( this.getVariableNodeFromTemp( tdArg ) ); + } else { HeapRegionNode hrnSrcCallee = (HeapRegionNode) reCallee.getSrc(); + + if( !hrnSrcCallee.isOutOfContext() ) { + AllocSite asSrc = hrnSrcCallee.getAllocSite(); + allocSites.add( asSrc ); + + Integer hrnIDSrcShadow = asSrc.getShadowIDfromID( hrnSrcCallee.getID() ); + rsnCallers.add( id2hrn.get( hrnIDSrcShadow ) ); - AllocSite asSrc = hrnSrcCallee.getAllocSite(); - allocSites.add( asSrc ); - - Integer hrnIDSrcShadow = asSrc.getShadowIDfromID( hrnSrcCallee.getID() ); - rsnCaller = id2hrn.get( hrnIDSrcShadow ); + } else { + // for out-of-context sources we have to find all + // caller sources that might match + assert hrnDstCaller != null; + + Iterator reItr = hrnDstCaller.iteratorToReferencers(); + while( reItr.hasNext() ) { + // the edge and field (either possibly null) must match + RefEdge reCaller = reItr.next(); + if( !reCaller.typeEquals ( reCallee.getType() ) || + !reCaller.fieldEquals( reCallee.getField() ) + ) { + continue; + } + + RefSrcNode rsnCaller = reCaller.getSrc(); + if( rsnCaller instanceof VariableNode ) { + // a variable node matches an OOC region with null type + if( hrnSrcCallee.getType() != null ) { + continue; + } + + } else { + // otherwise types should match + HeapRegionNode hrnCallerSrc = (HeapRegionNode) rsnCaller; + if( !hrnSrcCallee.getType().equals( hrnCallerSrc.getType() ) ) { + continue; + } + } + + // it matches, add to sources of edges to make + rsnCallers.add( rsnCaller ); + } + } } - assert rsnCaller != null; - - HeapRegionNode hrnDstCallee = reCallee.getDst(); + assert !rsnCallers.isEmpty(); - AllocSite asDst = hrnDstCallee.getAllocSite(); allocSites.add( asDst ); - Integer hrnIDDstShadow = asDst.getShadowIDfromID( hrnDstCallee.getID() ); - - HeapRegionNode hrnDstCaller = id2hrn.get( hrnIDDstShadow ); assert hrnDstCaller != null; - // TODO: beta rewrites - RefEdge reCaller = new RefEdge( rsnCaller, - hrnDstCaller, - reCallee.getType(), - reCallee.getField(), - rsetEmpty, - preds - ); - - // look to see if an edge with same field exists - // and merge with it, otherwise just add the edge - RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller, - reCallee.getType(), - reCallee.getField() - ); - if( edgeExisting != null ) { - edgeExisting.setBeta( - Canonical.union( edgeExisting.getBeta(), - reCaller.getBeta() - ) - ); - edgeExisting.setPreds( - Canonical.join( edgeExisting.getPreds(), - reCaller.getPreds() - ) - ); - - } else { - addRefEdge( rsnCaller, hrnDstCaller, reCaller ); + Iterator rsnItr = rsnCallers.iterator(); + while( rsnItr.hasNext() ) { + RefSrcNode rsnCaller = rsnItr.next(); + + // TODO: beta rewrites + RefEdge reCaller = new RefEdge( rsnCaller, + hrnDstCaller, + reCallee.getType(), + reCallee.getField(), + rsetEmpty, + preds + ); + + // look to see if an edge with same field exists + // and merge with it, otherwise just add the edge + RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller, + reCallee.getType(), + reCallee.getField() + ); + if( edgeExisting != null ) { + edgeExisting.setBeta( + Canonical.union( edgeExisting.getBeta(), + reCaller.getBeta() + ) + ); + edgeExisting.setPreds( + Canonical.join( edgeExisting.getPreds(), + reCaller.getPreds() + ) + ); + + } else { + addRefEdge( rsnCaller, hrnDstCaller, reCaller ); + } } - } + /* if( writeDebugDOTs ) { try { writeGraph( "caller33BeforeResolveOutOfContextEdges", true, false, false, false, true, true ); } catch( IOException e ) {} } - - // 3.c) resolve out-of-context -> callee edges + */ diff --git a/Robust/src/Tests/disjoint/predicateTest2/test.java b/Robust/src/Tests/disjoint/predicateTest2/test.java index da84da30..19e73f4e 100644 --- a/Robust/src/Tests/disjoint/predicateTest2/test.java +++ b/Robust/src/Tests/disjoint/predicateTest2/test.java @@ -12,6 +12,7 @@ public class Test { static public void main( String[] args ) { Foo f1 = new Foo(); + Foo extraVar = f1; addSomething( f1 ); Foo f2 = new Foo();