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

ClassInfo.java

00001 package gov.nasa.arc.ase.jpf.jvm;
00002 
00003 import de.fub.bytecode.*;
00004 import de.fub.bytecode.classfile.*;
00005 import de.fub.bytecode.generic.*;
00006 import gov.nasa.arc.ase.jpf.*;
00007 import gov.nasa.arc.ase.jpf.jvm.reflection.Reflection;
00008 import gov.nasa.arc.ase.util.Debug;
00009 import java.io.*;
00010 import java.util.*;
00011 // ifdef RACE
00012 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00013 //#endif RACE
00014 
00015 public class ClassInfo {
00016   // from JavaClass
00017   private JavaClass       classData;
00018   // Used for constant pool resolution (from JavaClass)
00019   private ConstantPoolGen classConstantPool;
00020   // List of all methods in class
00021   private Hashtable       methodList = new Hashtable();
00022   // List of all dynamic fields in object
00023   private Field[]     dynamicFields;
00024   // List of all static fields in object
00025   private Field[]     staticFields;
00026   // Safe Blocks for this Class
00027   private SafeBlocks      safeBlocks;
00028   // unique id (not private)
00029   //  int id;
00030   // ClassInfo for its superClass
00031   private ClassInfo       superClass;
00032 
00033   private static String[] reflectionPath = {
00034     "gov.nasa.arc.ase.jpf.jvm.reflection", ""
00035   };
00036 
00037   Hashtable fieldNames = new Hashtable();
00038 
00039   Reflection reflection = null;
00040 
00041   private static String[] classPath = null;
00042 
00043   // creates a new class info object
00044   public ClassInfo(JavaClass cd) {
00045 //    id = IDS.class_id++;
00046 
00047     classData = cd;
00048 
00049     if(Engine.options.po_reduction)
00050       loadSafeBlocks(cd);
00051     else
00052       safeBlocks = null;
00053 
00054     classConstantPool =  new ConstantPoolGen(cd.getConstantPool());
00055 
00056     // init fields
00057     int nsfields = 0;
00058     int ndfields = 0;
00059     Field[] fields = classData.getFields();
00060     for(int i = 0, l = fields.length; i < l; i++)
00061       if(fields[i].isStatic())
00062     nsfields++;
00063       else
00064     ndfields++;
00065 
00066     JavaClass jc = JPFVM.getJPFVM().loadClassData(classData.getSuperclassName());
00067     while(!jc.getClassName().equals("java.lang.Object")) {
00068       fields = jc.getFields();
00069       for(int i = 0, l = fields.length; i < l; i++)
00070     if(!fields[i].isStatic())
00071       ndfields++;
00072       jc = JPFVM.getJPFVM().loadClassData(jc.getSuperclassName());
00073     }
00074 
00075     staticFields = new Field[nsfields];
00076     dynamicFields = new Field[ndfields];
00077 
00078     int sfc = 0;
00079     int dfc = 0;
00080     
00081     fields = classData.getFields();
00082     for(int i = 0, l = fields.length; i < l; i++)
00083       if(fields[i].isStatic())
00084     staticFields[sfc++] = fields[i];
00085       else
00086     dynamicFields[dfc++] = fields[i];
00087 
00088     jc = JPFVM.getJPFVM().loadClassData(classData.getSuperclassName());
00089     while(!jc.getClassName().equals("java.lang.Object")) {
00090       fields = jc.getFields();
00091       for(int i = 0, l = fields.length; i < l; i++)
00092     if(!fields[i].isStatic())
00093       dynamicFields[dfc++] = fields[i];
00094       jc = JPFVM.getJPFVM().loadClassData(jc.getSuperclassName());
00095     }
00096 
00097     // init methods 
00098     Method[] methods = cd.getMethods();
00099     for(int i = 0, s = methods.length; i < s; i++) {
00100       Method m = methods[i];
00101       MethodInfo mi = new MethodInfo(m, this, classConstantPool);
00102       methodList.put(mi.getMethodName()+m.getSignature(), mi);
00103     }
00104 
00105     String superName = cd.getSuperclassName();
00106 
00107     if (cd.getClassName().equals("java.lang.Object")) {
00108 // ifdef DEBUG
00109 
00110 //#endif DEBUG
00111       superClass = null;      
00112     } else {
00113 // ifdef DEBUG
00114 
00115 
00116 //#endif DEBUG
00117       superClass = JPFVM.getJPFVM().getClass(superName);            
00118     }
00119 
00120     initFields();
00121 
00122     setReflection(cd.getClassName());
00123   }  
00124   public long callMethod(SystemState ss, KernelState ks, ThreadInfo th, String name, int[] args) {
00125     Reflection r = (Reflection)reflection.clone();
00126     r.setState(ss, ks, th);
00127     r.setObjectReference(args[0]);
00128 
00129     return r.callMethod(name, args);
00130   }  
00131   public long callStaticMethod(SystemState ss, KernelState ks, ThreadInfo th, String name, int[] args) {
00132     reflection.setState(ss, ks, th);
00133 
00134     return reflection.callStaticMethod(name, args);
00135   }  
00136   public Fields createFields() {
00137     Field[] fs = dynamicFields;
00138     Fields f = new Fields(this, fs.length);
00139     for(int i = 0, l = fs.length; i < l; i++) {
00140       f.setValue(i, Types.newValue(fs[i].getSignature()));
00141 // ifdef MARK_N_SWEEP
00142       if(Types.isReference(fs[i].getSignature()))
00143     f.setValueRef(i);
00144 //#endif MARK_N_SWEEP
00145     }
00146 
00147     return f;
00148   }  
00149   public Fields createStaticFields() {
00150     Field[] fs = staticFields;
00151     Fields f = new Fields(this, fs.length);
00152     for(int i = 0, l = fs.length; i < l; i++) {
00153       f.setValue(i, Types.newValue(fs[i].getSignature()));
00154 // ifdef MARK_N_SWEEP
00155       if(Types.isReference(fs[i].getSignature()))
00156     f.setValueRef(i);
00157 //#endif MARK_N_SWEEP
00158     }
00159 
00160     return f;
00161   }  
00162 // ifdef RACE
00163   private void DEPEND_ExecuteMainMethod(ThreadInfo th){
00164     if (Depend.on()){
00165       Depend.addMain(th);
00166     }
00167   }  
00168 //#endif RACE
00169 
00170   // executes the main method (just puts the frame on the stack)
00171   public ThreadInfo executeMain(KernelState ks, int classref) {
00172     ThreadInfo th = new ThreadInfo();
00173     ks.newThread(th);
00174 
00175     th.setStatus(STATUS.RUNNING);
00176     th.setClassInfo(this);
00177     th.setReference(new ClassRef(classref));
00178     th.newFrame(getMethodInfo("main([Ljava/lang/String;)V"));
00179 
00180     //** missing: we do not consider command line arguments yet **//
00181     th.setLocalVariable(0, (int)Types.newValue("[Ljava/lang/String;"));
00182 // ifdef MARK_N_SWEEP
00183     th.setLocalVariableRef(0);
00184 //#endif MARK_N_SWEEP
00185 
00186 // ifdef DEBUG
00187 
00188 //#endif DEBUG
00189 
00190 // ifdef RACE
00191     DEPEND_ExecuteMainMethod(th);
00192 //#endif RACE
00193 
00194     return th;
00195   }  
00196   public InstructionHandle executeMethod(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00197     MethodInfo mi = getMethodInfo(name);
00198     boolean atomic = TransitionResult.isAtomic();
00199     String cn = classData.getClassName();
00200 
00201     if(cn.startsWith("java.lang.") || cn.startsWith("java.util."))
00202       atomic = true;
00203 
00204     Reflection r = (Reflection)reflection.clone();
00205     r.setState(ss, ks, th);
00206     r.setObjectReference(th.getCalleeThis(mi.getArgumentSize()));
00207 
00208     th.createMethodStackFrame(mi);
00209 
00210     return r.executeMethod(mi, atomic);
00211   }  
00212   public InstructionHandle executeStaticMethod(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00213     MethodInfo mi = getMethodInfo(name);
00214     boolean atomic = TransitionResult.isAtomic();
00215     String cn = classData.getClassName();
00216 
00217     if(cn.startsWith("java.lang.") || cn.startsWith("java.util."))
00218       atomic = true;
00219 
00220     if(name.equals("<clinit>()V") && VirtualMachine.options.atomic_init)
00221       atomic = true;
00222 
00223     reflection.setState(ss, ks, th);
00224 
00225     th.createMethodStackFrame(mi);
00226 
00227     return reflection.executeStaticMethod(mi, atomic);
00228   }  
00229   public JavaClass getClassData() {
00230     return classData;
00231   }  
00232   public String getClassName() {
00233     return classData.getClassName();
00234   }  
00235   public ConstantPoolGen getCPG() {
00236     return classConstantPool;
00237   }  
00238   public Field[] getDynamicFields() {
00239     return dynamicFields;
00240   }  
00241   public String getFieldName(int index) {
00242     return (String)fieldNames.get(new Integer(index));
00243   }  
00244   public int getFieldType(int index) {
00245     return Type.getType(dynamicFields[index].getSignature()).getType();
00246   }  
00247   public int getFieldType(String fname) {
00248     int index = ((Integer)fieldNames.get(fname)).intValue();
00249 
00250     return Type.getType(dynamicFields[index].getSignature()).getType();
00251   }  
00252   public MethodInfo getMethodInfo(String name) {
00253     MethodInfo mi = (MethodInfo) methodList.get(name);
00254     if (mi == null) {
00255       if (name.equals("<clinit>()V")) // special case: don't look
00256     return null;                    // further if it is class init
00257 // ifdef DEBUG
00258 
00259 
00260 //#endif DEBUG
00261       if (superClass == null) {
00262     Debug.println(Debug.ERROR, "Method not found: " + name);
00263     System.exit(0);
00264       }
00265       return superClass.getMethodInfo(name);
00266     }
00267     else 
00268       return mi;
00269   }  
00270   public Field[] getStaticFields() {
00271     return staticFields;
00272   }  
00273   public int getStaticFieldType(int index) {
00274     return Type.getType(staticFields[index].getSignature()).getType();
00275   }  
00276   public int getStaticFieldType(String fname) {
00277     int index = ((Integer)fieldNames.get(fname)).intValue();
00278 
00279     return Type.getType(staticFields[index].getSignature()).getType();
00280   }  
00281   public ClassInfo getSuperClassInfo() {
00282     return superClass;
00283   }  
00284   private void initFields() {
00285     Field[] fs = dynamicFields;
00286     for(int i = 0, s = fs.length; i < s; i++)
00287       fieldNames.put(fs[i].getName(), new Integer(i));
00288     
00289     fs = getStaticFields();
00290     for(int i = 0, s = fs.length; i < s; i++)
00291       fieldNames.put(fs[i].getName(), new Integer(i));
00292   }  
00293   // executes the class init for the specific class.
00294   public InstructionHandle initialize(SystemState ss, KernelState ks, ThreadInfo th) {
00295     if(methodList.get("<clinit>()V") == null) return th.getPC();
00296 
00297     return executeStaticMethod(ss, ks, th, "<clinit>()V");
00298   }  
00299   public boolean isMethodDeterministic(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00300     MethodInfo mi = getMethodInfo(name);
00301 
00302     Reflection r = (Reflection)reflection.clone();
00303     r.setState(ss, ks, th);
00304     r.setObjectReference(th.getCalleeThis(mi.getArgumentSize()));
00305 
00306     return r.isMethodDeterministic(mi);
00307   }  
00308   public boolean isMethodExecutable(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00309     MethodInfo mi = getMethodInfo(name);
00310 
00311     Reflection r = (Reflection)reflection.clone();
00312     r.setState(ss, ks, th);
00313     r.setObjectReference(th.getCalleeThis(mi.getArgumentSize()));
00314 
00315     int stacksize = th.size();
00316     return r.isMethodExecutable(mi);
00317   }  
00318   public boolean isSafe(int line) {
00319     if (safeBlocks == null)
00320       return false;
00321     else
00322       return safeBlocks.isSafe(line);
00323   }  
00324   public boolean isStaticMethodDeterministic(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00325     MethodInfo mi = getMethodInfo(name);
00326 
00327     reflection.setState(ss, ks, th);
00328 
00329     return reflection.isStaticMethodDeterministic(mi);
00330   }  
00331   public boolean isStaticMethodExecutable(SystemState ss, KernelState ks, ThreadInfo th, String name) {
00332     MethodInfo mi = getMethodInfo(name);
00333 
00334     reflection.setState(ss, ks, th);
00335 
00336     return reflection.isStaticMethodExecutable(mi);
00337   }  
00338   public boolean isThread() {
00339     ClassInfo ci = this;
00340 
00341     while (ci != null) {
00342       if (ci.getClassName().equals("java.lang.Thread"))
00343     return true;
00344       ci = ci.superClass;
00345     }
00346 
00347     return false;
00348   }  
00349   private void loadSafeBlocks(JavaClass cd) {
00350     if(classPath == null) setClassPath();
00351 
00352     // read in safe blocks if they exist
00353     String name = cd.getClassName().replace('.', '/');
00354 
00355     for(int i = 0; i < classPath.length; i++)
00356       try {
00357     String filename = classPath[i] + "/" + name + ".safe";
00358     BufferedReader in = new BufferedReader(new FileReader(filename));       
00359     Debug.println(Debug.WARNING, "Loading " + filename);
00360     safeBlocks = new SafeBlocks(in);
00361 
00362     return;
00363       } catch (FileNotFoundException e) {
00364       }
00365 
00366     safeBlocks = null;
00367   }  
00368   public String reflectionClassName(String name) {
00369     int index = 0;
00370     int last = 0;
00371     StringBuffer sb = new StringBuffer();
00372 
00373     while((index = name.indexOf(".", last)) != -1) {
00374       sb.append(Character.toUpperCase(name.charAt(last)));
00375       sb.append(name.substring(last + 1, index));
00376       last = index + 1;
00377     }
00378     sb.append(name.substring(last));
00379 
00380     return sb.toString();
00381   }  
00382   private static void setClassPath() {
00383     StringTokenizer st = new StringTokenizer(System.getProperty("java.class.path"), ":");
00384     classPath = new String[st.countTokens()];
00385     for(int i = 0; st.hasMoreTokens(); i++)
00386       classPath[i] = st.nextToken();
00387   }  
00388   private void setReflection(String name) {
00389     int l = reflectionPath.length;
00390 
00391     for(int i = 0; i < l && reflection == null; i++) {
00392       String cn;
00393 
00394       if(reflectionPath[i].equals(""))
00395     cn = name + "Reflection";
00396       else
00397     cn = reflectionPath[i] + "." + name + "Reflection";
00398       try {
00399     Class clazz = Class.forName(cn);
00400     reflection = (Reflection)clazz.newInstance();
00401     Debug.println(Debug.WARNING, "Loading class " + cn);
00402       } catch(InstantiationException e) {
00403     Debug.println(Debug.ERROR, "Can't instantiate " + cn);
00404     System.exit(1);
00405       } catch(IllegalAccessException e) {
00406     Debug.println(Debug.ERROR, "Can't instantiate " + cn);
00407     System.exit(1);
00408       } catch(ClassNotFoundException e) {
00409       }
00410     }
00411 
00412     for(int i = 0; i < l && reflection == null; i++) {
00413       String cn;
00414       if(reflectionPath[i].equals(""))
00415     cn = reflectionClassName(name) + "Reflection";
00416       else
00417     cn = reflectionPath[i] + "." + reflectionClassName(name) + "Reflection";
00418       try {
00419     Class clazz = Class.forName(cn);
00420     reflection = (Reflection)clazz.newInstance();
00421     Debug.println(Debug.WARNING, "Loading class " + cn);
00422       } catch(InstantiationException e) {
00423     Debug.println(Debug.ERROR, "Can't instantiate " + cn);
00424     System.exit(1);
00425       } catch(IllegalAccessException e) {
00426     Debug.println(Debug.ERROR, "Can't instantiate " + cn);
00427     System.exit(1);
00428       } catch(ClassNotFoundException e) {
00429       }
00430     }
00431 
00432     if(reflection == null)
00433       reflection = new Reflection();
00434 
00435     reflection.setClassInfo(this);
00436   }  
00437 }

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