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

KernelState.java

00001 package gov.nasa.arc.ase.jpf.jvm;
00002 
00003 import de.fub.bytecode.classfile.*;
00004 import de.fub.bytecode.generic.*;
00005 import gov.nasa.arc.ase.jpf.*;
00006 import gov.nasa.arc.ase.util.Debug;
00007 import gov.nasa.arc.ase.util.HashData;
00008 import gov.nasa.arc.ase.util.HashPool;
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 KernelState implements iKernelState {
00016   public StaticArea  static_area;   // information about the loaded classes
00017   public DynamicArea dynamic_area;  // information about the created objects
00018   public List        threads;       // list of the threads
00019 
00020 // ifdef NO_COMPRESSION
00021   private int[] data;
00022 // ifdef NO_COMPRESSION
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 //#endif NO_COMPRESSION
00038 
00039 // ifdef NO_COMPRESSION
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 //#endif NO_COMPRESSION
00049 //#endif NO_COMPRESSION
00050 
00051   public KernelState() {
00052     static_area = new StaticArea();
00053     dynamic_area = new DynamicArea();
00054     threads = new ArrayList();
00055   }  
00056   // Looks for the thread info corresponding to the given object reference
00057   public iThreadInfo findThread(Ref ref) {
00058     // This is a very cheap implementation
00059     // just iterates the threads and checks their object reference
00060     //** Space for optimizations here too **//
00061     for(Iterator it = threads.iterator(); it.hasNext(); ) {
00062       ThreadInfo ti = (ThreadInfo)it.next(); 
00063       if (ti.getReference().equals(ref)) {
00064 // ifdef DEBUG
00065 
00066 //#endif DEBUG
00067     return ti;
00068       }
00069     }
00070 
00071     return null;
00072   }  
00073 // ifdef MARK_N_SWEEP
00074   public void gc() {
00075     Runner.GCRuns++;
00076     dynamic_area.gc(this);
00077   }  
00078 // ifdef NO_FASTBACKTRACK
00079 
00080 
00081 
00082 
00083 
00084 //#endif NO_FASTBACKTRACK
00085 
00086 // ifdef NO_COMPRESSION
00087 // ifdef NO_FASTBACKTRACK
00088   public int[] getBacktrackData() {
00089     // gets the information from the static area
00090     int[] sa = static_area.getStoringData();
00091     int sal = sa.length;
00092 
00093     // gets the information from the dynamic area
00094     int[] da = dynamic_area.getStoringData();
00095     int dal = da.length;
00096 
00097     // gets the information from the list of threads
00098 
00099     // okay here is a little more complicated
00100     // the class List doesn't have any method called
00101     // getStoringData, but each of the objects in it
00102     // do, because we put ThreadInfo objects
00103 
00104     // for each of the threads in the list we collect the information
00105     int tl = threads.size();
00106     int[][] ts = new int[tl][];
00107     int len = 0; // this will contain the total length
00108 
00109     for(int idx = 0; idx < tl; idx++) {
00110       ts[idx] = ((ThreadInfo)threads.get(idx)).getStoringData();
00111       // there is an extra value for the size of each thread info
00112       len += ts[idx].length + 1;
00113     }
00114 
00115     // the total size includes static area size, static area, dynamic area
00116     // size, dynamic area, number of threads and the information about each
00117     // thread (with already include the size of them).
00118     int size = 1 + sal + 1 + dal + 1 + len;
00119 
00120     // allocate an array big enough to fit all the information
00121     data = new int[size];
00122 
00123     data[0] = sal;              // static area size
00124     System.arraycopy(sa, 0, data, 1, sal);  // static area
00125     data[1 + sal] = dal;            // dynamic area size
00126     System.arraycopy(da, 0, data, 1 + sal + 1, dal);
00127     // dynamic area
00128     data[1 + sal + 1 + dal] = tl;       // number of threads
00129     for(int idx = 0, pos = 1 + sal + 1 + dal + 1; idx < tl; idx++) {
00130       int tsl = ts[idx].length;
00131       data[pos++] = tsl;            // length of the thread info
00132       System.arraycopy(ts[idx], 0, data, pos, tsl);
00133       // thread info
00134       // skips the positions used by the thread information
00135       pos += tsl;
00136     }
00137 
00138     return data;
00139   }  
00140 //#endif RACE
00141 
00142   public DynamicArea getDynamicArea() {
00143     return dynamic_area;
00144   }  
00145   public StaticArea getStaticArea() {
00146     return static_area;
00147   }  
00148 //#else NO_FASTBACKTRACK
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 //#endif NO_FASTBACKTRACK
00202 //#endif NO_COMPRESSION
00203 
00204 // ifdef NO_COMPRESSION
00205   // returns a compact rapresentation of the state
00206   public Object getStoringData() {
00207 // ifdef NO_FASTBACKTRACK
00208 
00209 //#endif NO_FASTBACKTRACK
00210     // computes and hash value for the data
00211     int hash_value = hash_data(data);
00212 
00213     ////#ifdef HASHCOMPACT
00214     if (VirtualMachine.options.hashcompact) {
00215       int[] hash_compact_value = new int[1];
00216       hash_compact_value[0] = hash_reverse_data(data);
00217       return new ArrayWrapper(hash_compact_value, hash_value);
00218     } else
00219     ////#endif HASHCOMPACT
00220       return new ArrayWrapper(data, hash_value);
00221   }  
00222 //#endif NO_COMPRESSION
00223 
00224   public int getThreadCount() {
00225     return threads.size();
00226   }  
00227   // Returns the information about a particular thread
00228   public iThreadInfo getThreadInfo(int thread) {
00229     if (thread < 0 || thread >= threads.size()) {
00230 // ifdef DEBUG
00231 
00232 //#endif DEBUG
00233       return null;
00234     }
00235 
00236     return (iThreadInfo)threads.get(thread);
00237   }  
00238 // ifdef RACE
00239   public LockTree getThreadLockTree(int idx) {
00240     return ((ThreadInfo)threads.get(idx)).getLockTree();
00241   }  
00242   // these are two polinomial hash functions
00243   private int hash_data(int[] data) {
00244     HashData hd = new HashData();
00245 
00246     for (int i = 0, l = data.length; i < l; i++)
00247       hd.add(data[i]);
00248 
00249     return hd.getValue();
00250   }  
00251   // this one looks like the first one but processes
00252   // the data backward giving a pretty statistically
00253   // indipendent value
00254   private int hash_reverse_data(int[] data) {
00255     HashData hd = new HashData();
00256 
00257     for (int i = data.length-1; i >= 0; i--)
00258       hd.add(data[i]);
00259 
00260     return hd.getValue();
00261   }  
00262   public int hashCode() {
00263     HashData hd = new HashData();
00264 
00265     dynamic_area.hash(hd);
00266     static_area.hash(hd);
00267 
00268     for(int i = 0, l = threads.size(); i < l; i++)
00269       ((ThreadInfo)threads.get(i)).hash(hd);
00270 
00271     return hd.getValue();
00272   }  
00273   // Checks if there are no alive threads
00274   //** This could be optimized (timewise) having a local table **//
00275   public boolean isTerminated() {
00276     for(Iterator it = threads.iterator(); it.hasNext(); )
00277       if (((ThreadInfo)it.next()).isAlive()) return false;
00278     return true;
00279   }  
00280 //#endif MARK_N_SWEEP
00281 
00282 // ifdef REFERENCE_COUNT
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 //#endif REFERENCE_COUNT
00291 
00292   public void log() {
00293     dynamic_area.log();
00294     static_area.log();
00295     for(int i = 0; i < threads.size(); i++)
00296       ((ThreadInfo)threads.get(i)).log();
00297     Debug.println(Debug.MESSAGE);
00298   }  
00299 //#endif NO_COMPRESSION
00300 
00301   // Adds a new thread to the thread list
00302   public void newThread(iThreadInfo ti) {
00303     ((ThreadInfo)ti).setThreadReference(threads.size());
00304     threads.add(ti);
00305   }  
00306 // ifdef NO_COMPRESSION
00307   // This function revert changes moving back to a previous state
00308   public void revertTo(int[] data) {
00309     int sal = data[0];              // static area size
00310     int[] sa = new int[sal];
00311     System.arraycopy(data, 1, sa, 0, sal);  // static area
00312     static_area.revertTo(sa);
00313 
00314     int dal = data[1 + sal];            // dynamic area size
00315     int[] da = new int[dal];
00316     System.arraycopy(data, 1 + sal + 1, da, 0, dal);
00317     dynamic_area.revertTo(da);          // dynamic area
00318 
00319     int tl = data[1 + sal + 1 + dal];       // number of threads
00320     int[][] ts = new int[tl][];
00321     for(int idx = 0, pos = 1 + sal + 1 + dal + 1; idx < tl; idx++) {
00322       int tsl = data[pos++];            // length of the thread info
00323       ts[idx] = new int[tsl];
00324       System.arraycopy(data, pos, ts[idx], 0, tsl);
00325                             // thread info
00326       
00327       // skips the positions used by the thread information
00328       pos += tsl;
00329     }
00330 
00331     // Now we reconstract the list. For the entry that are already present
00332     // we just try to revert them to the right value, if there are more
00333     // we build them from scratch, if there are less we remove the others.
00334     int ctl = threads.size();
00335 
00336     if(ctl == tl)
00337       for(int idx = 0; idx < tl; idx++)
00338     ((ThreadInfo)threads.get(idx)).revertTo(this, ts[idx]);
00339     else if(ctl < tl) {
00340       for(int idx = 0; idx < ctl; idx++)
00341     ((ThreadInfo)threads.get(idx)).revertTo(this, ts[idx]);
00342       for(int idx = ctl; idx < tl; idx++) {
00343     ThreadInfo th = new ThreadInfo(this, ts[idx]);
00344 
00345     threads.add(th);
00346     th.setThreadReference(idx);
00347       }
00348     } else {
00349       for(int idx = 0; idx < tl; idx++)
00350     ((ThreadInfo)threads.get(idx)).revertTo(this, ts[idx]);
00351       for(int idx = tl; idx < ctl; idx++)
00352     threads.remove(tl);
00353     }
00354   }  
00355 }

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