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
00012 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00013
00014
00015 public class KernelState implements iKernelState {
00016 public StaticArea static_area;
00017 public DynamicArea dynamic_area;
00018 public List threads;
00019
00020
00021 private int[] data;
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 public KernelState() {
00052 static_area = new StaticArea();
00053 dynamic_area = new DynamicArea();
00054 threads = new ArrayList();
00055 }
00056
00057 public iThreadInfo findThread(Ref ref) {
00058
00059
00060
00061 for(Iterator it = threads.iterator(); it.hasNext(); ) {
00062 ThreadInfo ti = (ThreadInfo)it.next();
00063 if (ti.getReference().equals(ref)) {
00064
00065
00066
00067 return ti;
00068 }
00069 }
00070
00071 return null;
00072 }
00073
00074 public void gc() {
00075 Runner.GCRuns++;
00076 dynamic_area.gc(this);
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 public int[] getBacktrackData() {
00089
00090 int[] sa = static_area.getStoringData();
00091 int sal = sa.length;
00092
00093
00094 int[] da = dynamic_area.getStoringData();
00095 int dal = da.length;
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 int tl = threads.size();
00106 int[][] ts = new int[tl][];
00107 int len = 0;
00108
00109 for(int idx = 0; idx < tl; idx++) {
00110 ts[idx] = ((ThreadInfo)threads.get(idx)).getStoringData();
00111
00112 len += ts[idx].length + 1;
00113 }
00114
00115
00116
00117
00118 int size = 1 + sal + 1 + dal + 1 + len;
00119
00120
00121 data = new int[size];
00122
00123 data[0] = sal;
00124 System.arraycopy(sa, 0, data, 1, sal);
00125 data[1 + sal] = dal;
00126 System.arraycopy(da, 0, data, 1 + sal + 1, dal);
00127
00128 data[1 + sal + 1 + dal] = tl;
00129 for(int idx = 0, pos = 1 + sal + 1 + dal + 1; idx < tl; idx++) {
00130 int tsl = ts[idx].length;
00131 data[pos++] = tsl;
00132 System.arraycopy(ts[idx], 0, data, pos, tsl);
00133
00134
00135 pos += tsl;
00136 }
00137
00138 return data;
00139 }
00140
00141
00142 public DynamicArea getDynamicArea() {
00143 return dynamic_area;
00144 }
00145 public StaticArea getStaticArea() {
00146 return static_area;
00147 }
00148
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
00202
00203
00204
00205
00206 public Object getStoringData() {
00207
00208
00209
00210
00211 int hash_value = hash_data(data);
00212
00213
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
00220 return new ArrayWrapper(data, hash_value);
00221 }
00222
00223
00224 public int getThreadCount() {
00225 return threads.size();
00226 }
00227
00228 public iThreadInfo getThreadInfo(int thread) {
00229 if (thread < 0 || thread >= threads.size()) {
00230
00231
00232
00233 return null;
00234 }
00235
00236 return (iThreadInfo)threads.get(thread);
00237 }
00238
00239 public LockTree getThreadLockTree(int idx) {
00240 return ((ThreadInfo)threads.get(idx)).getLockTree();
00241 }
00242
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
00252
00253
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
00274
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
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
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
00300
00301
00302 public void newThread(iThreadInfo ti) {
00303 ((ThreadInfo)ti).setThreadReference(threads.size());
00304 threads.add(ti);
00305 }
00306
00307
00308 public void revertTo(int[] data) {
00309 int sal = data[0];
00310 int[] sa = new int[sal];
00311 System.arraycopy(data, 1, sa, 0, sal);
00312 static_area.revertTo(sa);
00313
00314 int dal = data[1 + sal];
00315 int[] da = new int[dal];
00316 System.arraycopy(data, 1 + sal + 1, da, 0, dal);
00317 dynamic_area.revertTo(da);
00318
00319 int tl = data[1 + sal + 1 + dal];
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++];
00323 ts[idx] = new int[tsl];
00324 System.arraycopy(data, pos, ts[idx], 0, tsl);
00325
00326
00327
00328 pos += tsl;
00329 }
00330
00331
00332
00333
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 }