import Analysis.CallGraph.*;
import IR.*;
import IR.Flat.*;
+import IR.Tree.Modifiers;
import java.util.*;
import java.io.*;
// should be re-added to this set
private HashSet<Descriptor> descriptorsToVisit;
+ // a special field descriptor for all array elements
+ private static FieldDescriptor fdElement = new FieldDescriptor(new Modifiers(Modifiers.PUBLIC),
+ new TypeDescriptor( "Array[]" ),
+ "elements",
+ null,
+ false);
// this analysis generates an ownership graph for every task
rhs = fsfn.getSrc();
og.assignTempXFieldFEqualToTempY(lhs, fld, rhs);
break;
+
+ case FKind.FlatElementNode:
+ FlatElementNode fen = (FlatElementNode) fn;
+ lhs = fen.getDst();
+ rhs = fen.getSrc();
+ if( !lhs.getType().isPrimitive() ) {
+ og.assignTempXEqualToTempYFieldF(lhs, rhs, fdElement);
+ }
+ break;
+
+ case FKind.FlatSetElementNode:
+ FlatSetElementNode fsen = (FlatSetElementNode) fn;
+ lhs = fsen.getDst();
+ rhs = fsen.getSrc();
+ if( !rhs.getType().isPrimitive() ) {
+ og.assignTempXFieldFEqualToTempY(lhs, fdElement, rhs);
+ }
+ break;
case FKind.FlatNew:
FlatNew fnn = (FlatNew) fn;
-
-
-
// return just the allocation site associated with one FlatNew node
private AllocationSite getAllocationSiteFromFlatNewPRIVATE(FlatNew fn) {
// actions to take during the traversal
protected static final int VISIT_HRN_WRITE_FULL = 0;
+ protected static TempDescriptor tdReturn = new TempDescriptor("_Return___");
+
public Hashtable<Integer, HeapRegionNode> id2hrn;
public Hashtable<TempDescriptor, LabelNode > td2ln;
public HashSet<AllocationSite> allocationSites;
- protected static TempDescriptor tdReturn = new TempDescriptor("_Return___");
public OwnershipGraph(int allocationDepth) {
public void assignTempXEqualToTempYFieldF(TempDescriptor x,
TempDescriptor y,
FieldDescriptor f) {
-
LabelNode lnX = getLabelNodeFromTemp(x);
LabelNode lnY = getLabelNodeFromTemp(y);
public void assignTempXFieldFEqualToTempY(TempDescriptor x,
FieldDescriptor f,
TempDescriptor y) {
-
LabelNode lnX = getLabelNodeFromTemp(x);
LabelNode lnY = getLabelNodeFromTemp(y);
// return value may need to be assigned in caller
if( fc.getReturnTemp() != null ) {
- HashSet<HeapRegionNode> assignCallerRhs = new HashSet<HeapRegionNode>();
+ LabelNode lnLhsCaller = getLabelNodeFromTemp(fc.getReturnTemp() );
+ clearReferenceEdgesFrom(lnLhsCaller, null, true);
LabelNode lnReturnCallee = ogCallee.getLabelNodeFromTemp(tdReturn);
Iterator<ReferenceEdge> edgeCalleeItr = lnReturnCallee.iteratorToReferencees();
while( edgeCalleeItr.hasNext() ) {
ReferenceEdge edgeCallee = edgeCalleeItr.next();
- HashSet<HeapRegionNode> possibleCallerHRNs =
+ ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge(null,
+ null,
+ edgeCallee.getFieldDesc(),
+ false,
+ toShadowTokens(ogCallee, edgeCallee.getBeta() )
+ );
+ rewriteCallerEdgeBeta(fm.numParameters(),
+ bogusIndex,
+ edgeNewInCallerTemplate,
+ paramIndex2rewriteJ,
+ paramIndex2rewriteD,
+ paramIndex2paramToken,
+ paramIndex2paramTokenStar,
+ false,
+ null);
+
+ edgeNewInCallerTemplate.applyBetaNew();
+
+
+ HashSet<HeapRegionNode> assignCallerRhs =
getHRNSetThatPossiblyMapToCalleeHRN(ogCallee,
edgeCallee.getDst(),
false,
paramIndex2reachableCallerNodes);
- assignCallerRhs.addAll(possibleCallerHRNs);
- }
-
- LabelNode lnLhsCaller = getLabelNodeFromTemp(fc.getReturnTemp() );
- clearReferenceEdgesFrom(lnLhsCaller, null, true);
-
- Iterator<HeapRegionNode> itrHrn = assignCallerRhs.iterator();
- while( itrHrn.hasNext() ) {
- HeapRegionNode hrnCaller = itrHrn.next();
-
- ReferenceEdge edgeNew = new ReferenceEdge(lnLhsCaller,
- hrnCaller,
- null,
- false,
- new ReachabilitySet().makeCanonical()
- );
-
- addReferenceEdge(lnLhsCaller, hrnCaller, edgeNew);
+ Iterator<HeapRegionNode> itrHrn = assignCallerRhs.iterator();
+ while( itrHrn.hasNext() ) {
+ HeapRegionNode hrnCaller = itrHrn.next();
+
+ ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
+ edgeNewInCaller.setSrc(lnLhsCaller);
+ edgeNewInCaller.setDst(hrnCaller);
+
+ ReferenceEdge edgeExisting = lnLhsCaller.getReferenceTo(hrnCaller, edgeNewInCaller.getFieldDesc() );
+ if( edgeExisting == null ) {
+ // if this edge doesn't exist in the caller, create it
+ addReferenceEdge(lnLhsCaller, hrnCaller, edgeNewInCaller);
+ } else {
+ // if it already exists, merge with it
+ edgeExisting.setBeta(edgeExisting.getBeta().union(edgeNewInCaller.getBeta() ) );
+ }
+ }
}
}
mergeIntoSummary(hrnSummaryShadow, hrnSummary);
+ // then clear off after merge
+ clearReferenceEdgesFrom(hrnSummaryShadow, null, true);
+ clearReferenceEdgesTo(hrnSummaryShadow, null, true);
+ hrnSummaryShadow.setAlpha(new ReachabilitySet().makeCanonical() );
+
// then transplant shadow nodes onto the now clean normal nodes
for( int i = 0; i < as.getAllocationDepth(); ++i ) {
public class Parameter {
- flag w;
- Node root;
- public Parameter() {}
+ flag w;
+ Node root;
+ public Parameter() {}
}
public class Node {
- HashSet neighbors;
-
- public Node() {
- neighbors = new HashSet();
- }
-
- public static Node makeNode() {
- return new Node();
- }
-
- public addNeighbor( Node n ) {
- neighbors.add( n );
- }
+ HashSet neighbors;
+
+ public Node() {
+ neighbors = new HashSet();
+ }
+
+ public static Node makeNode() {
+ return new Node();
+ }
+
+ public addNeighbor( Node n ) {
+ neighbors.add( n );
+ }
}
task Startup( StartupObject s{ initialstate } ) {
-
- Parameter p1 = new Parameter();
-
- taskexit( s{ !initialstate } );
+
+ Parameter p1 = new Parameter();
+
+ taskexit( s{ !initialstate } );
}
task MakeGraph( Parameter p1{ !w } ) {
+ while( false ) {
+ Parameter p2 = new Parameter();
+
Node n1 = Node.makeNode();
Node n2 = Node.makeNode();
Node n3 = Node.makeNode();
-
+
n1.addNeighbor( n2 );
n2.addNeighbor( n3 );
n3.addNeighbor( n1 );
+
+ p2.root = n1;
+ }
- p1.root = n1;
-
-
- taskexit( p1{ w } );
+ taskexit( p1{ w } );
}