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

Fields.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.util.Debug;
00008 import gov.nasa.arc.ase.util.HashData;
00009 import java.io.*;
00010 import java.util.*;
00011 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00012 import gov.nasa.arc.ase.util.BSet;
00013 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00014 
00015 /**
00016  * Represents the fields of an object or class.
00017  */
00018 public class Fields {
00019   /**
00020    * Type of the object or class.
00021    */
00022   private String type;
00023 
00024   /**
00025    * Reference to the class information.
00026    */
00027   private ClassInfo ci;
00028 
00029   /**
00030    * Set of values.
00031    */
00032   private int[] values;
00033 
00034   /**
00035    * The number of fields.
00036    */
00037   private int nFields;
00038 
00039   /**
00040    * Set to true if the fields belong to a class.
00041    */
00042   private boolean isClass;
00043 
00044 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00045 
00046   /**
00047    * Keeps track of which values are references.
00048    */
00049   //** warning: should keep one for each class.             **//
00050   BSet vRefs;
00051   
00052 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00053 
00054   /**
00055    * Creates a new empty fields object. Used by clone.
00056    */
00057   private Fields() {
00058   }  
00059   /**
00060    * Creates a new field object.
00061    */
00062   public Fields(String t,
00063       ClassInfo c,
00064       int size,
00065       int nf,
00066       boolean ic
00067 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00068       , BSet v
00069 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00070       ) {
00071     type = t;
00072     ci = c;
00073     values = new int[size];
00074     nFields = nf;
00075     isClass = ic;
00076 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00077     vRefs = v;
00078 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00079     initFields();
00080   }  
00081   /**
00082    * Creates a clone.
00083    */
00084   public Object clone() {
00085     Fields f = new Fields();
00086 
00087     f.type = type;
00088     f.ci = ci;
00089     f.values = new int[values.length];
00090     System.arraycopy(values, 0, f.values, 0, values.length);
00091     f.nFields = nFields;
00092     f.isClass = isClass;
00093 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00094     f.vRefs = vRefs;
00095 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00096     
00097     return f;
00098   }  
00099   /**
00100    * Number of fields.
00101    */
00102   public int countFields() {
00103     return nFields;
00104   }  
00105   /**
00106    * Checks for equality.
00107    */
00108   public boolean equals(Object o) {
00109     if(o == null) return false;
00110     if(!(o instanceof Fields)) return false;
00111 
00112     Fields f = (Fields)o;
00113 
00114     if(!type.equals(f.type)) return false;
00115     if(ci != f.ci) return false;
00116     if(nFields != f.nFields) return false;
00117     if(isClass != f.isClass) return false;
00118     
00119     int[] v1 = values;
00120     int[] v2 = f.values;
00121     int l = v1.length;
00122 
00123     if(l != v2.length) return false;
00124 
00125     for(int i = 0; i < l; i++)
00126       if(v1[i] != v2[i]) return false;
00127 
00128 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00129 //    if(!vRefs.equals(f.vRefs))
00130 //      return false;
00131 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00132 
00133     return true;
00134   }  
00135   public int findex(String fname) {
00136     if(isClass)
00137       return ci.staticFieldIndex(fname);
00138     else
00139       return ci.dynamicFieldIndex(fname);
00140   }  
00141   /**
00142    * Returns a reference to the class information.
00143    */
00144   public ClassInfo getClassInfo() {
00145     return ci;
00146   }  
00147   /**
00148    * Gets the value of a field.
00149    */
00150   public int getField(int index) { return values[index]; }  
00151 //#endif MARK_N_SWEEP
00152 
00153   /**
00154    * Gets the value of a field.
00155    */
00156   public int getField(String fname) {
00157     return getField(findex(fname));
00158   }  
00159 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00160 
00161   /**
00162    * Returns the name of the field.
00163    */
00164   public String getFieldName(int index) {
00165     if(isArray())
00166       return Integer.toString(index / Types.getTypeSize(Types.getArrayElementType(type)));
00167     else
00168       if(isClass)
00169     return ci.getStaticField(index).getName();
00170       else
00171     return ci.getDynamicField(index).getName();
00172   }  
00173   public String getFieldType(int findex) {
00174     if(isArray())
00175       return type.substring(1);
00176     else
00177       if(isClass)
00178     return ci.getStaticField(findex).getType();
00179       else
00180     return ci.getDynamicField(findex).getType();
00181   }  
00182   public String getFieldType(String fname) {
00183     return getFieldType(findex(fname));
00184   }  
00185   public long getLongField(int index) {
00186     return Types.intsToLong(values[index+1], values[index]);
00187   }  
00188   public long getLongField(String fname) {
00189     return getLongField(findex(fname));
00190   }  
00191   /**
00192    * Returns the type of the object or class associated with the fields.
00193    */
00194   public String getType() {
00195     return type;
00196   }  
00197   /**
00198    * Adds some data to the computation of an hashcode.
00199    */
00200   public void hash(HashData hd) {
00201     for(int i = 0, s = values.length; i < s; i++)
00202       hd.add(values[i]);
00203   }  
00204   /**
00205    * Computes an hash code.
00206    */
00207   public int hashCode() {
00208     HashData hd = new HashData();
00209 
00210     hash(hd);
00211 
00212     return hd.getValue();
00213   }  
00214   private void initFields() {
00215     for(int i = 0; i < values.length; ) {
00216       String t = getFieldType(i);
00217       switch(Types.getBaseType(t)) {
00218     case Types.T_CHAR:
00219     case Types.T_FLOAT:
00220     case Types.T_BYTE:
00221     case Types.T_INT:
00222     case Types.T_SHORT:
00223     case Types.T_BOOLEAN:
00224       values[i] = 0;
00225       break;
00226 
00227     case Types.T_DOUBLE:
00228     case Types.T_LONG:
00229       values[i] = 0;
00230       values[i+1] = 0;
00231       break;
00232       
00233     case Types.T_ARRAY:
00234     case Types.T_REFERENCE:
00235       values[i] = -1;
00236       break;
00237       }
00238       i += Types.getTypeSize(t);
00239     }
00240   }  
00241   /**
00242    * Returns true if the fields belong to an array.
00243    */
00244   public boolean isArray() {
00245     return Types.getBaseType(type) == Types.T_ARRAY;
00246   }  
00247   /**
00248    * Returns true if the fields belong to a class.
00249    */
00250   public boolean isClass() {
00251     return isClass;
00252   }  
00253   /**
00254    * Returns true if a field contains a reference.
00255    */
00256   public boolean isRef(int index) {
00257     return vRefs.get(index);
00258   }  
00259 //#ifdef REFERENCE_COUNT
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 //#endif REFERENCE_COUNT
00273 
00274 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00275 
00276   /**
00277    * Returns true if a field contains a reference.
00278    */
00279   public boolean isRef(String fname) {
00280     return isRef(findex(fname));
00281   }  
00282   /**
00283    * Logs the content of the fields object.
00284    */
00285   public void log(int ref) {
00286     Debug.print(Debug.MESSAGE, "  ");
00287     if(isClass())
00288       Debug.print(Debug.MESSAGE, "@");
00289     else
00290       Debug.print(Debug.MESSAGE, "#");
00291     Debug.println(Debug.MESSAGE, ref + " " + Types.getTypeName(type) + "("+type+")");
00292     for(int i = 0; i < values.length; ) {
00293       Debug.print(Debug.MESSAGE, "    " + getFieldName(i)  + ":");
00294 
00295       String t = getFieldType(i);
00296       Debug.print(Debug.MESSAGE, "(" + Types.getTypeName(t) + ")");
00297       switch(Types.getBaseType(t)) {
00298     case Types.T_CHAR:
00299       Debug.println(Debug.MESSAGE, new Character((char)getField(i)).toString());
00300       break;
00301 
00302     case Types.T_DOUBLE:
00303       Debug.println(Debug.MESSAGE, Double.toString(Types.longToDouble(getLongField(i))));
00304       break;
00305       
00306     case Types.T_FLOAT:
00307       Debug.println(Debug.MESSAGE, Float.toString(Types.intToFloat(getField(i))));
00308       break;
00309       
00310     case Types.T_BYTE:
00311     case Types.T_INT:
00312     case Types.T_SHORT:
00313       Debug.println(Debug.MESSAGE, Integer.toString(getField(i)));
00314       break;
00315       
00316     case Types.T_LONG:
00317       Debug.println(Debug.MESSAGE, Long.toString(getLongField(i)));
00318       break;
00319       
00320     case Types.T_BOOLEAN:
00321       Debug.println(Debug.MESSAGE, new Boolean(Types.intToBoolean(getField(i))).toString());
00322       break;
00323 
00324     case Types.T_ARRAY:
00325     case Types.T_REFERENCE:
00326       Debug.println(Debug.MESSAGE, "#" + values[i]);
00327       break;
00328       }
00329       i += Types.getTypeSize(t);
00330     }
00331   }  
00332 //#ifdef MARK_N_SWEEP
00333 
00334   /**
00335    * Marks all the references contained in the fields of an object.
00336    */
00337   //** warning: it might not work for arrays of references.     **//
00338   public void mark(DynamicArea da) {
00339     for(int i = 0, l = values.length; i < l; i++)
00340       if(vRefs.get(i))
00341     da.mark(values[i]);
00342   }  
00343   /**
00344    * Sets the value of a field.
00345    */
00346   public void setField(int index, int value) {
00347 //#ifdef MARK_N_SWEEP
00348     if(vRefs.get(index)
00349     && values[index] != -1
00350     && values[index] != value)
00351       VirtualMachine.getSS().activateGC();
00352 //#endif MARK_N_SWEEP
00353 
00354 //#ifdef REFERENCE_COUNT
00355 
00356 
00357 
00358 
00359 
00360 //#endif REFERENCE_COUNT
00361 
00362     values[index] = value;
00363   }  
00364   /**
00365    * Sets the value of a field.
00366    */
00367   public void setField(String fname, int value) {
00368     setField(findex(fname), value);
00369   }  
00370   public void setLongField(int index, long value) {
00371     setField(index, Types.hiLong(value));
00372     setField(index+1, Types.loLong(value));
00373   }  
00374   public void setLongField(String fname, long value) {
00375     setLongField(findex(fname), value);
00376   }  
00377   /**
00378    * Size of the fields.
00379    */
00380   public int size() {
00381     return values.length;
00382   }  
00383   public String toString() {
00384     StringBuffer sb = new StringBuffer();
00385     sb.append("Fields(");
00386 
00387     sb.append("type=");
00388     sb.append(type);
00389     sb.append(",");
00390 
00391     sb.append("ci=");
00392     sb.append(ci.getName());
00393     sb.append(",");
00394 
00395     sb.append("values=");
00396     sb.append('[');
00397     for(int i = 0; i < values.length; i++) {
00398       if(i != 0)
00399     sb.append(',');
00400       sb.append(values[i]);
00401     }
00402     sb.append(']');
00403     sb.append(",");
00404 
00405     sb.append("nFields=");
00406     sb.append(nFields);
00407     sb.append(",");
00408 
00409     sb.append("isClass=");
00410     sb.append(isClass);
00411     sb.append(",");
00412 
00413 //#ifdef MARK_N_SWEEP || REFERENCE_COUNT
00414     sb.append("vRefs=");
00415     sb.append(vRefs);
00416 //#endif MARK_N_SWEEP || REFERENCE_COUNT
00417 
00418     sb.append(")");
00419 
00420     return sb.toString();
00421   }  
00422 }

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