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 gov.nasa.arc.ase.util.HashPool;
00010 import java.io.*;
00011 import java.util.*;
00012
00013 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00014
00015
00016 public class StaticArea {
00017 Vector classes;
00018 Vector objinfo;
00019
00020
00021
00022
00023 BitSet classChanged;
00024 BitSet objinfoChanged;
00025 boolean anyClassChanged;
00026 boolean anyObjectInfoChanged;
00027
00028
00029
00030 int[] classData;
00031 int[] objinfoData;
00032
00033
00034 private static final int EXTRA_GROW_SIZE = 10;
00035
00036
00037 public StaticArea() {
00038 classes = new Vector();
00039 objinfo = new Vector();
00040
00041
00042
00043 classChanged = new BitSet();
00044 objinfoChanged = new BitSet();
00045 anyClassChanged = false;
00046 anyObjectInfoChanged = false;
00047
00048
00049 classData = new int[0];
00050 objinfoData = new int[0];
00051
00052 }
00053
00054
00055 public int addClass(ClassInfo ci) {
00056 int index = indexFor(ci.getClassName());
00057
00058
00059
00060
00061
00062
00063 if (index >= classes.size()) {
00064 classes.setSize(index + EXTRA_GROW_SIZE);
00065 objinfo.setSize(index + EXTRA_GROW_SIZE);
00066 }
00067
00068 Fields fs = ci.createStaticFields();
00069 classes.setElementAt(fs, index);
00070
00071 ci.reflection.setClassRef(index);
00072
00073 objinfo.setElementAt(new ObjectInfo(), index);
00074
00075
00076
00077 classChanged.set(index);
00078 objinfoChanged.set(index);
00079 anyClassChanged = true;
00080 anyObjectInfoChanged = true;
00081
00082
00083 return index;
00084 }
00085
00086
00087
00088 private void cloneClass(int index) {
00089
00090 if(!classChanged.get(index)) {
00091 Object o = ((Fields)classes.get(index)).clone();
00092 classes.setElementAt(o, index);
00093
00094
00095 classChanged.set(index);
00096 anyClassChanged = true;
00097 }
00098 }
00099
00100
00101 private void cloneObjectInfo(int index) {
00102
00103 if(!objinfoChanged.get(index)) {
00104 Object o = ((ObjectInfo)objinfo.get(index)).clone();
00105 objinfo.setElementAt(o, index);
00106
00107
00108 objinfoChanged.set(index);
00109 anyObjectInfoChanged = true;
00110 }
00111 }
00112
00113 public boolean containsClass(String classname) {
00114 return hasClass(classname);
00115 }
00116
00117 public ClassInfo getClass(int classref) {
00118 return ((Fields)classes.get(classref)).getClassInfo();
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 public LockStatus getLockStatus(String classname,String fieldname) {
00128 int index = indexOf(classname);
00129 return ((Fields)classes.get(index)).getLockStatus(fieldname);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 public int[] getStoringData() {
00160
00161
00162 update();
00163
00164
00165 int cl = classData.length;
00166 int il = objinfoData.length;
00167
00168
00169
00170
00171
00172 int[] data = new int[cl + il];
00173
00174
00175 System.arraycopy(classData, 0, data, 0, cl);
00176 System.arraycopy(objinfoData, 0, data, cl, il);
00177
00178 return data;
00179 }
00180
00181
00182
00183
00184
00185
00186 public long getValue(int classref, String fieldname) {
00187 return ((Fields)classes.get(classref)).getValue(fieldname);
00188 }
00189 public long getValue(String classname, String fieldname) {
00190 return ((Fields)classes.get(indexOf(classname))).getValue(fieldname);
00191 }
00192 public int getVariableType(int classref, int index) {
00193 return ((Fields)classes.get(classref)).getClassInfo().getStaticFieldType(index);
00194 }
00195 public int getVariableType(int classref, String fname) {
00196 return ((Fields)classes.get(classref)).getClassInfo().getStaticFieldType(fname);
00197 }
00198
00199
00200 public int getVariableType(String classname, int index) {
00201 int classref = indexOf(classname);
00202 return ((Fields)classes.get(classref)).getClassInfo().getStaticFieldType(index);
00203 }
00204 public int getVariableType(String classname, String fname) {
00205 int classref = indexOf(classname);
00206 return ((Fields)classes.get(classref)).getClassInfo().getStaticFieldType(fname);
00207 }
00208
00209 public boolean hasClass(String classname) {
00210
00211 if(!StaticMap.hasEntry(classname)) return false;
00212
00213 int index = indexOf(classname);
00214 return (index >= 0 && index < classes.size() && classes.get(index) != null);
00215 }
00216 public void hash(HashData hd) {
00217 for(int i = 0, l = classes.size(); i < l; i++) {
00218 Object o = classes.get(i);
00219 if(o != null) hd.add(o.hashCode());
00220 }
00221
00222 for(int i = 0, l = objinfo.size(); i < l; i++) {
00223 Object o = objinfo.get(i);
00224 if(o != null) hd.add(o.hashCode());
00225 }
00226 }
00227 public int hashCode() {
00228 HashData hd = new HashData();
00229
00230 for(int i = 0, l = classes.size(); i < l; i++) {
00231 Object o = classes.get(i);
00232 if(o != null) hd.add(o.hashCode());
00233 }
00234
00235 for(int i = 0, l = objinfo.size(); i < l; i++) {
00236 Object o = objinfo.get(i);
00237 if(o != null) hd.add(o.hashCode());
00238 }
00239
00240 return hd.getValue();
00241 }
00242 private int indexFor(String classname) {
00243
00244 return StaticMap.addEntry(classname);
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 public int indexOf(String classname) {
00292
00293 return StaticMap.getEntry(classname);
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 public boolean isLoaded(String classname) {
00420 return StaticMap.hasEntry(classname);
00421 }
00422 public void log() {
00423 Debug.println(Debug.MESSAGE, "SA");
00424 for(int i = 0; i < classes.size(); i++) {
00425 Fields f = (Fields)classes.get(i);
00426 if(f != null) {
00427 Debug.println(Debug.MESSAGE, " @" + i + " " + f.getClassInfo().getClassName());
00428 f.log(i, false);
00429 }
00430 }
00431 }
00432
00433 public void mark(DynamicArea da) {
00434 int length = classes.size();
00435 for(int index = 0; index < length; index++) {
00436 Fields f = (Fields)classes.get(index);
00437 if(f != null) f.mark(da);
00438 }
00439 }
00440
00441
00442
00443 public boolean monitorCheckLock(int classref, ThreadInfo th) {
00444 return ((ObjectInfo)objinfo.get(classref)).getMonitor().checkLock(th);
00445 }
00446
00447
00448
00449 public boolean monitorCheckLock(String className, ThreadInfo th) {
00450 return monitorCheckLock(indexOf(className), th);
00451 }
00452
00453 public boolean monitorCheckLockAfterNotified(int classref, ThreadInfo th) {
00454 return ((ObjectInfo)objinfo.get(classref)).getMonitor().checkLockAfterNotified(th);
00455 }
00456 public boolean monitorCheckLockAfterNotified(String className, ThreadInfo th) {
00457 return monitorCheckLockAfterNotified(indexOf(className), th);
00458 }
00459
00460 public boolean monitorLock(int classref, ThreadInfo th) {
00461
00462
00463 cloneObjectInfo(classref);
00464
00465 return ((ObjectInfo)objinfo.get(classref)).getMonitor().lock(th, new ClassRef(classref));
00466 }
00467 public boolean monitorLock(String className, ThreadInfo th) {
00468 return monitorLock(indexOf(className), th);
00469 }
00470
00471 public boolean monitorLockAfterNotified(int classref, ThreadInfo th) {
00472
00473
00474 cloneObjectInfo(classref);
00475
00476 return ((ObjectInfo)objinfo.get(classref)).getMonitor().lockAfterNotified(th, new ClassRef(classref));
00477 }
00478 public boolean monitorLockAfterNotified(String className, ThreadInfo th) {
00479 return monitorLockAfterNotified(indexOf(className), th);
00480 }
00481
00482 public void monitorNotify(int classref, KernelState ks, Scheduler sch) {
00483
00484
00485 cloneObjectInfo(classref);
00486
00487 ((ObjectInfo)objinfo.get(classref)).getMonitor().notify(ks, sch);
00488 }
00489 public void monitorNotify(String className, KernelState ks, Scheduler sch) {
00490 monitorNotify(indexOf(className), ks, sch);
00491 }
00492
00493 public void monitorNotifyAll(int classref, KernelState ks) {
00494
00495
00496 cloneObjectInfo(classref);
00497
00498 ((ObjectInfo)objinfo.get(classref)).getMonitor().notifyAll(ks);
00499 }
00500 public void monitorNotifyAll(String className, KernelState ks) {
00501 monitorNotifyAll(indexOf(className), ks);
00502 }
00503
00504 public void monitorUnlock(int classref, ThreadInfo th) {
00505
00506
00507 cloneObjectInfo(classref);
00508
00509 ((ObjectInfo)objinfo.get(classref)).getMonitor().unlock(th, new ClassRef(classref));
00510 }
00511 public void monitorUnlock(String className, ThreadInfo th) {
00512 monitorUnlock(indexOf(className), th);
00513 }
00514
00515 public void monitorWait(int classref, ThreadInfo th) {
00516
00517
00518 cloneObjectInfo(classref);
00519
00520 ((ObjectInfo)objinfo.get(classref)).getMonitor().wait(th, new ClassRef(classref));
00521 }
00522 public void monitorWait(String className, ThreadInfo th) {
00523 monitorWait(indexOf(className), th);
00524 }
00525
00526
00527
00528
00529
00530 public void revertTo(int[] data) {
00531
00532 int len = data.length / 2;
00533
00534 int[] nClassData = new int[len];
00535 int[] nObjinfoData = new int[len];
00536
00537 System.arraycopy(data, 0, nClassData, 0, len);
00538 System.arraycopy(data, len, nObjinfoData, 0, len);
00539
00540 int s = classData.length;
00541
00542 if (s >= len) {
00543
00544
00545 for (int idx = 0; idx < len; idx++) {
00546 if(nClassData[idx] != classData[idx])
00547 classes.setElementAt(
00548 VirtualMachine.fieldsPool.getObject(nClassData[idx]),
00549 idx);
00550 if(nObjinfoData[idx] != objinfoData[idx])
00551 objinfo.setElementAt(
00552 VirtualMachine.objectInfoPool.getObject(nObjinfoData[idx]),
00553 idx);
00554 }
00555
00556 classes.setSize(len);
00557 objinfo.setSize(len);
00558 } else {
00559
00560 for (int idx = 0; idx < s; idx++) {
00561 if(nClassData[idx] != classData[idx])
00562 classes.setElementAt(
00563 VirtualMachine.fieldsPool.getObject(nClassData[idx]),
00564 idx);
00565 if(nObjinfoData[idx] != objinfoData[idx])
00566 objinfo.setElementAt(
00567 VirtualMachine.objectInfoPool.getObject(nObjinfoData[idx]),
00568 idx);
00569 }
00570 classes.setSize(len);
00571 objinfo.setSize(len);
00572
00573 for (int idx = s; idx < len; idx++) {
00574 classes.setElementAt(
00575 VirtualMachine.fieldsPool.getObject(nClassData[idx]),
00576 idx);
00577 objinfo.setElementAt(
00578 VirtualMachine.objectInfoPool.getObject(nObjinfoData[idx]),
00579 idx);
00580 }
00581 }
00582 classData = nClassData;
00583 objinfoData = nObjinfoData;
00584 }
00585 public void setValue(int classref, String fieldname, long value) {
00586
00587 cloneClass(classref);
00588
00589 ((Fields)classes.get(classref)).setValue(fieldname, value);
00590 }
00591 public void setValue(String classname, String fieldname, long value) {
00592
00593 cloneClass(indexOf(classname));
00594
00595 ((Fields)classes.get(indexOf(classname))).setValue(fieldname, value);
00596 }
00597
00598
00599
00600 private void update() {
00601 if (anyClassChanged) {
00602
00603 updateClasses();
00604
00605
00606 classChanged = new BitSet();
00607 anyClassChanged = false;
00608 }
00609
00610 if (anyObjectInfoChanged) {
00611
00612 updateObjectInfos();
00613
00614
00615 objinfoChanged = new BitSet();
00616 anyObjectInfoChanged = false;
00617 }
00618 }
00619
00620 private void updateClasses() {
00621
00622
00623
00624 int size = classes.size();
00625 int old_size = classData.length;
00626 int actual_size = -1;
00627
00628
00629
00630
00631
00632
00633
00634 int[] data = new int[size];
00635 for(int i = 0; i < size; i++) {
00636
00637 Fields o = (Fields)classes.get(i);
00638 if(o != null) {
00639
00640
00641 actual_size = i;
00642
00643 if (classChanged.get(i)) {
00644
00645 HashPool.PoolEntry e = VirtualMachine.fieldsPool.getEntry(o);
00646
00647
00648 classes.setElementAt(e.getObject(), i);
00649
00650 data[i] = e.getIndex();
00651 } else {
00652
00653
00654
00655
00656
00657 data[i] = classData[i];
00658 }
00659 } else {
00660
00661 data[i] = 0;
00662 }
00663 }
00664
00665
00666
00667 classData = new int[++actual_size];
00668 System.arraycopy(data, 0, classData, 0, actual_size);
00669 }
00670
00671 private void updateObjectInfos() {
00672
00673
00674
00675 int size = objinfo.size();
00676 int old_size = objinfoData.length;
00677 int actual_size = -1;
00678
00679
00680
00681
00682
00683
00684
00685 int[] data = new int[size];
00686 for(int i = 0; i < size; i++) {
00687
00688 ObjectInfo o = (ObjectInfo)objinfo.get(i);
00689 if(o != null) {
00690
00691
00692 actual_size = i;
00693
00694 if (objinfoChanged.get(i)) {
00695
00696 HashPool.PoolEntry e = VirtualMachine.objectInfoPool.getEntry(o);
00697
00698
00699 objinfo.setElementAt(e.getObject(), i);
00700
00701 data[i] = e.getIndex();
00702 } else {
00703
00704
00705
00706
00707
00708 data[i] = objinfoData[i];
00709 }
00710 } else {
00711
00712 data[i] = 0;
00713 }
00714 }
00715
00716
00717
00718 objinfoData = new int[++actual_size];
00719 System.arraycopy(data, 0, objinfoData, 0, actual_size);
00720 }
00721 }