From: yeom Date: Mon, 13 Aug 2012 02:04:25 +0000 (+0000) Subject: changes + annotation generation X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7a0d4aea90f5e090be8341e7ab4a8d5e33c788f5;p=IRC.git changes + annotation generation --- diff --git a/Robust/src/Analysis/SSJava/FlowGraph.java b/Robust/src/Analysis/SSJava/FlowGraph.java index 9018489c..8522f2ef 100644 --- a/Robust/src/Analysis/SSJava/FlowGraph.java +++ b/Robust/src/Analysis/SSJava/FlowGraph.java @@ -89,6 +89,10 @@ public class FlowGraph { // System.out.println("add a new neighbor " + neighbor + " to " + node); } + public boolean isParamDesc(Descriptor desc) { + return mapParamDescToIdx.containsKey(desc); + } + public boolean hasEdge(NTuple fromDescTuple, NTuple toDescTuple) { FlowNode fromNode = mapDescTupleToInferNode.get(fromDescTuple); diff --git a/Robust/src/Analysis/SSJava/FlowNode.java b/Robust/src/Analysis/SSJava/FlowNode.java index 7ce39ed5..c24d5776 100644 --- a/Robust/src/Analysis/SSJava/FlowNode.java +++ b/Robust/src/Analysis/SSJava/FlowNode.java @@ -23,6 +23,8 @@ public class FlowNode { // set true if this node stores a return value private boolean isReturn; + private boolean isDeclarationNode = false; + public Set getFieldNodeSet() { return fieldNodeSet; } @@ -143,4 +145,12 @@ public class FlowNode { id += ">"; return id; } + + public void setDeclarationNode() { + isDeclarationNode = true; + } + + public boolean isDeclaratonNode() { + return isDeclarationNode; + } } diff --git a/Robust/src/Analysis/SSJava/LocationInference.java b/Robust/src/Analysis/SSJava/LocationInference.java index 03cf57f7..c9877d8e 100644 --- a/Robust/src/Analysis/SSJava/LocationInference.java +++ b/Robust/src/Analysis/SSJava/LocationInference.java @@ -1,8 +1,11 @@ package Analysis.SSJava; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -13,6 +16,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; +import java.util.Vector; import IR.ClassDescriptor; import IR.Descriptor; @@ -81,6 +85,10 @@ public class LocationInference { private Map> mapMethodToCalleeSet; + private Map> mapFileNameToLineVector; + + private Map mapDescToDefinitionLine; + public static final String GLOBALLOC = "GLOBALLOC"; public static final String TOPLOC = "TOPLOC"; @@ -89,6 +97,8 @@ public class LocationInference { public static final Descriptor TOPDESC = new NameDescriptor(TOPLOC); + public static String newline = System.getProperty("line.separator"); + LocationInfo curMethodInfo; boolean debug = true; @@ -109,6 +119,9 @@ public class LocationInference { this.mapMethodDescToMethodLocationInfo = new HashMap(); this.mapMethodToCalleeSet = new HashMap>(); this.mapClassToLocationInfo = new HashMap(); + + this.mapFileNameToLineVector = new HashMap>(); + this.mapDescToDefinitionLine = new HashMap(); } public void setupToAnalyze() { @@ -165,6 +178,299 @@ public class LocationInference { // 3) check properties checkLattices(); + // 4) generate annotated source codes + generateAnnoatedCode(); + + } + + private void addMapClassDefinitionToLineNum(ClassDescriptor cd, String strLine, int lineNum) { + String pattern = "class " + cd.getSymbol() + " "; + if (strLine.indexOf(pattern) != -1) { + mapDescToDefinitionLine.put(cd, lineNum); + } + } + + private void addMapMethodDefinitionToLineNum(Set methodSet, String strLine, + int lineNum) { + for (Iterator iterator = methodSet.iterator(); iterator.hasNext();) { + MethodDescriptor md = (MethodDescriptor) iterator.next(); + String pattern = md.getMethodDeclaration(); + if (strLine.indexOf(pattern) != -1) { + mapDescToDefinitionLine.put(md, lineNum); + methodSet.remove(md); + return; + } + } + + } + + private void readOriginalSourceFiles() { + + SymbolTable classtable = state.getClassSymbolTable(); + + Set classDescSet = new HashSet(); + classDescSet.addAll(classtable.getValueSet()); + + try { + // inefficient implement. it may re-visit the same file if the file + // contains more than one class definitions. + for (Iterator iterator = classDescSet.iterator(); iterator.hasNext();) { + ClassDescriptor cd = (ClassDescriptor) iterator.next(); + + Set methodSet = new HashSet(); + methodSet.addAll(cd.getMethodTable().getValueSet()); + + String sourceFileName = cd.getSourceFileName(); + Vector lineVec = new Vector(); + + mapFileNameToLineVector.put(sourceFileName, lineVec); + + BufferedReader in = new BufferedReader(new FileReader(sourceFileName)); + String strLine; + int lineNum = 1; + lineVec.add(""); // the index is started from 1. + while ((strLine = in.readLine()) != null) { + lineVec.add(lineNum, strLine); + addMapClassDefinitionToLineNum(cd, strLine, lineNum); + addMapMethodDefinitionToLineNum(methodSet, strLine, lineNum); + lineNum++; + } + + } + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + private String generateLatticeDefinition(Descriptor desc) { + + SSJavaLattice lattice = getLattice(desc); + String rtr = "@LATTICE(\""; + + Map> map = lattice.getTable(); + Set keySet = map.keySet(); + boolean first = true; + for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { + String key = (String) iterator.next(); + if (!key.equals(lattice.getTopItem())) { + Set connectedSet = map.get(key); + + if (connectedSet.size() == 1) { + if (connectedSet.iterator().next().equals(lattice.getBottomItem())) { + if (!first) { + rtr += ","; + } else { + rtr += "LOC,"; + first = false; + } + rtr += key; + } + } + + for (Iterator iterator2 = connectedSet.iterator(); iterator2.hasNext();) { + String loc = (String) iterator2.next(); + if (!loc.equals(lattice.getBottomItem())) { + if (!first) { + rtr += ","; + } else { + rtr += "LOC,"; + first = false; + } + rtr += loc + "<" + key; + } + } + } + } + + rtr += "\")"; + + if (desc instanceof MethodDescriptor) { + TypeDescriptor returnType = ((MethodDescriptor) desc).getReturnType(); + if (returnType != null && (!returnType.isVoid())) { + rtr += "\n@RETURNLOC(\"RETURNLOC\")"; + } + rtr += "\n@THISLOC(\"this\")\n@PCLOC(\"PCLOC\")\n@GLOBALLOC(\"GLOBALLOC\")"; + + } + + return rtr; + } + + private void generateAnnoatedCode() { + + readOriginalSourceFiles(); + + setupToAnalyze(); + + while (!toAnalyzeIsEmpty()) { + ClassDescriptor cd = toAnalyzeNext(); + + setupToAnalazeMethod(cd); + + LocationInfo locInfo = mapClassToLocationInfo.get(cd); + + String sourceFileName = cd.getSourceFileName(); + + int classDefLine = mapDescToDefinitionLine.get(cd); + Vector sourceVec = mapFileNameToLineVector.get(sourceFileName); + + if (locInfo != null) { + + Map mapDescToInferLoc = locInfo.getMapDescToInferLocation(); + Set fieldDescSet = mapDescToInferLoc.keySet(); + for (Iterator iterator = fieldDescSet.iterator(); iterator.hasNext();) { + Descriptor fieldDesc = (Descriptor) iterator.next(); + String locIdentifier = locInfo.getFieldInferLocation(fieldDesc).getLocIdentifier(); + if (!getLattice(cd).containsKey(locIdentifier)) { + getLattice(cd).put(locIdentifier); + } + } + + String fieldLatticeDefStr = generateLatticeDefinition(cd); + String annoatedSrc = fieldLatticeDefStr + newline + sourceVec.get(classDefLine); + sourceVec.set(classDefLine, annoatedSrc); + + // generate annotations for field declarations + LocationInfo fieldLocInfo = getLocationInfo(cd); + Map inferLocMap = fieldLocInfo.getMapDescToInferLocation(); + + for (Iterator iter = cd.getFields(); iter.hasNext();) { + FieldDescriptor fd = (FieldDescriptor) iter.next(); + + String locAnnotationStr; + if (inferLocMap.containsKey(fd)) { + CompositeLocation inferLoc = inferLocMap.get(fd); + locAnnotationStr = generateLocationAnnoatation(inferLoc); + } else { + // if the field is not accssed by SS part, just assigns dummy + // location + locAnnotationStr = "@LOC(\"LOC\")"; + } + int fdLineNum = fd.getLineNum(); + String orgFieldDeclarationStr = sourceVec.get(fdLineNum); + String fieldDeclaration = fd.toString(); + fieldDeclaration = fieldDeclaration.substring(0, fieldDeclaration.length() - 1); + + int idx = orgFieldDeclarationStr.indexOf(fieldDeclaration); + String annoatedStr = + orgFieldDeclarationStr.substring(0, idx) + locAnnotationStr + " " + + orgFieldDeclarationStr.substring(idx); + sourceVec.set(fdLineNum, annoatedStr); + + } + + } + + while (!toAnalyzeMethodIsEmpty()) { + MethodDescriptor md = toAnalyzeMethodNext(); + SSJavaLattice methodLattice = md2lattice.get(md); + if (methodLattice != null) { + + int methodDefLine = md.getLineNum(); + + MethodLocationInfo methodLocInfo = getMethodLocationInfo(md); + + Map inferLocMap = + methodLocInfo.getMapDescToInferLocation(); + Set localVarDescSet = inferLocMap.keySet(); + + for (Iterator iterator = localVarDescSet.iterator(); iterator.hasNext();) { + Descriptor localVarDesc = (Descriptor) iterator.next(); + CompositeLocation inferLoc = inferLocMap.get(localVarDesc); + + String locAnnotationStr = generateLocationAnnoatation(inferLoc); + + if (!isParameter(md, localVarDesc)) { + if (mapDescToDefinitionLine.containsKey(localVarDesc)) { + int varLineNum = mapDescToDefinitionLine.get(localVarDesc); + + String orgSourceLine = sourceVec.get(varLineNum); + int idx = orgSourceLine.indexOf(localVarDesc.toString()); + String annoatedStr = + orgSourceLine.substring(0, idx) + locAnnotationStr + " " + + orgSourceLine.substring(idx); + sourceVec.set(varLineNum, annoatedStr); + } + } else { + String methodDefStr = sourceVec.get(methodDefLine); + int idx = methodDefStr.indexOf(localVarDesc.toString()); + assert (idx != -1); + String annoatedStr = + methodDefStr.substring(0, idx) + locAnnotationStr + " " + + methodDefStr.substring(idx); + sourceVec.set(methodDefLine, annoatedStr); + } + + } + + String methodLatticeDefStr = generateLatticeDefinition(md); + String annoatedStr = methodLatticeDefStr + newline + sourceVec.get(methodDefLine); + sourceVec.set(methodDefLine, annoatedStr); + + } + } + } + + codeGen(); + } + + private String generateLocationAnnoatation(CompositeLocation loc) { + String rtr = "@LOC(\""; + + // method location + Location methodLoc = loc.get(0); + rtr += methodLoc.getLocIdentifier(); + + for (int i = 1; i < loc.getSize(); i++) { + Location element = loc.get(i); + rtr += "," + element.getDescriptor().getSymbol() + "." + element.getLocIdentifier(); + } + + rtr += "\")"; + return rtr; + } + + private boolean isParameter(MethodDescriptor md, Descriptor localVarDesc) { + return getFlowGraph(md).isParamDesc(localVarDesc); + } + + private String extractFileName(String fileName) { + int idx = fileName.lastIndexOf("/"); + if (idx == -1) { + return fileName; + } else { + return fileName.substring(idx + 1); + } + + } + + private void codeGen() { + + Set originalFileNameSet = mapFileNameToLineVector.keySet(); + for (Iterator iterator = originalFileNameSet.iterator(); iterator.hasNext();) { + String orgFileName = (String) iterator.next(); + String outputFileName = extractFileName(orgFileName); + + Vector sourceVec = mapFileNameToLineVector.get(orgFileName); + + try { + + FileWriter fileWriter = new FileWriter("./infer/" + outputFileName); + BufferedWriter out = new BufferedWriter(fileWriter); + + for (int i = 0; i < sourceVec.size(); i++) { + out.write(sourceVec.get(i)); + out.newLine(); + } + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } private void simplifyLattices() { @@ -184,11 +490,9 @@ public class LocationInference { while (!toAnalyzeMethodIsEmpty()) { MethodDescriptor md = toAnalyzeMethodNext(); - if (ssjava.needTobeAnnotated(md)) { - SSJavaLattice methodLattice = md2lattice.get(md); - if (methodLattice != null) { - methodLattice.removeRedundantEdges(); - } + SSJavaLattice methodLattice = md2lattice.get(md); + if (methodLattice != null) { + methodLattice.removeRedundantEdges(); } } } @@ -234,12 +538,10 @@ public class LocationInference { while (!toAnalyzeMethodIsEmpty()) { MethodDescriptor md = toAnalyzeMethodNext(); - if (ssjava.needTobeAnnotated(md)) { - SSJavaLattice methodLattice = md2lattice.get(md); - if (methodLattice != null) { - ssjava.writeLatticeDotFile(cd, md, methodLattice); - debug_printDescriptorToLocNameMapping(md); - } + SSJavaLattice methodLattice = md2lattice.get(md); + if (methodLattice != null) { + ssjava.writeLatticeDotFile(cd, md, methodLattice); + debug_printDescriptorToLocNameMapping(md); } } } @@ -512,6 +814,18 @@ public class LocationInference { } } + for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { + FlowNode flowNode = (FlowNode) iterator.next(); + if (flowNode.isDeclaratonNode()) { + CompositeLocation inferLoc = methodInfo.getInferLocation(flowNode.getDescTuple().get(0)); + String locIdentifier = inferLoc.get(0).getLocIdentifier(); + if (!methodLattice.containsKey(locIdentifier)) { + methodLattice.put(locIdentifier); + } + + } + } + // create mapping from param idx to inferred composite location int offset; @@ -1533,9 +1847,11 @@ public class LocationInference { DeclarationNode dn, NodeTupleSet implicitFlowTupleSet) { VarDescriptor vd = dn.getVarDescriptor(); + mapDescToDefinitionLine.put(vd, dn.getNumLine()); NTuple tupleLHS = new NTuple(); tupleLHS.add(vd); - getFlowGraph(md).createNewFlowNode(tupleLHS); + FlowNode fn = getFlowGraph(md).createNewFlowNode(tupleLHS); + fn.setDeclarationNode(); if (dn.getExpression() != null) { diff --git a/Robust/src/Analysis/SSJava/SSJavaAnalysis.java b/Robust/src/Analysis/SSJava/SSJavaAnalysis.java index e95766fd..84c8b3e3 100644 --- a/Robust/src/Analysis/SSJava/SSJavaAnalysis.java +++ b/Robust/src/Analysis/SSJava/SSJavaAnalysis.java @@ -133,8 +133,11 @@ public class SSJavaAnalysis { public void doCheck() { doMethodAnnotationCheck(); - computeLinearTypeCheckMethodSet(); - doLinearTypeCheck(); + + if (state.SSJAVA) { + computeLinearTypeCheckMethodSet(); + doLinearTypeCheck(); + } init(); @@ -262,6 +265,10 @@ public class SSJavaAnalysis { methodAnnotationChecker = new MethodAnnotationCheck(this, state, tu); methodAnnotationChecker.methodAnnoatationCheck(); methodAnnotationChecker.methodAnnoataionInheritanceCheck(); + if (state.SSJAVAINFER) { + annotationRequireClassSet.add(methodContainingSSJavaLoop.getClassDesc()); + annotationRequireSet.add(methodContainingSSJavaLoop); + } state.setAnnotationRequireSet(annotationRequireSet); } diff --git a/Robust/src/IR/FieldDescriptor.java b/Robust/src/IR/FieldDescriptor.java index d2e50ac5..b48a13f6 100644 --- a/Robust/src/IR/FieldDescriptor.java +++ b/Robust/src/IR/FieldDescriptor.java @@ -20,6 +20,7 @@ public class FieldDescriptor extends Descriptor { private boolean isenum; private int enumvalue; private boolean isEnumClass; + private int lineNum; private ClassDescriptor cn; @@ -117,5 +118,13 @@ public class FieldDescriptor extends Descriptor { public boolean isEnumClass() { return this.isEnumClass; } + + public void setLineNum(int n){ + lineNum=n; + } + + public int getLineNum(){ + return lineNum; + } } diff --git a/Robust/src/IR/MethodDescriptor.java b/Robust/src/IR/MethodDescriptor.java index 924b83d1..d8e2ea0d 100644 --- a/Robust/src/IR/MethodDescriptor.java +++ b/Robust/src/IR/MethodDescriptor.java @@ -23,6 +23,9 @@ public class MethodDescriptor extends Descriptor { protected boolean isinvokedbystatic; // flag to indicate if this method is invoked by some static block protected boolean isdefaultconstructor; // flag to indicate if this is a default constructor + + private int lineNum; + public MethodDescriptor(Modifiers m, TypeDescriptor rt, String identifier) { super(identifier); @@ -224,4 +227,29 @@ public class MethodDescriptor extends Descriptor { public void setDefaultConstructor() { this.isdefaultconstructor = true; } + + public String getMethodDeclaration(){ + String st=""; + String type=""; + if (returntype != null) + st = modifier.toString() + returntype.toString() + " " + type + identifier + "("; + else + st = modifier.toString() + identifier + "("; + for (int i = 0; i < params.size(); i++) { + st += getParamType(i) + " " + getParamName(i); + if ((i + 1) != params.size()) + st += ", "; + } + st += ")"; + return st; + } + + public void setLineNum(int n){ + lineNum=n; + } + + public int getLineNum(){ + return lineNum; + } + } diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index c8efb8e7..54b49d9b 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -1027,7 +1027,9 @@ private void addOuterClassReferences( ClassDescriptor cn, ClassDescriptor ocn, i } } - cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal)); + FieldDescriptor fd=new FieldDescriptor(m, arrayt, identifier, en, isglobal); + fd.setLineNum(tmp.getLine()); + cn.addField(fd); assignAnnotationsToType(m,arrayt); } } @@ -1826,7 +1828,8 @@ private void addOuterClassReferences( ClassDescriptor cn, ClassDescriptor ocn, i ParseNode pmd=pn.getChild("method_declarator"); String name=pmd.getChild("name").getTerminal(); MethodDescriptor md=new MethodDescriptor(m, returntype, name); - + md.setLineNum(pmd.getLine()); + ParseNode paramnode=pmd.getChild("parameters"); parseParameterList(md,paramnode); return md; diff --git a/Robust/src/buildscript b/Robust/src/buildscript index e1b2566d..8a7b7a9a 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -184,6 +184,8 @@ tmpbuilddirectory="tmpbuilddirectory" JNI=false SSJAVA=false USE_SSJAVA_CLASSPATH=false +USE_SSJAVA_INFER_CLASSPATH=false +USE_SSJAVA_NOCLASSPATH=false SRCAFTERPP=false; COREPROF=false; NUMA=false; @@ -696,8 +698,13 @@ elif [[ $1 = '-ssjavadebug' ]] then JAVAOPTS="$JAVAOPTS -ssjavadebug" +elif [[ $1 = '-ssjavanoclasspath' ]] +then +USE_SSJAVA_NOCLASSPATH=true + elif [[ $1 = '-ssjavainfer' ]] then +USE_SSJAVA_INFER_CLASSPATH=true JAVAOPTS="$JAVAOPTS -ssjavainfer" elif [[ $1 = '-ssjava-inject-error' ]] @@ -906,7 +913,13 @@ elif $MGCFLAG elif $USE_SSJAVA_CLASSPATH then - JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/SSJava" + if $USE_SSJAVA_INFER_CLASSPATH + then + JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/SSJavaInfer" + elif ! $USE_SSJAVA_INFER_NOCLASSPATH + then + JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/SSJava" + fi else JAVAOPTS="$JAVAOPTS -classlibrary $ROBUSTROOT/ClassLibrary/ -classlibrary $ROBUSTROOT/ClassLibrary/gnu/"