Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

BIRCTraceManager.java

00001 package edu.ksu.cis.bandera.bui.counterexample;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@cis.ksu.edu)                    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import java.lang.reflect.Method;
00036 import javax.swing.*;
00037 import javax.swing.tree.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 import edu.ksu.cis.bandera.jjjc.*;
00041 import edu.ksu.cis.bandera.annotation.*;
00042 import edu.ksu.cis.bandera.birc.*;
00043 import edu.ksu.cis.bandera.jext.*;
00044 import java.util.*;
00045 import edu.ksu.cis.bandera.abstraction.*;
00046 import edu.ksu.cis.bandera.abstraction.typeinference.*;
00047 public class BIRCTraceManager implements TraceManager {
00048     private static Jimple jimple = Jimple.v();
00049     private TypeTable typeTable;
00050     private AnnotationManager am = CompilationManager.getAnnotationManager();
00051     private SootClassManager scm = CompilationManager.getSootClassManager();
00052     private Vector threadAnnotations = new Vector();
00053     private Vector threadTreeModels = new Vector();
00054     private Vector annotationTrace = new Vector();
00055     private Vector stmtIndexTrace = new Vector();
00056     private Hashtable valueNodeValueTable;
00057     private JimpleTrace trace;
00058     private int traceLength;
00059     private Stmt[] stmts;
00060     private JimpleStore currentStore;
00061     private Vector threads;
00062     private int currentStep = 0;
00063 /**
00064  * BIRCTraceManager constructor comment.
00065  */
00066 public BIRCTraceManager(JimpleTrace trace, TypeTable typeTable) {
00067     this.trace = trace;
00068     this.am = CompilationManager.getAnnotationManager();
00069     this.scm = CompilationManager.getSootClassManager();
00070     this.typeTable = typeTable;
00071     stmts = trace.getStatements();
00072     for (int i = 0; i < stmts.length; i++) {
00073         try {
00074             Annotation a = am.getContainingAnnotation((Stmt) stmts[i]);
00075             if ("edu.ksu.cis.bandera.annotation.SequentialAnnotation".equals(a.getClass().getName())) continue;
00076             if (annotationTrace.size() > 0) {
00077                 if (a != annotationTrace.lastElement()) {
00078                     stmtIndexTrace.add(new Integer(i));
00079                     annotationTrace.add(a);
00080                     System.out.println(a.getClass().getName() + ":" + a);
00081                 }
00082             } else {
00083                 stmtIndexTrace.add(new Integer(i));
00084                 annotationTrace.add(a);
00085                 System.out.println(a.getClass().getName() + ":" + a);
00086             }
00087         } catch (Exception e) {
00088             System.out.println("Couldn't find annotation for " + stmts[i]);
00089         }
00090     }
00091     traceLength = annotationTrace.size();
00092     currentStore = trace.getStore(0);
00093     threads = currentStore.getThreads();
00094     threadTreeModels.setSize(threads.size());
00095     threadAnnotations.setSize(threads.size());
00096     reset();
00097 }
00098 /**
00099  * back method comment.
00100  */
00101 public void back() {
00102     int index = ((Integer) stmtIndexTrace.elementAt(--currentStep)).intValue();
00103     Annotation a = (Annotation) annotationTrace.elementAt(currentStep);
00104     currentStore = trace.getStore(index);
00105     currentStore.print();
00106     int tid = 0;
00107     for (Iterator i = threads.iterator(); i.hasNext(); tid++) {
00108         SootMethod sm = (SootMethod) i.next();
00109         if (((JimpleBody) sm.getBody(jimple)).getStmtList().indexOf(stmts[index]) >= 0) {
00110             threadAnnotations.setElementAt(a, tid);
00111             break;
00112         }
00113     }
00114 }
00115 /**
00116  * cleanup method comment.
00117  */
00118 public void cleanup() {}
00119 /**
00120  * forward method comment.
00121  */
00122 public void forward() {
00123     if (currentStep == traceLength-1) {
00124         currentStore = trace.getLastStore();
00125         currentStore.print();
00126         currentStep++;
00127         return;
00128     }
00129     int index = ((Integer) stmtIndexTrace.elementAt(++currentStep)).intValue();
00130     currentStore = trace.getStore(index);
00131     currentStore.print();
00132     Annotation a = (Annotation) annotationTrace.elementAt(currentStep);
00133     int tid = 0;
00134     for (Iterator i = threads.iterator(); i.hasNext(); tid++) {
00135         SootMethod sm = (SootMethod) i.next();
00136         if (((JimpleBody) sm.getBody(jimple)).getStmtList().indexOf(stmts[index]) >= 0) {
00137             System.out.println("ThID: " + tid + ", annotation: " + a);
00138             threadAnnotations.setElementAt(a, tid);
00139             break;
00140         }
00141     }
00142 }
00143 /**
00144  * 
00145  * @return java.lang.String
00146  * @param type java.lang.Object
00147  * @param value int
00148  */
00149 private String getAbstractToken(Object type, int value) {
00150     String className = type.getClass().getName();
00151     String methodName = "getToken";
00152     try {
00153         Class cls = Class.forName(className);
00154         Method mtd = cls.getMethod(methodName, new Class[] {int.class});
00155         return (String) mtd.invoke(null, new Object[] {new Integer(value)});
00156     } catch (Exception e) {
00157         return "" + value;
00158     }
00159 }
00160 /**
00161  * getAnnotation method comment.
00162  */
00163 public edu.ksu.cis.bandera.annotation.Annotation getAnnotation() {
00164     if (currentStep == traceLength) return (Annotation) annotationTrace.elementAt(currentStep - 1);
00165     return (Annotation) annotationTrace.elementAt(currentStep);
00166 }
00167 /**
00168  * getAnnotation method comment.
00169  */
00170 public edu.ksu.cis.bandera.annotation.Annotation getAnnotation(int threadID) {
00171     return (Annotation) threadAnnotations.elementAt(threadID);
00172 }
00173 /**
00174  * 
00175  * @return edu.ksu.cis.bandera.birc.JimpleLiteral
00176  * @param topMethod ca.mcgill.sable.soot.SootMethod
00177  * @param realMethod ca.mcgill.sable.soot.SootMethod
00178  * @param local ca.mcgill.sable.soot.jimple.Local
00179  */
00180 private JimpleLiteral getLocalValue(SootMethod topMethod, SootMethod realMethod, Local local) {
00181     System.out.println(topMethod + ";" + realMethod + ";" + local);
00182     if (topMethod == realMethod) return currentStore.getLocalValue(topMethod, local);
00183     Vector v = new Vector();
00184     HashSet inlinedLocal = am.getInlinedLocal(new LocalExpr(realMethod, local));
00185     if (inlinedLocal != null) {
00186         for (Iterator i = inlinedLocal.iterator(); i.hasNext();) {
00187             LocalExpr le = (LocalExpr) i.next();
00188             if (le.getMethod() == topMethod) {
00189                 v.add(le.getLocal());
00190             }
00191         }
00192     }
00193     if ((v.size() == 0) || (v.size() > 1)) {
00194         System.out.println("Unable to find value for <" + realMethod + ", " + local + ">, default to null");
00195         return null;
00196     } else {
00197         return currentStore.getLocalValue(topMethod, (Local) v.firstElement());
00198     }
00199 }
00200 /**
00201  * getNumOfSteps method comment.
00202  */
00203 public int getNumOfSteps() {
00204     return traceLength;
00205 }
00206 /**
00207  * getThreadTreeModels method comment.
00208  */
00209 public java.util.Vector getThreadTreeModels() {
00210     return threadTreeModels;
00211 }
00212 /**
00213  * getValueText method comment.
00214  */
00215 public String getValueText(javax.swing.tree.DefaultTreeModel model, javax.swing.tree.DefaultMutableTreeNode node) {
00216     if (!(node.getUserObject() instanceof ValueNode))
00217         return "";
00218     ValueNode vn = (ValueNode) node.getUserObject();
00219     Object literal = valueNodeValueTable.get(vn);
00220     if (literal == null)
00221         return "";
00222     if (literal instanceof ReferenceLiteral) {
00223         if (((ReferenceLiteral) literal).value == null)
00224             return "null";
00225         literal = ((ReferenceLiteral) literal).value;
00226         if (literal instanceof ArrayLiteral) {
00227             ArrayLiteral arrayLiteral = (ArrayLiteral) literal;
00228             if (node.getChildCount() == 0) {
00229                 int size = arrayLiteral.length;
00230                 for (int i = 0; i < size; i++) {
00231                     ValueNode vNode = new ValueNode(arrayLiteral, i);
00232                     model.insertNodeInto(new DefaultMutableTreeNode(vNode), node, node.getChildCount());
00233                     valueNodeValueTable.put(vNode, arrayLiteral.contents[i]);
00234                 }
00235             }
00236             return "#" + arrayLiteral.getId();
00237         } else {
00238                 ClassLiteral classLiteral = (ClassLiteral) literal;
00239                 if (node.getChildCount() == 0) {
00240                     SootClass sc = classLiteral.getSource();
00241                     for (ca.mcgill.sable.util.Iterator i = sc.getFields().iterator(); i.hasNext();) {
00242                         SootField sf = (SootField) i.next();
00243                         ValueNode vNode = new ValueNode(sf);
00244                         model.insertNodeInto(new DefaultMutableTreeNode(vNode), node, node.getChildCount());
00245                         valueNodeValueTable.put(vNode, classLiteral.getFieldValue(sf));
00246                     }
00247                 }
00248                 String result = "#" + classLiteral.getId() + "\nHolding: ";
00249                 LockLiteral lockLiteral = classLiteral.getLockValue();
00250                 if (threads.indexOf(lockLiteral.getHoldingThread()) != -1)
00251                     result += "Thread ID" + threads.indexOf(lockLiteral.getHoldingThread());
00252                 result += "\nWaiting: ";
00253                 for (int i = 0; i < lockLiteral.getNumWaiting(); i++) {
00254                     if (i == (lockLiteral.getNumWaiting() - 1)) {
00255                         result += ("ThreadID:" + threads.indexOf(lockLiteral.getWaitingThread(i)));
00256                     } else {
00257                         result += ("ThreadID:" + threads.indexOf(lockLiteral.getWaitingThread(i)) + ", ");
00258                     }
00259                 }
00260                 return result;
00261             }
00262     } else if (literal instanceof BooleanLiteral) {
00263         return "" + ((BooleanLiteral) literal).value;
00264     } else if (literal instanceof IntegerLiteral) {
00265         return "" + ((IntegerLiteral) literal).value;
00266     } else {
00267         return literal.toString();
00268     }
00269 }
00270 /**
00271  * getVariableTreeModel method comment.
00272  */
00273 public javax.swing.tree.TreeModel getVariableTreeModel() {
00274     valueNodeValueTable = new Hashtable();
00275     
00276     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Store");
00277 
00278     Hashtable compiledClasses = CompilationManager.getCompiledClasses();
00279     for (Enumeration e = compiledClasses.elements(); e.hasMoreElements();) {
00280         SootClass sc = (SootClass) e.nextElement();
00281         for (ca.mcgill.sable.util.Iterator i = sc.getFields().iterator(); i.hasNext();) {
00282             SootField sf = (SootField) i.next();
00283             if (Modifier.isStatic(sf.getModifiers())) {
00284                 Object o = currentStore.getStaticFieldValue(sf);
00285                 if (o != null) {
00286                     ValueNode vn = new ValueNode(sf);
00287                     Object t = typeTable.get(sf);
00288                     if ((t != null) && (t instanceof IntegralAbstraction) && !(t instanceof ConcreteIntegralAbstraction)) {
00289                         o = getAbstractToken(typeTable.get(sf), ((IntegerLiteral) o).value);
00290                     }
00291                     valueNodeValueTable.put(vn, o);
00292                     root.add(new DefaultMutableTreeNode(vn));
00293                 }
00294             }
00295         }
00296     }
00297 
00298     for (int i = 0; i < threadAnnotations.size(); i++) {
00299         threadTreeModels.setElementAt(null, i);
00300         if (!isAlive(i)) continue;
00301         Annotation a = (Annotation) threadAnnotations.elementAt(i);
00302         if (a == null) continue;
00303         Annotation ta = am.getMethodAnnotationContainingAnnotation(a);
00304         if ((a instanceof MethodDeclarationAnnotation)
00305                 || (a instanceof ConstructorDeclarationAnnotation)
00306                 || (a instanceof FieldDeclarationAnnotation)
00307                 || (a instanceof ClassDeclarationAnnotation))
00308             ta = a;
00309         Hashtable locals = a.getDeclaredLocalVariables();
00310         SootMethod sm;
00311         if (ta instanceof MethodDeclarationAnnotation) {
00312             sm = ((MethodDeclarationAnnotation) ta).getSootMethod();
00313             Hashtable parameters = ((MethodDeclarationAnnotation) ta).getParameterLocals();
00314             for (Enumeration e = parameters.keys(); e.hasMoreElements();) {
00315                 Object key = e.nextElement();
00316                 locals.put(key, parameters.get(key));
00317             }
00318         } else if (ta instanceof ConstructorDeclarationAnnotation) {
00319             sm = ((ConstructorDeclarationAnnotation) ta).getSootMethod();
00320             Hashtable parameters = ((ConstructorDeclarationAnnotation) ta).getParameterLocals();
00321             for (Enumeration e = parameters.keys(); e.hasMoreElements();) {
00322                 Object key = e.nextElement();
00323                 locals.put(key, parameters.get(key));
00324             }
00325         } else {
00326             DefaultMutableTreeNode node = new DefaultMutableTreeNode("Thread<no information available>, ID " + i);
00327             root.add(node);
00328             threadTreeModels.setElementAt(new DefaultTreeModel(node), i);
00329             continue;
00330         }
00331         DefaultMutableTreeNode mNode = new DefaultMutableTreeNode(new ValueNode(sm, i));
00332         if (!Modifier.isStatic(sm.getModifiers())) {
00333             Local lcl = ((JimpleBody) sm.getBody(jimple)).getLocal("JJJCTEMP$0");
00334             Object o = getLocalValue((SootMethod) threads.elementAt(i), sm, lcl);
00335             if (o != null) {
00336                 ValueNode vn = new ValueNode(lcl);
00337                 mNode.add(new DefaultMutableTreeNode(vn));
00338                 valueNodeValueTable.put(vn, o);
00339             }
00340         }
00341         for (Enumeration e = locals.elements(); e.hasMoreElements();) {
00342             Local lcl = (Local) e.nextElement();
00343             Object o = getLocalValue((SootMethod) threads.elementAt(i), sm, lcl);
00344             if (o != null) {
00345                 Object t = typeTable.get(lcl);
00346                 if ((t != null) && (t instanceof IntegralAbstraction) && !(t instanceof ConcreteIntegralAbstraction)) {
00347                     o = getAbstractToken(typeTable.get(lcl), ((IntegerLiteral) o).value);
00348                 }
00349                 ValueNode vn = new ValueNode(lcl);
00350                 mNode.add(new DefaultMutableTreeNode(vn));
00351                 valueNodeValueTable.put(vn, o);
00352             }
00353         }
00354         root.add(mNode);
00355         threadTreeModels.setElementAt(new DefaultTreeModel(mNode), i);
00356     }
00357 
00358     return new DefaultTreeModel(root);
00359 }
00360 /**
00361  * isAlive method comment.
00362  */
00363 public boolean isAlive(int threadID) {
00364     return currentStore.isActive((SootMethod) threads.elementAt(threadID));
00365 }
00366 /**
00367  * reset method comment.
00368  */
00369 public void reset() {
00370     currentStep = 0;
00371     currentStore = trace.getStore(0);
00372     currentStore.print();
00373     Annotation a = (Annotation) annotationTrace.elementAt(0);
00374     int tid = 0;
00375     for (Iterator i = threads.iterator(); i.hasNext(); tid++) {
00376         SootMethod sm = (SootMethod) i.next();
00377         if (((JimpleBody) sm.getBody(jimple)).getStmtList().indexOf(stmts[0]) >= 0) {
00378             threadAnnotations.setElementAt(a, tid);
00379             break;
00380         }
00381     }
00382 }
00383 }

Generated at Thu Feb 7 06:40:51 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001