changes + annotation generation
authoryeom <yeom>
Mon, 13 Aug 2012 02:04:25 +0000 (02:04 +0000)
committeryeom <yeom>
Mon, 13 Aug 2012 02:04:25 +0000 (02:04 +0000)
Robust/src/Analysis/SSJava/FlowGraph.java
Robust/src/Analysis/SSJava/FlowNode.java
Robust/src/Analysis/SSJava/LocationInference.java
Robust/src/Analysis/SSJava/SSJavaAnalysis.java
Robust/src/IR/FieldDescriptor.java
Robust/src/IR/MethodDescriptor.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/buildscript

index 9018489c4b588108f9409bbc2a105f5baa5a5693..8522f2ef87284f6d319e8d1ab36cc8388fc05c89 100644 (file)
@@ -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<Descriptor> fromDescTuple, NTuple<Descriptor> toDescTuple) {
 
     FlowNode fromNode = mapDescTupleToInferNode.get(fromDescTuple);
index 7ce39ed50055c8c9b4be6140ee22259a3d83ff88..c24d57763bc1230c39031c5f6e4912eccacada84 100644 (file)
@@ -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<FlowNode> getFieldNodeSet() {
     return fieldNodeSet;
   }
@@ -143,4 +145,12 @@ public class FlowNode {
     id += ">";
     return id;
   }
+
+  public void setDeclarationNode() {
+    isDeclarationNode = true;
+  }
+
+  public boolean isDeclaratonNode() {
+    return isDeclarationNode;
+  }
 }
index 03cf57f7570eb5d6e96bd9df3ce4612423a1dbe1..c9877d8e611e19adf14d32137be2dcbb24cd819c 100644 (file)
@@ -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<MethodDescriptor, Set<MethodDescriptor>> mapMethodToCalleeSet;
 
+  private Map<String, Vector<String>> mapFileNameToLineVector;
+
+  private Map<Descriptor, Integer> 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<MethodDescriptor, MethodLocationInfo>();
     this.mapMethodToCalleeSet = new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
     this.mapClassToLocationInfo = new HashMap<ClassDescriptor, LocationInfo>();
+
+    this.mapFileNameToLineVector = new HashMap<String, Vector<String>>();
+    this.mapDescToDefinitionLine = new HashMap<Descriptor, Integer>();
   }
 
   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<MethodDescriptor> 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<ClassDescriptor> classDescSet = new HashSet<ClassDescriptor>();
+    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<MethodDescriptor> methodSet = new HashSet<MethodDescriptor>();
+        methodSet.addAll(cd.getMethodTable().getValueSet());
+
+        String sourceFileName = cd.getSourceFileName();
+        Vector<String> lineVec = new Vector<String>();
+
+        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<String> lattice = getLattice(desc);
+    String rtr = "@LATTICE(\"";
+
+    Map<String, Set<String>> map = lattice.getTable();
+    Set<String> keySet = map.keySet();
+    boolean first = true;
+    for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+      String key = (String) iterator.next();
+      if (!key.equals(lattice.getTopItem())) {
+        Set<String> 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<String> sourceVec = mapFileNameToLineVector.get(sourceFileName);
+
+      if (locInfo != null) {
+
+        Map<Descriptor, CompositeLocation> mapDescToInferLoc = locInfo.getMapDescToInferLocation();
+        Set<Descriptor> 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<Descriptor, CompositeLocation> 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<String> methodLattice = md2lattice.get(md);
+        if (methodLattice != null) {
+
+          int methodDefLine = md.getLineNum();
+
+          MethodLocationInfo methodLocInfo = getMethodLocationInfo(md);
+
+          Map<Descriptor, CompositeLocation> inferLocMap =
+              methodLocInfo.getMapDescToInferLocation();
+          Set<Descriptor> 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<String> originalFileNameSet = mapFileNameToLineVector.keySet();
+    for (Iterator iterator = originalFileNameSet.iterator(); iterator.hasNext();) {
+      String orgFileName = (String) iterator.next();
+      String outputFileName = extractFileName(orgFileName);
+
+      Vector<String> 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<String> methodLattice = md2lattice.get(md);
-          if (methodLattice != null) {
-            methodLattice.removeRedundantEdges();
-          }
+        SSJavaLattice<String> 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<String> methodLattice = md2lattice.get(md);
-          if (methodLattice != null) {
-            ssjava.writeLatticeDotFile(cd, md, methodLattice);
-            debug_printDescriptorToLocNameMapping(md);
-          }
+        SSJavaLattice<String> 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<Descriptor> tupleLHS = new NTuple<Descriptor>();
     tupleLHS.add(vd);
-    getFlowGraph(md).createNewFlowNode(tupleLHS);
+    FlowNode fn = getFlowGraph(md).createNewFlowNode(tupleLHS);
+    fn.setDeclarationNode();
 
     if (dn.getExpression() != null) {
 
index e95766fd84714287c23a727f95d82206b1ec8190..84c8b3e3754c2f803f74b9078119f4c73f541efd 100644 (file)
@@ -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);
   }
 
index d2e50ac5342ece7e94ce0fba821742e65842bce0..b48a13f62b5e96295c62b72a7b02f3739cf4e47f 100644 (file)
@@ -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;
+  }
 
 }
index 924b83d12e3abe5e13792788abdbd339dba3abd1..d8e2ea0d739f583aa5e578eb48f2b7137a149151 100644 (file)
@@ -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;
+  }
+  
 }
index c8efb8e7bc29898770e26fdbb7b1bb8a90733140..54b49d9be0e32327e1bcf5678541e7c153a09e2a 100644 (file)
@@ -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;
index e1b2566dc1f407e1349abe50116975a414926a80..8a7b7a9a156ba3d36a1aa99a7b5f060539dcba47 100755 (executable)
@@ -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/"