From: jjenista Date: Tue, 13 Nov 2007 19:15:53 +0000 (+0000) Subject: Added framework for ownership analysis. X-Git-Tag: preEdgeChange~371 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4a5fbadc87b9d6bebc0947c03c85cd2d337c5c5f;p=IRC.git Added framework for ownership analysis. --- diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java new file mode 100644 index 00000000..0b9a0c68 --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java @@ -0,0 +1,181 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; +import java.io.*; + + +public class OwnershipAnalysis { + + private State state; + + private BufferedWriter flatbw; + + private HashSet visited; + private HashSet toVisit; + + private int labelindex; + private Hashtable flatnodetolabel; + private Hashtable flatNodeToOwnershipGraph; + + + // this analysis generates an ownership graph for every task + // in the program + public OwnershipAnalysis(State state) throws java.io.IOException { + this.state=state; + + System.out.println( "Performing Ownership Analysis..." ); + + // analyzeTasks(); + } + + /* + public void analyzeTasks() throws java.io.IOException { + for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) { + + // extract task data and flat IR graph of the task + TaskDescriptor td = (TaskDescriptor)it_tasks.next(); + FlatMethod fm = state.getMethodFlat(td); + String taskname=td.getSymbol(); + + // give every node in the flat IR graph a unique label + // so a human being can inspect the graph and verify + // correctness + flatnodetolabel=new Hashtable(); + visited=new HashSet(); + labelindex=0; + labelFlatNodes(fm); + + // initialize the mapping of flat nodes to ownership graphs + // every flat node in the IR graph has its own ownership graph + flatNodeToOwnershipGraph = new Hashtable(); + + flatbw=new BufferedWriter(new FileWriter("task"+taskname+"_FlatIR.dot")); + flatbw.write("digraph Task"+taskname+" {\n"); + + analyzeFlatIRGraph(fm,taskname); + + flatbw.write("}\n"); + flatbw.close(); + } + } + + private void labelFlatNodes(FlatNode fn) { + visited.add(fn); + flatnodetolabel.put(fn,new Integer(labelindex++)); + for(int i=0;i(); + toVisit=new HashSet(); + toVisit.add(fm); + + while( !toVisit.isEmpty() ) { + FlatNode fn=(FlatNode)toVisit.iterator().next(); + toVisit.remove(fn); + visited.add(fn); + + // get this node's ownership graph, or create a new one + OwnershipGraph og = getGraphFromFlat( fn ); + + if( fn.kind() == FKind.FlatMethod ) { + + // FlatMethod does not have toString + flatbw.write( makeDotNodeDec( taskname, flatnodetolabel.get(fn), fn.getClass().getName(), "FlatMethod" ) ); + + FlatMethod fmd = (FlatMethod) fn; + // the FlatMethod is the top-level node, so take the opportunity to + // generate regions of the heap for each parameter to start the + // analysis + for( int i = 0; i < fmd.numParameters(); ++i ) { + TempDescriptor tdParam = fmd.getParameter( i ); + og.newHeapRegion( tdParam ); + } + } else { + flatbw.write( makeDotNodeDec( taskname, flatnodetolabel.get(fn), fn.getClass().getName(), fn.toString() ) ); + } + + TempDescriptor src; + TempDescriptor dst; + FieldDescriptor fld; + switch(fn.kind()) { + case FKind.FlatOpNode: + FlatOpNode fon = (FlatOpNode) fn; + if(fon.getOp().getOp()==Operation.ASSIGN) { + src = fon.getLeft(); + dst = fon.getDest(); + og.assignTempToTemp( src, dst ); + og.writeGraph( makeNodeName( taskname, flatnodetolabel.get(fn), "Op" ) ); + } + break; + + case FKind.FlatFieldNode: + FlatFieldNode ffn = (FlatFieldNode) fn; + src = ffn.getSrc(); + dst = ffn.getDst(); + fld = ffn.getField(); + og.assignTempToField( src, dst, fld ); + og.writeGraph( makeNodeName( taskname, flatnodetolabel.get(fn), "Field" ) ); + break; + + case FKind.FlatSetFieldNode: + FlatSetFieldNode fsfn = (FlatSetFieldNode) fn; + src = fsfn.getSrc(); + dst = fsfn.getDst(); + fld = fsfn.getField(); + og.assignFieldToTemp( src, dst, fld ); + og.writeGraph( makeNodeName( taskname, flatnodetolabel.get(fn), "SetField" ) ); + break; + + case FKind.FlatReturnNode: + og.writeGraph( makeNodeName( taskname, flatnodetolabel.get(fn), "Return" ) ); + break; + } + + // send this flat node's ownership graph along the out edges + // to be taken by the next flat edges in the flow, or if they + // already have a graph, to be merged + for(int i=0;i node"+flatnodetolabel.get(nn)+";\n" ); + + if( !visited.contains( nn ) ) { + // FIX THE COPY!!!!!!!!!!!!!!! + //flatNodeToOwnershipGraph.put( nn, og.copy() ); + flatNodeToOwnershipGraph.put( nn, og ); + toVisit.add( nn ); + } + } + } + } + + private String makeNodeName( String taskname, Integer id, String type ) { + String s = String.format( "%05d", id ); + return "task"+taskname+"_FN"+s+"_"+type; + } + + private String makeDotNodeDec( String taskname, Integer id, String type, String details ) { + if( details == null ) { + return " node"+id+"[label=\""+makeNodeName(taskname,id,type)+"\"];\n"; + } else { + return " node"+id+"[label=\""+makeNodeName(taskname,id,type)+"\\n"+details+"\"];\n"; + } + } + */ +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java new file mode 100644 index 00000000..a60d5340 --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java @@ -0,0 +1,163 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; +import java.io.*; + + +public class OwnershipGraph { + + protected int heapRegionNodeIDs; + protected Vector heapRoots; + + protected int labelNodeIDs; + protected Hashtable td2ln; + + public OwnershipGraph() { + heapRegionNodeIDs = 0; + heapRoots = new Vector(); + + labelNodeIDs = 0; + td2ln = new Hashtable(); + } + + public void assignTempToTemp( TempDescriptor src, + TempDescriptor dst ) { + OwnershipLabelNode srcln = getLabelNodeFromTemp( src ); + OwnershipHeapRegionNode hrn = srcln.getOwnershipHeapRegionNode(); + OwnershipLabelNode dstln = getLabelNodeFromTemp( dst ); + dstln.setOwnershipHeapRegionNode( hrn ); + } + + public void assignTempToField( TempDescriptor src, + TempDescriptor dst, + FieldDescriptor fd ) { + OwnershipLabelNode srcln = getLabelNodeFromTemp( src ); + OwnershipHeapRegionNode hrn = srcln.getOwnershipHeapRegionNode(); + OwnershipLabelNode dstln = getLabelNodeFromTemp( dst ); + dstln.setOwnershipHeapRegionNode( hrn.getField( fd ) ); + } + + public void assignFieldToTemp( TempDescriptor src, + TempDescriptor dst, + FieldDescriptor fd ) { + OwnershipLabelNode srcln = getLabelNodeFromTemp( src ); + OwnershipHeapRegionNode srchrn = srcln.getOwnershipHeapRegionNode(); + OwnershipLabelNode dstln = getLabelNodeFromTemp( dst ); + OwnershipHeapRegionNode dsthrn = dstln.getOwnershipHeapRegionNode(); + dsthrn.setField( fd, srchrn ); + } + + public void newHeapRegion( TempDescriptor td ) { + TypeDescriptor typeDesc = td.getType(); + OwnershipHeapRegionNode hrn = allocate( typeDesc ); + OwnershipLabelNode ln = getLabelNodeFromTemp( td ); + ln.setOwnershipHeapRegionNode( hrn ); + heapRoots.add( hrn ); + } + + protected OwnershipHeapRegionNode allocate( TypeDescriptor typeDesc ) { + OwnershipHeapRegionNode hrn = + new OwnershipHeapRegionNode( heapRegionNodeIDs ); + ++heapRegionNodeIDs; + + if( typeDesc.isClass() ) { + ClassDescriptor classDesc = typeDesc.getClassDesc(); + Iterator fieldItr = classDesc.getFields(); + while( fieldItr.hasNext() ) { + FieldDescriptor fd = (FieldDescriptor)fieldItr.next(); + TypeDescriptor fieldType = fd.getType(); + OwnershipHeapRegionNode fieldNode = allocate( fieldType ); + hrn.setField( fd, fieldNode ); + } + } + + return hrn; + } + + protected OwnershipLabelNode getLabelNodeFromTemp( TempDescriptor td ) { + if( !td2ln.containsKey( td ) ) { + td2ln.put( td, new OwnershipLabelNode( labelNodeIDs, td ) ); + ++labelNodeIDs; + } + + return td2ln.get( td ); + } + + /* + public void addEdge( TempDescriptor tu, TempDescriptor tv ) { + OwnershipLabelNode nu = getOwnershipFromTemp( tu ); + OwnershipLabelNode nv = getOwnershipFromTemp( tv ); + + nu.addOutEdge( nv ); + nv.addInEdge( nu ); + } + + public OwnershipGraph copy() { + OwnershipGraph newog = new OwnershipGraph(); + + // first create a node in the new graph from + // every temp desc in the old graph + Set s = td2on.entrySet(); + Iterator i = s.iterator(); + while( i.hasNext() ) { + Map.Entry me = (Map.Entry) i.next(); + OwnershipLabelNode nu = (OwnershipLabelNode) me.getValue(); + newog.getOwnershipFromTemp( nu.getTempDescriptor() ); + } + + // then use every out-edge of the old graph to + // create the edges of the new graph + i = s.iterator(); + while( i.hasNext() ) { + Map.Entry me = (Map.Entry) i.next(); + OwnershipLabelNode nu = (OwnershipLabelNode) me.getValue(); + for( int j = 0; j < nu.numOutEdges(); ++j ) { + OwnershipLabelNode nv = nu.getOutEdge( j ); + newog.addEdge( nu.getTempDescriptor(), nv.getTempDescriptor() ); + } + } + + return newog; + } + */ + + + public void writeGraph( String graphName ) throws java.io.IOException { + BufferedWriter bw = new BufferedWriter( new FileWriter( graphName+".dot" ) ); + bw.write( "digraph "+graphName+" {\n" ); + + for( int i = 0; i < heapRoots.size(); ++i ) { + OwnershipHeapRegionNode hrn = heapRoots.get( i ); + visitHeapNodes( bw, hrn ); + } + + Set s = td2ln.entrySet(); + Iterator i = s.iterator(); + while( i.hasNext() ) { + Map.Entry me = (Map.Entry) i.next(); + OwnershipLabelNode ln = (OwnershipLabelNode) me.getValue(); + OwnershipHeapRegionNode lnhrn = ln.getOwnershipHeapRegionNode(); + bw.write( " "+ln.toString()+" -> "+lnhrn.toString()+";\n" ); + } + + bw.write( "}\n" ); + bw.close(); + } + + protected void visitHeapNodes( BufferedWriter bw, + OwnershipHeapRegionNode hrn ) throws java.io.IOException { + bw.write( " "+hrn.toString()+"[shape=box];\n" ); + + Iterator fitr = hrn.getFieldIterator(); + while( fitr.hasNext() ) { + Map.Entry me = (Map.Entry) fitr.next(); + FieldDescriptor fd = (FieldDescriptor) me.getKey(); + OwnershipHeapRegionNode childhrn = (OwnershipHeapRegionNode) me.getValue(); + bw.write( " "+hrn.toString()+" -> "+childhrn.toString()+ + "[label=\""+fd.getSymbol()+"\"];\n" ); + visitHeapNodes( bw, childhrn ); + } + } +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipHeapRegionNode.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipHeapRegionNode.java new file mode 100644 index 00000000..79ef7828 --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipHeapRegionNode.java @@ -0,0 +1,38 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; + +public class OwnershipHeapRegionNode { + + protected int id; + protected Hashtable fields; + + public OwnershipHeapRegionNode( int id ) { + this.id = id; + fields = new Hashtable(); + } + + public void setField( FieldDescriptor fd, + OwnershipHeapRegionNode ohrn ) { + fields.put( fd, ohrn ); + } + + public OwnershipHeapRegionNode getField( FieldDescriptor fd ) { + return fields.get( fd ); + } + + public Iterator getFieldIterator() { + Set s = fields.entrySet(); + return s.iterator(); + } + + public String getIDString() { + return (new Integer( id )).toString(); + } + + public String toString() { + return "OHRN"+getIDString(); + } +} \ No newline at end of file diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipLabelNode.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipLabelNode.java new file mode 100644 index 00000000..e6fe8ce2 --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipLabelNode.java @@ -0,0 +1,41 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; + +public class OwnershipLabelNode { + + protected int id; + protected TempDescriptor td; + protected OwnershipHeapRegionNode ohrn; + + public OwnershipLabelNode( int id, TempDescriptor td ) { + this.id = id; + this.td = td; + } + + public OwnershipHeapRegionNode getOwnershipHeapRegionNode() { + return ohrn; + } + + public void setOwnershipHeapRegionNode( OwnershipHeapRegionNode ohrn ) { + this.ohrn = ohrn; + } + + public TempDescriptor getTempDescriptor() { + return td; + } + + public String getIDString() { + return (new Integer( id )).toString(); + } + + public String getTempDescriptorString() { + return td.toString(); + } + + public String toString() { + return "OLN"+getIDString()+"_"+getTempDescriptorString(); + } +} \ No newline at end of file diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipNode.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipNode.java new file mode 100644 index 00000000..2555b6cd --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipNode.java @@ -0,0 +1,80 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; + +public class OwnershipNode { + + protected int id; + protected Vector inEdges; + protected Vector outEdges; + + public OwnershipNode( int id ) { + this.id = id; + inEdges = new Vector(); + outEdges = new Vector(); + } + + public String getIDString() { + return (new Integer( id )).toString(); + } + + + + /* +digraph test +{ + node [shape=record]; + p1 [label="{P1 p1|{int x| {Thing m|{int j|{Part f|{a|b|c}}|{Part g|{a|b|c}}}}}}"]; + p2 [label="{P2 p2|{int y|int z|{Thing n|{int j|{Part f|{a|b|c}}|{Part g|{a|b|c}}}}}}"]; + + edge [color=red]; + p1:b -> p2:j; +} + */ + + /* + public String makeDotNode() { + String + TypeDescriptor typeDesc = td.getType(); + if( typeDesc.isClass() ) { + ClassDescriptor classDesc = typeDesc.getClassDesc(); + Iterator fieldItr = classDesc.getFields(); + while( fieldItr.hasNext() ) { + FieldDescriptor fd = (FieldDescriptor)it.next(); + } + } else if( typeDesc.isArray() ) { + // deal with arrays + } else { + + } + return toString(); + } + */ + + + public int numInEdges() { + return inEdges.size(); + } + + public OwnershipNode getInEdge(int i) { + return (OwnershipNode) inEdges.get(i); + } + + public void addInEdge(OwnershipNode n) { + inEdges.add(n); + } + + public int numOutEdges() { + return outEdges.size(); + } + + public OwnershipNode getOutEdge(int i) { + return (OwnershipNode) outEdges.get(i); + } + + public void addOutEdge(OwnershipNode n) { + outEdges.add(n); + } +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/TestOwnership.java b/Robust/src/Analysis/OwnershipAnalysis/TestOwnership.java new file mode 100644 index 00000000..c2793926 --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/TestOwnership.java @@ -0,0 +1,43 @@ +package Analysis.OwnershipAnalysis; + +import IR.*; +import IR.Flat.*; +import java.util.*; +import java.io.*; + + +public class TestOwnership { + + public static void main( String args[] ) throws java.io.IOException { + System.out.println( "Testing ownership analysis components." ); + + /* + TempDescriptor ta = new TempDescriptor( "ta" ); + TempDescriptor tb = new TempDescriptor( "tb" ); + TempDescriptor tc = new TempDescriptor( "tc" ); + TempDescriptor td = new TempDescriptor( "td" ); + + OwnershipGraph og1 = new OwnershipGraph(); + + og1.assignTempToTemp( ta, tb ); + og1.assignTempToTemp( tb, tc ); + og1.assignTempToTemp( td, tc ); + og1.newHeapRegion( tc ); + + og1.writeGraph( "testGraph1" ); + */ + + /* + og1.addEdge( ta, tb ); + og1.addEdge( tb, tc ); + og1.addEdge( tc, td ); + og1.addEdge( td, ta ); + og1.addEdge( tb, td ); + + + + OwnershipGraph og2 = og1.copy(); + og2.writeGraph( "testGraph2" ); + */ + } +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/makefile b/Robust/src/Analysis/OwnershipAnalysis/makefile new file mode 100644 index 00000000..e3156eac --- /dev/null +++ b/Robust/src/Analysis/OwnershipAnalysis/makefile @@ -0,0 +1,19 @@ +GRAPH=testGraph + +all: view + +view: PNGs + eog *.png & + +PNGs: DOTs + d2p *.dot + +DOTs: run + +run: + java -classpath ../.. Analysis.OwnershipAnalysis.TestOwnership + +clean: + rm -f *~ + rm -f *.dot + rm -f *.png diff --git a/Robust/src/IR/State.java b/Robust/src/IR/State.java index d0b2a079..9db4b173 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -50,6 +50,7 @@ public class State { public boolean FLATIRGRAPHTASKS=false; public boolean FLATIRGRAPHUSERMETHODS=false; public boolean FLATIRGRAPHLIBMETHODS=false; + public boolean OWNERSHIP=false; public boolean OPTIONAL=false; public boolean THREAD=false; public boolean CONSCHECK=false; diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index e6cb52ec..706dca58 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -21,6 +21,7 @@ import Analysis.Locality.LocalityAnalysis; import Analysis.Locality.GenerateConversions; import Analysis.Prefetch.PrefetchAnalysis; import Analysis.FlatIRGraph.FlatIRGraph; +import Analysis.OwnershipAnalysis.OwnershipAnalysis; import Interface.*; public class Main { @@ -65,6 +66,8 @@ public class Main { state.FLATIRGRAPH=true; state.FLATIRGRAPHLIBMETHODS=true; } + else if (option.equals("-ownership")) + state.OWNERSHIP=true; else if (option.equals("-optional")) state.OPTIONAL=true; else if (option.equals("-thread")) @@ -88,6 +91,10 @@ public class Main { System.out.println("-thread -- threads"); System.out.println("-instructionfailures -- insert code for instruction level failures"); System.out.println("-taskstate -- do task state analysis"); + System.out.println("-flatirtasks -- create dot files for flat IR graphs of tasks"); + System.out.println("-flatirusermethods -- create dot files for flat IR graphs of user methods"); + System.out.println("-flatirlibmethods -- create dot files for flat IR graphs of library class methods"); + System.out.println(" note: -flatirusermethods or -flatirlibmethods currently generate all class method flat IR graphs"); System.out.println("-ownership -- do ownership analysis"); System.out.println("-optional -- enable optional arguments"); System.out.println("-webinterface -- enable web interface"); @@ -201,6 +208,10 @@ public class Main { state.FLATIRGRAPHLIBMETHODS); } + if (state.OWNERSHIP) { + OwnershipAnalysis oa = new OwnershipAnalysis(state); + } + System.exit(0); } diff --git a/Robust/src/Makefile b/Robust/src/Makefile index 6f7ec5e2..9a566bbe 100644 --- a/Robust/src/Makefile +++ b/Robust/src/Makefile @@ -72,6 +72,12 @@ Analysis/TaskStateAnalysis/TaskNode.class \ Analysis/TaskStateAnalysis/FlagComparator.class \ Analysis/TaskStateAnalysis/TaskNodeNamer.class Util/Edge.class \ Analysis/FlatIRGraph/FlatIRGraph.class \ +Analysis/OwnershipAnalysis/OwnershipAnalysis.class \ +Analysis/OwnershipAnalysis/OwnershipGraph.class \ +Analysis/OwnershipAnalysis/OwnershipNode.class \ +Analysis/OwnershipAnalysis/OwnershipHeapRegionNode.class \ +Analysis/OwnershipAnalysis/OwnershipLabelNode.class \ +Analysis/OwnershipAnalysis/TestOwnership.class \ Util/GraphNode.class Util/Namer.class Util/Relation.class \ Interface/HTTPHeader.class Interface/HTTPResponse.class \ Interface/HTTPServices.class Interface/HashStrings.class \ @@ -98,10 +104,10 @@ Parse/Parser.java Parse/Sym.java: Parse/java14.cup javadoc: mkdir javadoc - javadoc -classpath ../cup:.:$(CLASSPATH) -sourcepath . -private -d javadoc Lex Util IR IR.Tree IR.Flat Analysis Analysis.CallGraph Analysis.Flag Analysis.TaskStateAnalysis Analysis.Locality Analysis.Prefetch Main + javadoc -classpath ../cup:.:$(CLASSPATH) -sourcepath . -private -d javadoc Lex Util IR IR.Tree IR.Flat Analysis Analysis.CallGraph Analysis.Flag Analysis.TaskStateAnalysis Analysis.Locality Analysis.Prefetch Main Analysis.OwnershipAnalysis clean: - rm -f IR/*.class IR/Tree/*.class Main/*.class Lex/*.class Parse/*.class Parse/Sym.java Parse/Parser.java IR/Flat/*.class classdefs.h methodheaders.h methods.c structdefs.h virtualtable.h task.h taskdefs.c taskdefs.h Analysis/*.class Analysis/Flag/*.class Analysis/CallGraph/*.class Analysis/TaskStateAnalysis/*.class Interface/*.class Util/*.class Analysis/Locality/*.class Analysis/Prefetch/*.class Analysis/FlatIRGraph/*.class + rm -f IR/*.class IR/Tree/*.class Main/*.class Lex/*.class Parse/*.class Parse/Sym.java Parse/Parser.java IR/Flat/*.class classdefs.h methodheaders.h methods.c structdefs.h virtualtable.h task.h taskdefs.c taskdefs.h Analysis/*.class Analysis/Flag/*.class Analysis/CallGraph/*.class Analysis/TaskStateAnalysis/*.class Interface/*.class Util/*.class Analysis/Locality/*.class Analysis/Prefetch/*.class Analysis/FlatIRGraph/*.class Analysis/OwnershipAnalysis/*.class cleandoc: rm -rf javadoc \ No newline at end of file