bw.close();
}
+
+
+ public Alloc getCmdLineArgsAlloc() {
+ return getAllocationSiteFromFlatNew( constructedCmdLineArgsNew );
+ }
///////////////////////////////////////////
//
// end public interface
static protected Hashtable<FlatNode, ReachGraph> fn2rgAtEnter =
new Hashtable<FlatNode, ReachGraph>();
+ static protected Hashtable<FlatNode, ReachGraph> fn2rgAtExit =
+ new Hashtable<FlatNode, ReachGraph>();
+
+
private Hashtable<FlatCall, Descriptor> fc2enclosing;
Accessible accessible;
+
+ // we construct an entry method of flat nodes complete
+ // with a new allocation site to model the command line
+ // args creation just for the analysis, so remember that
+ // allocation site. Later in code gen we might want to
+ // know if something is pointing-to to the cmd line args
+ // and we can verify by checking the allocation site field.
+ protected FlatNew constructedCmdLineArgsNew;
+
+
+
+
// allocate various structures that are not local
// to a single class method--should be done once
protected void allocateStructures() {
System.out.println(" Generating reach graph for program point: "+fgrn.getGraphName() );
+
rg.writeGraph("genReach"+fgrn.getGraphName(),
true, // write labels (variables)
true, // selectively hide intermediate temp vars
mapBackEdgeToMonotone.put(fn, rg);
}
+
+ ReachGraph rgOnExit = new ReachGraph();
+ rgOnExit.merge(rg);
+ fn2rgAtExit.put(fn, rgOnExit);
+
+
// at this point rg should be the correct update
// by an above transfer function, or untouched if
// the flat node type doesn't affect the heap
-
// Take in source entry which is the program's compiled entry and
// create a new analysis entry, a method that takes no parameters
// and appears to allocate the command line arguments and call the
cmdLineArgs,
false // is global
);
+ this.constructedCmdLineArgsNew = fn;
TempDescriptor[] sourceEntryArgs = new TempDescriptor[1];
sourceEntryArgs[0] = cmdLineArgs;
}
}
+
+
+
+ public Set<Alloc> canPointToAt( TempDescriptor x,
+ FlatNode programPoint ) {
+
+ ReachGraph rgAtEnter = fn2rgAtEnter.get( programPoint );
+ if( rgAtEnter == null ) {
+ return null;
+ }
+
+ return rgAtEnter.canPointTo( x );
+ }
+
+
+ public Set<Alloc> canPointToAfter( TempDescriptor x,
+ FlatNode programPoint ) {
+
+ ReachGraph rgAtExit = fn2rgAtExit.get( programPoint );
+ if( rgAtExit == null ) {
+ return null;
+ }
+
+ return rgAtExit.canPointTo( x );
+ }
+
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAt( TempDescriptor x,
+ FieldDescriptor f,
+ FlatNode programPoint ) {
+
+ ReachGraph rgAtEnter = fn2rgAtEnter.get( programPoint );
+ if( rgAtEnter == null ) {
+ return null;
+ }
+
+ return rgAtEnter.canPointTo( x, f.getSymbol() );
+ }
+
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAtElement( TempDescriptor x,
+ FlatNode programPoint ) {
+
+ ReachGraph rgAtEnter = fn2rgAtEnter.get( programPoint );
+ if( rgAtEnter == null ) {
+ return null;
+ }
+
+ assert x.getType() != null;
+ assert x.getType().isArray();
+
+ return rgAtEnter.canPointTo( x, arrayElementFieldName );
+ }
}
package Analysis.Disjoint;
+
+import java.util.*;
+
+import IR.*;
+import IR.Flat.TempDescriptor;
+import IR.Flat.FlatNode;
import IR.Flat.FlatNew;
+
public interface HeapAnalysis {
public EffectsAnalysis getEffectsAnalysis();
public Alloc getAllocationSiteFromFlatNew(FlatNew node);
+ public Alloc getCmdLineArgsAlloc();
+
+ // Use these methods to find out what allocation sites
+ // the given pointer might point to at or after the
+ // given program point. In the case of a variable and
+ // 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
+ public Set<Alloc> canPointToAt( TempDescriptor x,
+ FlatNode programPoint );
+
+ public Set<Alloc> canPointToAfter( TempDescriptor x,
+ FlatNode programPoint );
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAt( TempDescriptor x,
+ FieldDescriptor f,
+ FlatNode programPoint );
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAtElement( TempDescriptor x, // x[i]
+ FlatNode programPoint );
}
public Set<TempDescriptor> getInaccessibleVars() {
return inaccessibleVars;
}
+
+
+
+
+ public Set<Alloc> canPointTo( TempDescriptor x ) {
+ VariableNode vn = getVariableNodeNoMutation( x );
+ if( vn == null ) {
+ return null;
+ }
+
+ Set<Alloc> out = new HashSet<Alloc>();
+
+ Iterator<RefEdge> edgeItr = vn.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ HeapRegionNode hrn = edgeItr.next().getDst();
+
+ out.add( hrn.getAllocSite() );
+ }
+
+ return out;
+ }
+
+
+
+ public Hashtable< Alloc, Set<Alloc> > canPointTo( TempDescriptor x,
+ String field ) {
+
+ VariableNode vn = getVariableNodeNoMutation( x );
+ if( vn == null ) {
+ return null;
+ }
+
+ 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();
+
+ Set<Alloc> moreValues = new HashSet<Alloc>();
+ Iterator<RefEdge> edgeItr2 = hrn.iteratorToReferencees();
+ while( edgeItr2.hasNext() ) {
+ RefEdge edge = edgeItr2.next();
+
+ if( field.equals( edge.getField() ) ) {
+ moreValues.add( edge.getDst().getAllocSite() );
+ }
+ }
+
+ if( out.containsKey( key ) ) {
+ out.get( key ).addAll( moreValues );
+ } else {
+ out.put( key, moreValues );
+ }
+ }
+
+ return out;
+ }
+
+
+
+ // for debugging
+ public TempDescriptor findVariableByName( String name ) {
+
+ for( TempDescriptor td: td2vn.keySet() ) {
+ if( td.getSymbol().contains( name ) ) {
+ return td;
+ }
+ }
+
+ return null;
+ }
}
return fm;
}
- public HeapAnalysis getDisjointAnalysis() {
+ public HeapAnalysis getHeapAnalysis() {
return disjointAnalysisTaints;
}
}
}
}
-}
\ No newline at end of file
+
+
+
+
+ public Alloc getCmdLineArgsAlloc() {
+ return null;
+ }
+
+
+
+ public Set<Alloc> canPointToAt( TempDescriptor x,
+ FlatNode programPoint ) {
+ return null;
+ }
+
+ public Set<Alloc> canPointToAfter( TempDescriptor x,
+ FlatNode programPoint ) {
+ return null;
+ }
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAt( TempDescriptor x,
+ FieldDescriptor f,
+ FlatNode programPoint ) {
+ return null;
+ }
+
+ public Hashtable< Alloc, Set<Alloc> > canPointToAtElement( TempDescriptor x,
+ FlatNode programPoint ) {
+ return null;
+ }
+}
-coreprof-enable cpe_taskstallmem
-USEOOO= -ooojava $(NUM_OOO_WORKERS) 2 -squeue #-ooodebug-disable-task-mem-pool
+USEOOO= -ooojava $(NUM_OOO_WORKERS) 2 -squeue #-ooodebug-disable-task-mem-pool
USERCR= -ooojava $(NUM_RCR_WORKERS) 2 -rcr -squeue -ooodebug
OOODEBUG= -ooodebug -printlinenum
RCRDEBUG= -rcr_debug -printlinenum
RCRDEBUGV= -rcr_debug_verbose -printlinenum
-BSFLAGS= -64bit -mainclass $(PROGRAM) -heapsize-mb 8000 -garbagestats -joptimize -noloop -optimize -nolock -debug #-nooptimize #src-after-pp
+BSFLAGS= -64bit -mainclass $(PROGRAM) -heapsize-mb 5000 -garbagestats -joptimize -noloop -optimize -nolock -debug #-nooptimize #src-after-pp
+
+
+CHECKPOINTSTO= -disjoint -pointsto-check-v-runtime
DRELEASEMODE=-disjoint-release-mode -disjoint-dvisit-stack-callees-on-top -disjoint-alias-file aliases.txt tabbed
-DISJOINT= -disjoint -disjoint-k 1 -enable-assertions $(DRELEASEMODE) #-disjoint-desire-determinism
+DISJOINT= -disjoint -disjoint-k 1 -enable-assertions $(DRELEASEMODE) #-disjoint-desire-determinism
#####################################
rcr-remake-c:
$(BUILDSCRIPT) -nojava $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) $(USERCR) $(DISJOINT) -o $(PROGRAM)r -builddir rcr $(SOURCE_FILES)
+
single: $(PROGRAM)s.bin
$(PROGRAM)s.bin: $(SOURCE_FILES) ../master-makefile
- $(BUILDSCRIPT) -thread $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) -o $(PROGRAM)s -builddir sing $(SOURCE_FILES)
+ $(BUILDSCRIPT) $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) -o $(PROGRAM)s -builddir sing $(SOURCE_FILES)
+
+
+check-pointsto: $(PROGRAM)c.bin
+
+$(PROGRAM)c.bin: $(SOURCE_FILES) ../master-makefile
+ $(BUILDSCRIPT) $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) $(CHECKPOINTSTO) -o $(PROGRAM)c -builddir chk $(SOURCE_FILES)
+
+
ooo: $(PROGRAM)p.bin
--- /dev/null
+package IR.Flat;
+
+import Analysis.Disjoint.HeapAnalysis;
+import Analysis.Disjoint.Alloc;
+import IR.*;
+
+import java.io.*;
+import java.util.*;
+
+
+// This BuildCode Extension (BCX) takes a heap analysis
+// with points-to information and generates checks at runtime
+// verifies the allocation site of objects pointed-to. It
+// doesn't fully verify an analysis but it can reveal bugs!
+
+
+public class BCXPointsToCheckVRuntime implements BuildCodeExtension {
+
+ protected BuildCode buildCode;
+ protected HeapAnalysis heapAnalysis;
+
+
+ public BCXPointsToCheckVRuntime( BuildCode buildCode,
+ HeapAnalysis heapAnalysis ) {
+ this.buildCode = buildCode;
+ this.heapAnalysis = heapAnalysis;
+ }
+
+
+ public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
+ outmethodheader.println("#include \"assert.h\"");
+ }
+
+
+ public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
+
+ for( int i = 0; i < fm.numParameters(); ++i ) {
+ TempDescriptor td = fm.getParameter( i );
+ TypeDescriptor type = td.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ td,
+ heapAnalysis.canPointToAfter( td, fm )
+ );
+ }
+ }
+ }
+
+
+ public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
+
+ TempDescriptor lhs;
+ TempDescriptor rhs;
+ FieldDescriptor fld;
+ TempDescriptor idx;
+ TypeDescriptor type;
+
+
+ switch( fn.kind() ) {
+
+ case FKind.FlatOpNode: {
+ FlatOpNode fon = (FlatOpNode) fn;
+ if( fon.getOp().getOp() == Operation.ASSIGN ) {
+ lhs = fon.getDest();
+ rhs = fon.getLeft();
+
+ type = lhs.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ lhs,
+ heapAnalysis.canPointToAt( lhs, fn )
+ );
+
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ rhs,
+ heapAnalysis.canPointToAt( rhs, fn )
+ );
+ }
+ }
+ } break;
+
+
+ case FKind.FlatCastNode: {
+ FlatCastNode fcn = (FlatCastNode) fn;
+ lhs = fcn.getDst();
+ rhs = fcn.getSrc();
+
+ type = fcn.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ lhs,
+ heapAnalysis.canPointToAt( lhs, fn )
+ );
+
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ rhs,
+ heapAnalysis.canPointToAt( rhs, fn )
+ );
+ }
+ } break;
+
+
+ case FKind.FlatFieldNode: {
+ FlatFieldNode ffn = (FlatFieldNode) fn;
+ lhs = ffn.getDst();
+ rhs = ffn.getSrc();
+ fld = ffn.getField();
+
+ type = lhs.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ lhs,
+ heapAnalysis.canPointToAt( lhs, fn )
+ );
+
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ rhs,
+ fld,
+ null,
+ heapAnalysis.canPointToAt( rhs, fld, fn )
+ );
+ }
+ } break;
+
+
+ case FKind.FlatElementNode: {
+ FlatElementNode fen = (FlatElementNode) fn;
+ lhs = fen.getDst();
+ rhs = fen.getSrc();
+ idx = fen.getIndex();
+
+ type = lhs.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ lhs,
+ heapAnalysis.canPointToAt( lhs, fn )
+ );
+
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ rhs,
+ null,
+ idx,
+ heapAnalysis.canPointToAtElement( rhs, fn )
+ );
+ }
+ } break;
+
+ }
+
+ }
+
+
+ public void additionalCodePostNode(FlatMethod fm,
+ FlatNode fn,
+ PrintWriter output) {
+ switch( fn.kind() ) {
+ case FKind.FlatCall: {
+ FlatCall fc = (FlatCall) fn;
+ TempDescriptor td = fc.getReturnTemp();
+
+ if( td != null ) {
+ TypeDescriptor type = td.getType();
+ if( type.isPtr() ) {
+ genAssertRuntimePtrVsHeapResults( output,
+ fm,
+ td,
+ heapAnalysis.canPointToAfter( td, fn )
+ );
+ }
+ }
+ } break;
+ }
+ }
+
+
+
+ protected void
+ genAssertRuntimePtrVsHeapResults( PrintWriter output,
+ FlatMethod context,
+ TempDescriptor x,
+ Set<Alloc> targetsByAnalysis ) {
+
+ output.println( "" );
+ output.println( "// asserts vs. heap results (DEBUG)" );
+
+ if( targetsByAnalysis == null ||
+ targetsByAnalysis.isEmpty() ) {
+ output.println( "assert( "+
+ buildCode.generateTemp( context, x )+
+ " == NULL );\n" );
+
+ } else {
+ output.print( "assert( "+
+ buildCode.generateTemp( context, x )+
+ " == NULL || " );
+
+ Iterator<Alloc> aItr = targetsByAnalysis.iterator();
+ while( aItr.hasNext() ) {
+ Alloc a = aItr.next();
+ output.print( buildCode.generateTemp( context, x )+
+ "->allocsite == "+
+ a.getUniqueAllocSiteID()
+ );
+ if( aItr.hasNext() ) {
+ output.print( " || " );
+ }
+ }
+
+ output.println( " );\n" );
+ }
+ }
+
+
+
+ protected void
+ genAssertRuntimePtrVsHeapResults( PrintWriter output,
+ FlatMethod context,
+ TempDescriptor x,
+ FieldDescriptor f, // this null OR
+ TempDescriptor i, // this null
+ Hashtable< Alloc, Set<Alloc> > targetsByAnalysis ) {
+
+ assert f == null || i == null;
+
+ output.println( "// asserts vs. heap results (DEBUG)" );
+
+ if( targetsByAnalysis == null ||
+ targetsByAnalysis.isEmpty() ) {
+ output.println( "assert( "+
+ buildCode.generateTemp( context, x )+
+ " == NULL );\n" );
+ } else {
+ output.println( "{" );
+
+ // if the ptr is null, that's ok, if not check allocsite
+ output.println( "if( "+
+ buildCode.generateTemp( context, x )+
+ " != NULL ) {" );
+
+ // precompute the allocsite, if any, of the object we will
+ // get from hopping through the first ptr
+ output.println( "int allocsiteOneHop = -1;" );
+ output.println( buildCode.strObjType+"* objOneHop;" );
+
+ if( f != null ) {
+ output.println( "objOneHop = ("+buildCode.strObjType+"*) "+
+ buildCode.generateTemp( context, x )+
+ "->"+f.getSafeSymbol()+";");
+ } else {
+ output.println( "objOneHop = ("+buildCode.strObjType+"*) "+
+ "((struct "+x.getType().dereference().getSafeSymbol()+"**)"+
+ "(((void*) &("+buildCode.generateTemp( context, x )+"->___length___))+sizeof(int)))"+
+ "["+buildCode.generateTemp( context, i )+"];" );
+ }
+
+ output.println( "if( objOneHop != NULL ) { allocsiteOneHop = objOneHop->allocsite; }" );
+
+ output.println( "switch( "+
+ buildCode.generateTemp( context, x )+
+ "->allocsite ) {" );
+
+ Iterator<Alloc> kItr = targetsByAnalysis.keySet().iterator();
+ while( kItr.hasNext() ) {
+ Alloc k = kItr.next();
+
+ output.print( "case "+
+ k.getUniqueAllocSiteID()+
+ ": assert( allocsiteOneHop == -1" );
+
+ Set<Alloc> hopTargets = targetsByAnalysis.get( k );
+ if( hopTargets != null ) {
+
+ if( !hopTargets.isEmpty() ) {
+ output.print( " || " );
+ }
+
+ Iterator<Alloc> aItr = hopTargets.iterator();
+ while( aItr.hasNext() ) {
+ Alloc a = aItr.next();
+
+ output.print( "allocsiteOneHop == "+
+ a.getUniqueAllocSiteID() );
+
+ if( aItr.hasNext() ) {
+ output.print( " || " );
+ }
+ }
+ }
+
+ output.println( " ); break;" );
+ }
+
+ output.println( " default: assert( 0 ); break;" );
+ output.println( "}" );
+ output.println( "}" );
+ output.println( "}\n" );
+ }
+ }
+
+
+
+
+ public void printExtraArrayFields(PrintWriter outclassdefs) {}
+ public void outputTransCode(PrintWriter output) {}
+ public void buildCodeSetup() {}
+ public void generateSizeArrayExtensions(PrintWriter outclassdefs) {}
+ public void preCodeGenInitialization() {}
+ public void postCodeGenCleanUp() {}
+ public void additionalClassObjectFields(PrintWriter outclassdefs) {}
+ public void additionalCodeGen(PrintWriter outmethodheader,
+ PrintWriter outstructs,
+ PrintWriter outmethod) {}
+ public void additionalCodeAtTopOfMain(PrintWriter outmethod) {}
+ public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {}
+ public void additionalCodeAtBottomOfMain(PrintWriter outmethod) {}
+ public void additionalIncludesMethodsImplementation(PrintWriter outmethod) {}
+ public void additionalIncludesStructsHeader(PrintWriter outstructs) {}
+ public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {}
+ public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew) {}
+}
--- /dev/null
+package IR.Flat;
+
+import Analysis.Disjoint.HeapAnalysis;
+import Analysis.Disjoint.Alloc;
+import IR.*;
+
+import java.io.*;
+import java.util.*;
+
+
+// This BuildCode Extension (BCX) takes a heap analysis
+// with points-to information and adds a field to objects
+// at runtime that specifies which allocation site it is
+// from. This extension supports other extensions.
+
+
+public class BCXallocsiteObjectField implements BuildCodeExtension {
+
+ protected BuildCode buildCode;
+ protected HeapAnalysis heapAnalysis;
+
+
+ public BCXallocsiteObjectField( BuildCode buildCode,
+ HeapAnalysis heapAnalysis ) {
+ this.buildCode = buildCode;
+ this.heapAnalysis = heapAnalysis;
+ }
+
+
+ public void additionalClassObjectFields(PrintWriter outclassdefs) {
+ outclassdefs.println(" int allocsite;");
+ }
+
+ public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {
+ outmethod.println(argsVar+"->allocsite = "+
+ heapAnalysis.getCmdLineArgsAlloc().getUniqueAllocSiteID()+
+ ";"
+ );
+ }
+
+ public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew) {
+ outmethod.println(dstVar+"->allocsite = "+
+ heapAnalysis.getAllocationSiteFromFlatNew( flatNew ).getUniqueAllocSiteID()+
+ ";"
+ );
+ }
+
+
+ public void printExtraArrayFields(PrintWriter outclassdefs) {}
+ public void outputTransCode(PrintWriter output) {}
+ public void buildCodeSetup() {}
+ public void generateSizeArrayExtensions(PrintWriter outclassdefs) {}
+ public void preCodeGenInitialization() {}
+ public void postCodeGenCleanUp() {}
+ public void additionalCodeGen(PrintWriter outmethodheader,
+ PrintWriter outstructs,
+ PrintWriter outmethod) {}
+ public void additionalCodeAtTopOfMain(PrintWriter outmethod) {}
+ public void additionalCodeAtBottomOfMain(PrintWriter outmethod) {}
+ public void additionalIncludesMethodsImplementation(PrintWriter outmethod) {}
+ public void additionalIncludesStructsHeader(PrintWriter outstructs) {}
+ public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {}
+ public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {}
+ public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {}
+ public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {}
+ public void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) {}
+}
\ No newline at end of file
int globaldefscount=0;
boolean mgcstaticinit = false;
JavaBuilder javabuilder;
+ String strObjType;
int boundschknum = 0;
State.logEvent("Virtual");
virtualcalls=new Virtual(state, null, callgraph);
printedfieldstbl = new Hashtable<String, ClassDescriptor>();
+ extensions = new Vector<BuildCodeExtension>();
+ this.strObjType =
+ "struct "+
+ typeutil.getClass( TypeUtil.ObjectClass ).getSafeSymbol();
}
/** The buildCode method outputs C code for all the methods. The Flat
try {
buildCodeSetup(); //EXTENSION POINT
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.buildCodeSetup();
+ }
+
outstructs=new CodePrinter(new FileOutputStream(PREFIX+"structdefs.h"), true);
outmethodheader=new CodePrinter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
outclassdefs=new CodePrinter(new FileOutputStream(PREFIX+"classdefs.h"), true);
}
additionalIncludesMethodsHeader(outmethodheader);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalIncludesMethodsHeader(outmethodheader);
+ }
/* Output Structures */
outputStructs(outstructs);
// an opportunity for subclasses to do extra
// initialization
preCodeGenInitialization();
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.preCodeGenInitialization();
+ }
State.logEvent("Start outputMethods");
/* Build the actual methods */
// opportunity for subclasses to gen extra code
additionalCodeGen(outmethodheader, outstructs, outmethod);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeGen(outmethodheader, outstructs, outmethod);
+ }
+
if (state.TASK) {
/* Output code for tasks */
outstructs.close();
postCodeGenCleanUp();
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.postCodeGenCleanUp();
+ }
+
State.logEvent("End of buildCode");
}
additionalCodeAtTopOfMain(outmethod);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeAtTopOfMain(outmethod);
+ }
if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
outmethod.println(" }");
+
+ additionalCodeForCommandLineArgs(outmethod, "stringarray");
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeForCommandLineArgs(outmethod, "stringarray");
+ }
+
+
MethodDescriptor md=typeutil.getMain();
ClassDescriptor cd=typeutil.getMainClass();
additionalCodeAtBottomOfMain(outmethod);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeAtBottomOfMain(outmethod);
+ }
+
outmethod.println("}");
}
outmethod.println("#include \"checkers.h\"");
}
-
additionalIncludesMethodsImplementation(outmethod);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalIncludesMethodsImplementation(outmethod);
+ }
outmethod.println("struct global_defs_t * global_defs_p;");
outmethod.println("struct global_defsprim_t * global_defsprim_p;");
additionalCodeAtTopMethodsImplementation(outmethod);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeAtTopMethodsImplementation(outmethod);
+ }
+
generateMethods(outmethod);
}
additionalIncludesStructsHeader(outstructs);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalIncludesStructsHeader(outstructs);
+ }
/* Output #defines that the runtime uses to determine type
outclassdefs.println(" int type;");
outclassdefs.println(" int hashcode;");
+
additionalClassObjectFields(outclassdefs);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalClassObjectFields(outclassdefs);
+ }
if (state.EVENTMONITOR) {
printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs, outglobaldefsprim);
printedfieldstbl.clear();
+
printExtraArrayFields(outclassdefs);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.printExtraArrayFields(outclassdefs);
+ }
+
if (state.ARRAYPAD) {
outclassdefs.println(" int paddingforarray;");
}
protected void generateSizeArray(PrintWriter outclassdefs) {
outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
+
generateSizeArrayExtensions(outclassdefs);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.generateSizeArrayExtensions(outclassdefs);
+ }
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
cdarray=new ClassDescriptor[state.numClasses()];
classdefout.println(" int hashcode;");
additionalClassObjectFields(classdefout);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalClassObjectFields(classdefout);
+ }
if (state.EVENTMONITOR) {
}
additionalCodeAtTopFlatMethodBody(output, fm);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeAtTopFlatMethodBody(output, fm);
+ }
/* Check to see if we need to do a GC if this is a
* multi-threaded program...*/
}
additionalCodeAtTopFlatMethodBody(output, fm);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeAtTopFlatMethodBody(output, fm);
+ }
/* Check to see if we need to do a GC if this is a
* multi-threaded program...*/
protected void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
if(state.LINENUM) printSourceLineNumber(fm,fn,output);
+
additionalCodePreNode(fm, fn, output);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodePreNode(fm, fn, output);
+ }
switch(fn.kind()) {
case FKind.FlatAtomicEnterNode:
}
additionalCodePostNode(fm, fn, output);
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodePostNode(fm, fn, output);
+ }
+
}
public void generateFlatBackEdge(FlatMethod fm, FlatBackEdge fn, PrintWriter output) {
protected void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
+ String dst=generateTemp(fm,fn.getDst());
+
if (fn.getType().isArray()) {
int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
}
}
if (state.FASTCHECK) {
- String dst=generateTemp(fm,fn.getDst());
output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
}
+
+ for(BuildCodeExtension bcx: extensions) {
+ bcx.additionalCodeNewObject(output, dst, fn);
+ }
}
protected void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
return l;
}
+
+
+ // either create and register an extension object with buildcode
+ // or look at the following option of subclassing BuildCode
+ private Vector<BuildCodeExtension> extensions;
+
+ // note that extensions are invoked in the order they are added
+ // to BuildCode
+ public void registerExtension( BuildCodeExtension bcx ) {
+ extensions.add( bcx );
+ }
+
+
// override these methods in a subclass of BuildCode
// to generate code for additional systems
protected void printExtraArrayFields(PrintWriter outclassdefs) {
}
protected void additionalCodeAtTopOfMain(PrintWriter outmethod) {
}
+ protected void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {
+ }
protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
}
protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
--- /dev/null
+package IR.Flat;
+
+import java.io.*;
+
+// implement these methods and register the extension
+// object with BuildCode. BuildCode will then invoke the
+// methods below at the extension points.
+
+public interface BuildCodeExtension {
+
+ public void printExtraArrayFields(PrintWriter outclassdefs);
+ public void outputTransCode(PrintWriter output);
+ public void buildCodeSetup();
+ public void generateSizeArrayExtensions(PrintWriter outclassdefs);
+
+ public void preCodeGenInitialization();
+ public void postCodeGenCleanUp();
+
+ public void additionalCodeGen(PrintWriter outmethodheader,
+ PrintWriter outstructs,
+ PrintWriter outmethod);
+
+ public void additionalIncludesMethodsHeader(PrintWriter outmethodheader);
+ public void additionalIncludesMethodsImplementation(PrintWriter outmethod);
+ public void additionalIncludesStructsHeader(PrintWriter outstructs);
+
+ public void additionalClassObjectFields(PrintWriter outclassdefs);
+
+ public void additionalCodeAtTopOfMain(PrintWriter outmethod);
+ public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar);
+ public void additionalCodeAtBottomOfMain(PrintWriter outmethod);
+ public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod);
+ public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm);
+ public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output);
+ public void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output);
+ public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew);
+}
public class BuildOoOJavaCode extends BuildCode {
- OoOJavaAnalysis oooa;
+ protected OoOJavaAnalysis oooa;
- String maxTaskRecSizeStr="__maxTaskRecSize___";
+ protected String maxTaskRecSizeStr="__maxTaskRecSize___";
- String mlperrstr =
+ protected String mlperrstr =
"if(status != 0) { "+
"sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
"perror(errmsg); exit(-1); }";
- RuntimeConflictResolver rcr = null;
+ protected RuntimeConflictResolver rcr = null;
+
+
public BuildOoOJavaCode(State st,
Hashtable temptovar,
protected void additionalClassObjectFields(PrintWriter outclassdefs) {
outclassdefs.println(" int oid;");
- outclassdefs.println(" int allocsite;");
}
output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
}
-
-
- // eom - set up related allocation sites's waiting queues
- // TODO: we have to do a table-based thing here...
- // jjenista, I THINK WE LOSE THIS ALTOGETHER!
- /*
- FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
- if(callerSESEplaceholder!= oooa.getMainSESE()){
- Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder);
- if (graph != null && graph.hasConflictEdge()) {
- output.println(" // set up waiting queues ");
- output.println(" int numMemoryQueue=0;");
- output.println(" int memoryQueueItemID=0;");
- Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
- System.out.println("#lockSet="+lockSet.hashCode());
- System.out.println("lockset="+lockSet);
- for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
- Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next();
- System.out.println("id="+seseLock.getID());
- System.out.println("#="+seseLock);
- }
- System.out.println("size="+lockSet.size());
- if (lockSet.size() > 0) {
- output.println(" numMemoryQueue=" + lockSet.size() + ";");
- output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
- output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
- output.println();
- }
- }
- }
- */
}
"=allocate_newarray_mlp("+localsprefixaddr+
", "+arrayid+", "+generateTemp(fm, fn.getSize())+
", oid, "+
- oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
+ oooa.getHeapAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
");");
output.println(" oid += oidIncrement;");
} else {
"=allocate_new_mlp("+localsprefixaddr+
", "+fn.getType().getClassDesc().getId()+
", oid, "+
- oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
+ oooa.getHeapAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
");");
output.println(" oid += oidIncrement;");
} else {
return rtr;
}
+
}
public boolean DISJOINTDEBUGSCHEDULING=false;
+
+ public boolean POINTSTO_CHECK_V_RUNTIME=false;
+
+
public boolean OOOJAVA=false;
public boolean OOODEBUG=false;
public boolean RCR=false;
import IR.Tree.BuildIR;
import IR.Tree.JavaBuilder;
import IR.Tree.SemanticCheck;
-import IR.Flat.BuildCodeMultiCore;
-import IR.Flat.BuildCodeMGC;
-import IR.Flat.BuildFlat;
-import IR.Flat.BuildCode;
-import IR.Flat.BuildCodeTran;
-import IR.Flat.BuildOoOJavaCode;
+import IR.Flat.*;
import IR.Flat.Inliner;
import IR.ClassDescriptor;
import IR.State;
import Analysis.Liveness;
import Analysis.ArrayReferencees;
import Analysis.Pointer.Pointer;
+import Analysis.Disjoint.HeapAnalysis;
import IR.MethodDescriptor;
import IR.Flat.FlatMethod;
import Interface.*;
String outputdir = null;
boolean isDistributeInfo = false;
boolean isDisAll = false;
- int startnum = 0;
+ int startnum = 0;
for(int i=0; i<args.length; i++) {
} else if( option.equals("-disjoint-debug-scheduling") ) {
state.DISJOINTDEBUGSCHEDULING = true;
+
+
+ } else if( option.equals("-pointsto-check-v-runtime") ) {
+ state.POINTSTO_CHECK_V_RUNTIME = true;
+
+
} else if (option.equals("-optional"))
state.OPTIONAL=true;
else if (option.equals("-optimize"))
SafetyAnalysis sa=null;
PrefetchAnalysis pa=null;
OoOJavaAnalysis oooa=null;
+ HeapAnalysis heapAnalysis=null;
+
if (state.INLINEATOMIC) {
Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
while(classit.hasNext()) {
Liveness l = new Liveness();
ArrayReferencees ar = new ArrayReferencees(state, tu, callgraph);
DisjointAnalysis da = new DisjointAnalysis(state, tu, callgraph, l, ar, null, null);
+ heapAnalysis = da;
}
if (state.OOOJAVA) {
Liveness l = new Liveness();
ArrayReferencees ar = new ArrayReferencees(state, tu, callgraph);
oooa = new OoOJavaAnalysis(state, tu, callgraph, l, ar);
+ heapAnalysis = oooa.getHeapAnalysis();
}
}
}
+ if( (state.OOOJAVA || state.POINTSTO_CHECK_V_RUNTIME) &&
+ heapAnalysis != null ) {
+ // use this extension to generate the allocsite field of Object and
+ // ArrayObject for whatever other extensions and systems need it
+ BCXallocsiteObjectField bcx = new BCXallocsiteObjectField( bc, heapAnalysis );
+ bc.registerExtension( bcx );
+ }
+
+ if( state.POINTSTO_CHECK_V_RUNTIME &&
+ heapAnalysis != null ) {
+ BCXPointsToCheckVRuntime bcx = new BCXPointsToCheckVRuntime( bc, heapAnalysis );
+ bc.registerExtension( bcx );
+ }
+
bc.buildCode();
State.logEvent("Done With BuildCode");
#endif
#ifdef MLP
v->oid=oid;
- v->allocsite=allocsite;
+ // v->allocsite=allocsite;
#endif
return v;
}
echo -disjoint-dvisit-pqueue use prio. q strat to visit descriptors
echo -disjoint-desire-determinism set above interproc for determinism
echo -disjoint-debug-scheduling debug when methods are scheduled for analysis
+echo
+echo -pointsto-check-v-runtime check allocation site of pointer targets at runtime to help verify heap analysis results
echo
echo "-mlp <num cores> <max sese age> build mlp code"
echo -mlpdebug if mlp, report progress and interim results
then
#threading java stuff
JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/JavaThread"
- fi
- #base java stuff
- JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/Java"
+ else
+ #base java stuff
+ JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/Java"
+ fi
fi
# everyone gets this except ssjava!