From: yeom Date: Sat, 5 Mar 2011 00:44:10 +0000 (+0000) Subject: introduce new flag -ssjava for enabling SSJava feature and start working on the imple... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e2f2f0d93bd15c2fd2771480369a7bfab5c339e5;p=IRC.git introduce new flag -ssjava for enabling SSJava feature and start working on the implementation of flow-down rule checking plus minor updates. --- diff --git a/Robust/src/Analysis/SSJava/FlowDownCheck.java b/Robust/src/Analysis/SSJava/FlowDownCheck.java new file mode 100644 index 00000000..a4b0e6f7 --- /dev/null +++ b/Robust/src/Analysis/SSJava/FlowDownCheck.java @@ -0,0 +1,288 @@ +package Analysis.SSJava; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import IR.AnnotationDescriptor; +import IR.ClassDescriptor; +import IR.FieldDescriptor; +import IR.MethodDescriptor; +import IR.State; +import IR.SymbolTable; +import IR.TypeDescriptor; +import IR.VarDescriptor; +import IR.Tree.AssignmentNode; +import IR.Tree.BlockExpressionNode; +import IR.Tree.BlockNode; +import IR.Tree.BlockStatementNode; +import IR.Tree.DeclarationNode; +import IR.Tree.ExpressionNode; +import IR.Tree.Kind; +import Util.Lattice; + +public class FlowDownCheck { + + State state; + HashSet toanalyze; + + public FlowDownCheck(State state) { + this.state = state; + this.toanalyze = new HashSet(); + } + + public void flowDownCheck() { + + SymbolTable classtable = state.getClassSymbolTable(); + toanalyze.addAll(classtable.getValueSet()); + toanalyze.addAll(state.getTaskSymbolTable().getValueSet()); + + // Do methods next + while (!toanalyze.isEmpty()) { + Object obj = toanalyze.iterator().next(); + ClassDescriptor cd = (ClassDescriptor) obj; + toanalyze.remove(cd); + if (cd.isClassLibrary()) { + // doesn't care about class libraries now + continue; + } + + checkClass(cd); + + for (Iterator method_it = cd.getMethods(); method_it.hasNext();) { + MethodDescriptor md = (MethodDescriptor) method_it.next(); + try { + checkMethodBody(cd, md); + } catch (Error e) { + System.out.println("Error in " + md); + throw e; + } + } + } + } + + public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) { + ClassDescriptor superdesc = cd.getSuperDesc(); + if (superdesc != null) { + Set possiblematches = superdesc.getMethodTable().getSet(md.getSymbol()); + for (Iterator methodit = possiblematches.iterator(); methodit.hasNext();) { + MethodDescriptor matchmd = (MethodDescriptor) methodit.next(); + if (md.matches(matchmd)) { + if (matchmd.getModifiers().isFinal()) { + throw new Error("Try to override final method in method:" + md + " declared in " + cd); + } + } + } + } + BlockNode bn = state.getMethodBody(md); + checkBlockNode(md, md.getParameterTable(), bn); + } + + public void checkBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) { + /* Link in the naming environment */ + bn.getVarTable().setParent(nametable); + for (int i = 0; i < bn.size(); i++) { + BlockStatementNode bsn = bn.get(i); + checkBlockStatementNode(md, bn.getVarTable(), bsn); + } + } + + public void checkBlockStatementNode(MethodDescriptor md, SymbolTable nametable, + BlockStatementNode bsn) { + + switch (bsn.kind()) { + case Kind.BlockExpressionNode: + checkBlockExpressionNode(md, nametable, (BlockExpressionNode) bsn); + return; + + case Kind.DeclarationNode: + checkDeclarationNode(md, (DeclarationNode) bsn); + return; + } + /* + * switch (bsn.kind()) { case Kind.BlockExpressionNode: + * checkBlockExpressionNode(md, nametable, (BlockExpressionNode) bsn); + * return; + * + * case Kind.DeclarationNode: checkDeclarationNode(md, nametable, + * (DeclarationNode) bsn); return; + * + * case Kind.TagDeclarationNode: checkTagDeclarationNode(md, nametable, + * (TagDeclarationNode) bsn); return; + * + * case Kind.IfStatementNode: checkIfStatementNode(md, nametable, + * (IfStatementNode) bsn); return; + * + * case Kind.SwitchStatementNode: checkSwitchStatementNode(md, nametable, + * (SwitchStatementNode) bsn); return; + * + * case Kind.LoopNode: checkLoopNode(md, nametable, (LoopNode) bsn); return; + * + * case Kind.ReturnNode: checkReturnNode(md, nametable, (ReturnNode) bsn); + * return; + * + * case Kind.TaskExitNode: checkTaskExitNode(md, nametable, (TaskExitNode) + * bsn); return; + * + * case Kind.SubBlockNode: checkSubBlockNode(md, nametable, (SubBlockNode) + * bsn); return; + * + * case Kind.AtomicNode: checkAtomicNode(md, nametable, (AtomicNode) bsn); + * return; + * + * case Kind.SynchronizedNode: checkSynchronizedNode(md, nametable, + * (SynchronizedNode) bsn); return; + * + * case Kind.ContinueBreakNode: checkContinueBreakNode(md, nametable, + * (ContinueBreakNode) bsn); return; + * + * case Kind.SESENode: case Kind.GenReachNode: // do nothing, no semantic + * check for SESEs return; } + */ + // throw new Error(); + } + + void checkBlockExpressionNode(MethodDescriptor md, SymbolTable nametable, BlockExpressionNode ben) { + checkExpressionNode(md, nametable, ben.getExpression(), null); + } + + void checkExpressionNode(MethodDescriptor md, SymbolTable nametable, ExpressionNode en, + TypeDescriptor td) { + + switch (en.kind()) { + case Kind.AssignmentNode: + checkAssignmentNode(md, nametable, (AssignmentNode) en, td); + return; + } + /* + * switch(en.kind()) { case Kind.AssignmentNode: + * checkAssignmentNode(md,nametable,(AssignmentNode)en,td); return; + * + * case Kind.CastNode: checkCastNode(md,nametable,(CastNode)en,td); return; + * + * case Kind.CreateObjectNode: + * checkCreateObjectNode(md,nametable,(CreateObjectNode)en,td); return; + * + * case Kind.FieldAccessNode: + * checkFieldAccessNode(md,nametable,(FieldAccessNode)en,td); return; + * + * case Kind.ArrayAccessNode: + * checkArrayAccessNode(md,nametable,(ArrayAccessNode)en,td); return; + * + * case Kind.LiteralNode: checkLiteralNode(md,nametable,(LiteralNode)en,td); + * return; + * + * case Kind.MethodInvokeNode: + * checkMethodInvokeNode(md,nametable,(MethodInvokeNode)en,td); return; + * + * case Kind.NameNode: checkNameNode(md,nametable,(NameNode)en,td); return; + * + * case Kind.OpNode: checkOpNode(md,nametable,(OpNode)en,td); return; + * + * case Kind.OffsetNode: checkOffsetNode(md, nametable, (OffsetNode)en, td); + * return; + * + * case Kind.TertiaryNode: checkTertiaryNode(md, nametable, + * (TertiaryNode)en, td); return; + * + * case Kind.InstanceOfNode: checkInstanceOfNode(md, nametable, + * (InstanceOfNode) en, td); return; + * + * case Kind.ArrayInitializerNode: checkArrayInitializerNode(md, nametable, + * (ArrayInitializerNode) en, td); return; + * + * case Kind.ClassTypeNode: checkClassTypeNode(md, nametable, + * (ClassTypeNode) en, td); return; } + */ + } + + void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, + TypeDescriptor td) { + + ClassDescriptor cd = md.getClassDesc(); + Lattice locOrder = (Lattice) state.getCd2LocationOrder().get(cd); + + String destLocation = an.getDest().getType().getAnnotationMarkers().elementAt(0).getMarker(); + String srcLocation = an.getSrc().getType().getAnnotationMarkers().elementAt(0).getMarker(); + + if (!locOrder.isGreaterThan(srcLocation, destLocation)) { + throw new Error("Value flow from " + srcLocation + " to " + destLocation + + "does not respect location hierarchy."); + } + + } + + void checkDeclarationNode(MethodDescriptor md, DeclarationNode dn) { + + ClassDescriptor cd = md.getClassDesc(); + VarDescriptor vd = dn.getVarDescriptor(); + Vector annotationVec = vd.getType().getAnnotationMarkers(); + + // currently enforce every variable to have corresponding location + if (annotationVec.size() == 0) { + throw new Error("Location is not assigned to variable " + vd.getSymbol() + " in the method " + + md.getSymbol() + " of the class " + cd.getSymbol()); + } + + if (annotationVec.size() > 1) { + // variable can have at most one location + throw new Error(vd.getSymbol() + " has more than one location."); + } + + // check if location is defined + String locationID = annotationVec.elementAt(0).getMarker(); + Lattice lattice = (Lattice) state.getCd2LocationOrder().get(cd); + + if (lattice == null || (!lattice.containsKey(locationID))) { + throw new Error("Location " + locationID + + " is not defined in the location hierarchy of class " + cd.getSymbol() + "."); + } + + } + + private void checkClass(ClassDescriptor cd) { + // Check to see that fields are okay + for (Iterator field_it = cd.getFields(); field_it.hasNext();) { + FieldDescriptor fd = (FieldDescriptor) field_it.next(); + checkFieldDeclaration(cd, fd); + } + + // Check to see that methods respects ss property + for (Iterator method_it = cd.getMethods(); method_it.hasNext();) { + MethodDescriptor md = (MethodDescriptor) method_it.next(); + checkMethodDeclaration(cd, md); + } + } + + private void checkMethodDeclaration(ClassDescriptor cd, MethodDescriptor md) { + + } + + private void checkFieldDeclaration(ClassDescriptor cd, FieldDescriptor fd) { + + Vector annotationVec = fd.getType().getAnnotationMarkers(); + + // currently enforce every variable to have corresponding location + if (annotationVec.size() == 0) { + throw new Error("Location is not assigned to the field " + fd.getSymbol() + " of the class " + + cd.getSymbol()); + } + + if (annotationVec.size() > 1) { + // variable can have at most one location + throw new Error("Field " + fd.getSymbol() + " of class " + cd + + " has more than one location."); + } + + // check if location is defined + String locationID = annotationVec.elementAt(0).getMarker(); + Lattice lattice = (Lattice) state.getCd2LocationOrder().get(cd); + + if (lattice == null || (!lattice.containsKey(locationID))) { + throw new Error("Location " + locationID + + " is not defined in the location hierarchy of class " + cd.getSymbol() + "."); + } + + } +} diff --git a/Robust/src/Analysis/SSJava/SSJavaAnalysis.java b/Robust/src/Analysis/SSJava/SSJavaAnalysis.java new file mode 100644 index 00000000..35cd5500 --- /dev/null +++ b/Robust/src/Analysis/SSJava/SSJavaAnalysis.java @@ -0,0 +1,22 @@ +package Analysis.SSJava; + +import java.util.HashSet; + +import IR.State; + +public class SSJavaAnalysis { + + State state; + HashSet toanalyze; + + public SSJavaAnalysis(State state) { + this.state = state; + } + + public void doCheck() { + FlowDownCheck checker = new FlowDownCheck(state); + checker.flowDownCheck(); + // doMoreAnalysis(); + } + +} diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index d1fa7b49..4e313bb7 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -40,9 +40,8 @@ public class ClassDescriptor extends Descriptor { HashMap enumConstantTbl; int enumconstantid = 0; - // for SSJava - Lattice locOrder; - + boolean isClassLibrary=false; + public ClassDescriptor(String classname, boolean isInterface) { this("", classname, isInterface); } @@ -61,7 +60,6 @@ public class ClassDescriptor extends Descriptor { superIFdesc = new SymbolTable(); this.innerdescs = new SymbolTable(); this.enumdescs = new SymbolTable(); - this.locOrder=new Lattice(); } public int getId() { @@ -376,12 +374,12 @@ public class ClassDescriptor extends Descriptor { return this.modifiers; } - public Lattice getLocOrder(){ - return this.locOrder; + public void setClassLibrary(){ + this.isClassLibrary=true; } - public void setLocOrder(Lattice locOrder){ - this.locOrder=locOrder; + public boolean isClassLibrary(){ + return isClassLibrary; } } diff --git a/Robust/src/IR/State.java b/Robust/src/IR/State.java index 723fb62d..30f89e46 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -2,6 +2,8 @@ package IR; import IR.Tree.*; import IR.Flat.*; import IR.*; +import Util.Lattice; + import java.util.*; import Analysis.TaskStateAnalysis.*; @@ -21,6 +23,7 @@ public class State { this.selfloops=new HashSet(); this.excprefetch=new HashSet(); this.classpath=new Vector(); + this.cd2locationOrderMap=new Hashtable(); this.lines=0; } @@ -110,6 +113,9 @@ public class State { public boolean RCR_DEBUG=false; public boolean RCR_DEBUG_VERBOSE=false; public boolean NOSTALLTR=false; + + //SSJava + public boolean SSJAVA=false; public boolean OPTIONAL=false; @@ -180,6 +186,7 @@ public class State { private int numtasks=0; private int numstaticblocks=0; private int arraycount=0; + public Hashtable cd2locationOrderMap; public boolean OPTIMIZE=false; private Hashtable> optionaltaskdescriptors; @@ -313,4 +320,13 @@ public class State { tasks.add(td); numtasks++; } + + public void addLocationOrder(ClassDescriptor cd, Lattice order){ + cd2locationOrderMap.put(cd,order); + } + + public Hashtable getCd2LocationOrder(){ + return cd2locationOrderMap; + } + } diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 4b505b0a..8ec7fd66 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -4,6 +4,8 @@ import Util.Lattice; import java.util.*; +import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction; + public class BuildIR { State state; @@ -481,16 +483,20 @@ public class BuildIR { } } - private void parseLocationOrder(ClassDescriptor cn, ParseNode pn){ + private void parseLocationOrder(ClassDescriptor cd, ParseNode pn){ ParseNodeVector pnv=pn.getChildren(); Lattice locOrder=new Lattice(); for(int i=0; i annotationSet; + private Vector annotationSet; public boolean equals(Object o) { if (o instanceof TypeDescriptor) { @@ -285,7 +286,7 @@ public class TypeDescriptor extends Descriptor { this.class_desc=null; this.arraycount=0; this.isClassNameRef =false; - this.annotationSet=new HashSet(); + this.annotationSet=new Vector(); } public TypeDescriptor(String st) { @@ -294,7 +295,7 @@ public class TypeDescriptor extends Descriptor { this.class_desc=null; this.arraycount=0; this.isClassNameRef =false; - this.annotationSet=new HashSet(); + this.annotationSet=new Vector(); } public ClassDescriptor getClassDesc() { @@ -307,7 +308,7 @@ public class TypeDescriptor extends Descriptor { this.class_desc=cd; this.arraycount=0; this.isClassNameRef =false; - this.annotationSet=new HashSet(); + this.annotationSet=new Vector(); } public TypeDescriptor(int t) { @@ -315,7 +316,7 @@ public class TypeDescriptor extends Descriptor { this.type=t; this.arraycount=0; this.isClassNameRef =false; - this.annotationSet=new HashSet(); + this.annotationSet=new Vector(); } public String toString() { @@ -367,7 +368,7 @@ public class TypeDescriptor extends Descriptor { annotationSet.add(an); } - public Set getAnnotationMarkerSet(){ + public Vector getAnnotationMarkers(){ return annotationSet; } diff --git a/Robust/src/IR/TypeUtil.java b/Robust/src/IR/TypeUtil.java index a704929c..80b40191 100644 --- a/Robust/src/IR/TypeUtil.java +++ b/Robust/src/IR/TypeUtil.java @@ -57,7 +57,8 @@ public class TypeUtil { //have to find class addNewClass(classname, todo); cd=(ClassDescriptor)state.getClassSymbolTable().get(classname); - + cd.setClassLibrary(); + System.out.println("Build class:"+cd); todo.add(cd); } diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index e329aa8b..ec83d412 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -25,6 +25,7 @@ import IR.ClassDescriptor; import IR.State; import IR.TaskDescriptor; import IR.TypeUtil; +import Analysis.SSJava.SSJavaAnalysis; import Analysis.Scheduling.MCImplSynthesis; import Analysis.Scheduling.Schedule; import Analysis.Scheduling.ScheduleAnalysis; @@ -340,7 +341,9 @@ public class Main { state.KEEP_RG_FOR_ALL_PROGRAM_POINTS=true; } else if (option.equals("-nostalltr")){ state.NOSTALLTR = true; - }else if (option.equals("-help")) { + } else if (option.equals("-ssjava")){ + state.SSJAVA = true; + } else if (option.equals("-help")) { System.out.println("-classlibrary classlibrarydirectory -- directory where classlibrary is located"); System.out.println("-selfloop task -- this task doesn't self loop its parameters forever"); System.out.println("-dir outputdirectory -- output code in outputdirectory"); @@ -395,16 +398,15 @@ public class Main { if (state.classpath.size()==1) state.classpath.add(ClassLibraryPrefix); + SSJavaAnalysis ssjava=new SSJavaAnalysis(state); BuildIR bir=new BuildIR(state); TypeUtil tu=new TypeUtil(state, bir); - SemanticCheck sc=new SemanticCheck(state,tu); for(int i=0;i { s = new HashSet(); table.put(key, s); } - if (!s.contains(value)) { + if (value!=null && !s.contains(value)) { size++; s.add(value); return true; @@ -29,10 +29,44 @@ public class Lattice { return false; } + public boolean isIntroducingCycle(T key) { + + Set reachableSet = new HashSet(); + Set neighborSet = get(key); + + if (neighborSet == null) { + return false; + } else { + reachableSet.addAll(neighborSet); + } + + int oldReachableSize; + do { + oldReachableSize = reachableSet.size(); + Set nextLevelNeighbors = new HashSet(); + for (Iterator iterator = neighborSet.iterator(); iterator.hasNext();) { + T element = iterator.next(); + Set neighbors = get(element); + if (neighbors != null) { + nextLevelNeighbors.addAll(neighbors); + reachableSet.addAll(neighbors); + } + + if (reachableSet.contains(key)) { + // found cycle + return true; + } + } + neighborSet = nextLevelNeighbors; + } while (oldReachableSize != reachableSet.size()); + + return false; + } + public Set get(T key) { return table.get(key); } - + public boolean containsKey(T o) { return table.containsKey(o); } @@ -40,7 +74,6 @@ public class Lattice { public boolean isGreaterThan(T a, T b) { Set neighborSet = get(a); - System.out.println("neightborSet of " + a + "=" + neighborSet); if (neighborSet == null) { return false; diff --git a/Robust/src/buildscript b/Robust/src/buildscript index 7e04cd90..27a5cd0a 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -100,6 +100,9 @@ echo "-gccacheadapt setup as cacheadaptable mode (should be used together with - echo -gcprofile build with gcprofile options echo -mgc generate Multicore GC binary without task stuff echo +echo SSJava options +echo -ssjava enables SSJava +echo echo Other options echo -abcclose turnoff array boundary checks echo -builddir setup different build directory