import Analysis.ArrayReferencees;
import Analysis.OoOJava.Accessible;
import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.FlatIRGraph.*;
import IR.*;
import IR.Flat.*;
import IR.Tree.Modifiers;
);
TempDescriptor cmdLineArgs =
- new TempDescriptor("args",
+ new TempDescriptor("analysisEntryTemp_args",
mdSourceEntry.getParamType(0)
);
- FlatNew fn =
+ FlatNew fnArgs =
new FlatNew(mdSourceEntry.getParamType(0),
cmdLineArgs,
false // is global
);
- this.constructedCmdLineArgsNew = fn;
+ this.constructedCmdLineArgsNew = fnArgs;
+
+
+ // jjenista - we might want to model more of the initial context
+ // someday, so keep this trickery in that case. For now, this analysis
+ // ignores immutable types which includes String, so the following flat
+ // nodes will not add anything to the reach graph.
+ //
+ //TempDescriptor anArg =
+ // new TempDescriptor("analysisEntryTemp_arg",
+ // mdSourceEntry.getParamType(0).dereference()
+ // );
+ //
+ //FlatNew fnArg =
+ // new FlatNew(mdSourceEntry.getParamType(0).dereference(),
+ // anArg,
+ // false // is global
+ // );
+ //
+ //TempDescriptor index =
+ // new TempDescriptor("analysisEntryTemp_index",
+ // new TypeDescriptor(TypeDescriptor.INT)
+ // );
+ //
+ //FlatLiteralNode fl =
+ // new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),
+ // new Integer( 0 ),
+ // index
+ // );
+ //
+ //FlatSetElementNode fse =
+ // new FlatSetElementNode(cmdLineArgs,
+ // index,
+ // anArg
+ // );
+
TempDescriptor[] sourceEntryArgs = new TempDescriptor[1];
sourceEntryArgs[0] = cmdLineArgs;
fe
);
- this.fmAnalysisEntry.addNext(fn);
- fn.addNext(fc);
+ this.fmAnalysisEntry.addNext(fnArgs);
+ fnArgs.addNext(fc);
fc.addNext(frn);
frn.addNext(fe);
}
return null;
}
- return rgAtEnter.canPointTo( x, f.getSymbol() );
+ return rgAtEnter.canPointTo( x, f.getSymbol(), f.getType() );
}
assert x.getType() != null;
assert x.getType().isArray();
- return rgAtEnter.canPointTo( x, arrayElementFieldName );
+ return rgAtEnter.canPointTo( x, arrayElementFieldName, x.getType().dereference() );
}
}
// a field or element dereference you get a hashtable
// where the keys are allocs for the variables and the
// values are from following the second hop
+ // NOTE: if the set of Alloc's that something can point
+ // to is DONTCARE, this will mean "the analysis doesn't care
+ // what it points to" so the client shouldn't either, NOT
+ // interpreting it as "it can't point to anything." The
+ // meaning "it can't point to anything" will be represented
+ // by an empty set of Alloc.
+ static public final Set<Alloc> DONTCARE_PTR = new HashSet<Alloc>();
+ static public final Hashtable< Alloc, Set<Alloc> > DONTCARE_DREF = new Hashtable< Alloc, Set<Alloc> >();
+
public Set<Alloc> canPointToAt( TempDescriptor x,
FlatNode programPoint );
public Set<Alloc> canPointTo( TempDescriptor x ) {
- VariableNode vn = getVariableNodeNoMutation( x );
- if( vn == null ) {
- return null;
+
+ if( !DisjointAnalysis.shouldAnalysisTrack( x.getType() ) ) {
+ // if we don't care to track it, return null which means
+ // "a client of this result shouldn't care either"
+ return HeapAnalysis.DONTCARE_PTR;
}
Set<Alloc> out = new HashSet<Alloc>();
+ VariableNode vn = getVariableNodeNoMutation( x );
+ if( vn == null ) {
+ // the empty set means "can't point to anything"
+ return out;
+ }
+
Iterator<RefEdge> edgeItr = vn.iteratorToReferencees();
while( edgeItr.hasNext() ) {
HeapRegionNode hrn = edgeItr.next().getDst();
-
out.add( hrn.getAllocSite() );
}
public Hashtable< Alloc, Set<Alloc> > canPointTo( TempDescriptor x,
- String field ) {
+ String field,
+ TypeDescriptor fieldType ) {
+
+ if( !DisjointAnalysis.shouldAnalysisTrack( x.getType() ) ) {
+ // if we don't care to track it, return null which means
+ // "a client of this result shouldn't care either"
+ return HeapAnalysis.DONTCARE_DREF;
+ }
+
+ Hashtable< Alloc, Set<Alloc> > out = new Hashtable< Alloc, Set<Alloc> >();
VariableNode vn = getVariableNodeNoMutation( x );
if( vn == null ) {
- return null;
+ // the empty set means "can't point to anything"
+ return out;
}
- Hashtable< Alloc, Set<Alloc> > out = new Hashtable< Alloc, Set<Alloc> >();
Iterator<RefEdge> edgeItr = vn.iteratorToReferencees();
while( edgeItr.hasNext() ) {
HeapRegionNode hrn = edgeItr.next().getDst();
+ Alloc key = hrn.getAllocSite();
- Alloc key = hrn.getAllocSite();
+ if( !DisjointAnalysis.shouldAnalysisTrack( fieldType ) ) {
+ // if we don't care to track it, put no entry which means
+ // "a client of this result shouldn't care either"
+ out.put( key, HeapAnalysis.DONTCARE_PTR );
+ continue;
+ }
Set<Alloc> moreValues = new HashSet<Alloc>();
Iterator<RefEdge> edgeItr2 = hrn.iteratorToReferencees();
TempDescriptor x,
Set<Alloc> targetsByAnalysis ) {
+ assert targetsByAnalysis != null;
+
+
output.println( "" );
output.println( "// asserts vs. heap results (DEBUG)" );
- if( targetsByAnalysis == null ||
- targetsByAnalysis.isEmpty() ) {
+
+ if( targetsByAnalysis == HeapAnalysis.DONTCARE_PTR ) {
+ output.println( "// ANALYSIS DIDN'T CARE WHAT "+x+" POINTS-TO" );
+ return;
+ }
+
+
+ if( targetsByAnalysis.isEmpty() ) {
output.println( "assert( "+
buildCode.generateTemp( context, x )+
" == NULL );\n" );
FieldDescriptor f, // this null OR
TempDescriptor i, // this null
Hashtable< Alloc, Set<Alloc> > targetsByAnalysis ) {
-
+ assert targetsByAnalysis != null;
+
assert f == null || i == null;
output.println( "// asserts vs. heap results (DEBUG)" );
+
+
+ if( targetsByAnalysis == HeapAnalysis.DONTCARE_DREF ) {
+ output.println( "// ANALYSIS DIDN'T CARE WHAT "+x+" POINTS-TO" );
+ return;
+ }
+
- if( targetsByAnalysis == null ||
- targetsByAnalysis.isEmpty() ) {
+ if( targetsByAnalysis.isEmpty() ) {
output.println( "assert( "+
buildCode.generateTemp( context, x )+
" == NULL );\n" );
output.print( "case "+
k.getUniqueAllocSiteID()+
- ": assert( allocsiteOneHop == -1" );
-
+ ":" );
+
Set<Alloc> hopTargets = targetsByAnalysis.get( k );
- if( hopTargets != null ) {
+ if( hopTargets == HeapAnalysis.DONTCARE_PTR ) {
+ output.print( "/* ANALYSIS DOESN'T CARE */" );
+
+ } else {
+ output.print( "assert( allocsiteOneHop == -1" );
if( !hopTargets.isEmpty() ) {
output.print( " || " );
output.print( " || " );
}
}
+
+ output.print( " );" );
}
- output.println( " ); break;" );
+ output.println( " break;" );
}
output.println( " default: assert( 0 ); break;" );