00001 package gov.nasa.arc.ase.jpf.jvm;
00002
00003 import java.util.List;
00004 import gov.nasa.arc.ase.util.Debug;
00005 import gov.nasa.arc.ase.util.HashPool;
00006 import gov.nasa.arc.ase.util.HashData;
00007 import gov.nasa.arc.ase.jpf.jvm.reflection.Reflection;
00008 import gov.nasa.arc.ase.jpf.InternalErrorException;
00009
00010
00011
00012
00013
00014
00015
00016
00017 public class ElementInfo implements Storable, Reference {
00018 private static HashPool fieldsPool = new HashPool();
00019 private static HashPool monitorPool = new HashPool();
00020
00021
00022
00023
00024 public Fields fields;
00025 public Monitor monitor;
00026
00027
00028
00029
00030
00031
00032
00033 public Area area;
00034 public int index;
00035
00036
00037
00038
00039
00040 private int fIndex = -1;
00041 private int mIndex = -1;
00042
00043 public ElementInfo() {
00044 }
00045 public ElementInfo(ElementInfo ei) {
00046 if(ei.fIndex == -1)
00047 fields = (Fields)ei.fields.clone();
00048 else
00049 fields = ei.fields;
00050
00051 if(ei.mIndex == -1)
00052 monitor = (Monitor)ei.monitor.clone();
00053 else
00054 monitor = ei.monitor;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 area = null;
00065
00066 index = -1;
00067
00068 fIndex = ei.fIndex;
00069
00070 mIndex = ei.mIndex;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 public ElementInfo(Fields f, Monitor m) {
00080 fields = f;
00081 monitor = m;
00082 }
00083 public int arrayLength() {
00084 if(!fields.isArray())
00085 throw new InternalErrorException("object is not an array");
00086
00087 return fields.countFields();
00088 }
00089 public boolean[] asBooleanArray() {
00090 if(!fields.isArray())
00091 throw new InternalErrorException("object is not an array");
00092
00093 int length = fields.countFields();
00094 boolean[] result = new boolean[length];
00095
00096 for(int i = 0; i < length; i++)
00097 result[i] = Types.intToBoolean(getField(i));
00098
00099 return result;
00100 }
00101 public byte[] asByteArray() {
00102 if(!fields.isArray())
00103 throw new InternalErrorException("object is not an array");
00104
00105 int length = fields.countFields();
00106 byte[] result = new byte[length];
00107
00108 for(int i = 0; i < length; i++)
00109 result[i] = (byte)getField(i);
00110
00111 return result;
00112 }
00113 public char[] asCharArray() {
00114 if(!fields.isArray())
00115 throw new InternalErrorException("object is not an array");
00116
00117 int length = fields.countFields();
00118 char[] result = new char[length];
00119
00120 for(int i = 0; i < length; i++)
00121 result[i] = (char)getField(i);
00122
00123 return result;
00124 }
00125 public double[] asDoubleArray() {
00126 if(!fields.isArray())
00127 throw new InternalErrorException("object is not an array");
00128
00129 int length = fields.countFields();
00130 double[] result = new double[length];
00131
00132 for(int i = 0; i < length; i++)
00133 result[i] = Types.longToDouble(getLongField(i));
00134
00135 return result;
00136 }
00137 public float[] asFloatArray() {
00138 if(!fields.isArray())
00139 throw new InternalErrorException("object is not an array");
00140
00141 int length = fields.countFields();
00142 float[] result = new float[length];
00143
00144 for(int i = 0; i < length; i++)
00145 result[i] = Types.intToFloat(getField(i));
00146
00147 return result;
00148 }
00149 public int[] asIntArray() {
00150 if(!fields.isArray())
00151 throw new InternalErrorException("object is not an array");
00152
00153 int length = fields.countFields();
00154 int[] result = new int[length];
00155
00156 for(int i = 0; i < length; i++)
00157 result[i] = getField(i);
00158
00159 return result;
00160 }
00161 public long[] asLongArray() {
00162 if(!fields.isArray())
00163 throw new InternalErrorException("object is not an array");
00164
00165 int length = fields.countFields();
00166 long[] result = new long[length];
00167
00168 for(int i = 0; i < length; i += 2)
00169 result[i] = getLongField(i);
00170
00171 return result;
00172 }
00173 public Reflection[] asObjectArray() {
00174 if(!fields.isArray())
00175 throw new InternalErrorException("object is not an array");
00176
00177 int length = fields.countFields();
00178 Reflection[] result = new Reflection[length];
00179
00180 for(int i = 0; i < length; i++)
00181 result[i] = area.get(getField(i)).getReflection();
00182
00183 return result;
00184 }
00185 public short[] asShortArray() {
00186 if(!fields.isArray())
00187 throw new InternalErrorException("object is not an array");
00188
00189 int length = fields.countFields();
00190 short[] result = new short[length];
00191
00192 for(int i = 0; i < length; i++)
00193 result[i] = (short)getField(i);
00194
00195 return result;
00196 }
00197 public String asString() {
00198 if(!fields.getClassInfo().instanceOf("java.lang.String"))
00199 throw new InternalErrorException("object is not of type java.lang.String");
00200
00201 int value = getField("value");
00202 int length = getField("count");
00203
00204 ElementInfo e = area.get(value);
00205
00206 StringBuffer sb = new StringBuffer();
00207 for(int i = 0; i < length; i++)
00208 sb.append((char)e.getField(i));
00209
00210 return sb.toString();
00211 }
00212 public void backtrackTo(ArrayOffset storing, Object backtrack) {
00213 setFieldsIndex(storing.get());
00214 setMonitorIndex(storing.get());
00215
00216
00217
00218
00219
00220
00221
00222
00223 }
00224
00225
00226 public boolean canLock(ThreadInfo th) {
00227 return monitor.canLock(th);
00228 }
00229 public Object clone() {
00230 return new ElementInfo(this);
00231 }
00232 private Fields cloneFields() {
00233 if(fIndex == -1) return fields;
00234
00235 fIndex = -1;
00236 area.ks.data = null;
00237 area.hasChanged.set(index);
00238 area.anyChanged = true;
00239 return fields = (Fields)fields.clone();
00240 }
00241 private Monitor cloneMonitor() {
00242 if(mIndex == -1) return monitor;
00243
00244 mIndex = -1;
00245 area.ks.data = null;
00246 area.hasChanged.set(index);
00247 area.anyChanged = true;
00248 return monitor = (Monitor)monitor.clone();
00249 }
00250
00251
00252 public String getArrayType() {
00253 if(!fields.isArray())
00254 throw new InternalErrorException("object is not an array");
00255
00256 return Types.getArrayElementType(fields.getType());
00257 }
00258 public Object getBacktrackData() {
00259
00260
00261
00262
00263
00264 return null;
00265 }
00266 public boolean getBooleanArrayElement(int findex) { return Types.intToBoolean(getField(findex)); }
00267 public boolean getBooleanField(String fname) { return Types.intToBoolean(getField(fname)); }
00268 public byte getByteArrayElement(int findex) { return (byte)getField(findex); }
00269 public byte getByteField(String fname) { return (byte)getField(fname); }
00270 public char getCharArrayElement(int findex) { return (char)getField(findex); }
00271 public char getCharField(String fname) { return (char)getField(fname); }
00272 public ClassInfo getClassInfo() {
00273 return fields.getClassInfo();
00274 }
00275 public double getDoubleArrayElement(int findex) { return Types.longToDouble(getLongField(findex)); }
00276 public double getDoubleField(String fname) { return Types.longToDouble(getLongField(fname)); }
00277 public int getField(int findex) {
00278 return fields.getField(findex);
00279 }
00280 public int getField(String fname) {
00281 return fields.getField(fname);
00282 }
00283
00284
00285 private int getFieldsIndex() {
00286 if(fIndex != -1) return fIndex;
00287
00288 HashPool.PoolEntry e = fieldsPool.getEntry(fields);
00289 fields = (Fields)e.getObject();
00290
00291 return fIndex = e.getIndex();
00292 }
00293 public String getFieldType(int findex) {
00294 return fields.getFieldType(findex);
00295 }
00296 public String getFieldType(String fname) {
00297 return fields.getFieldType(fname);
00298 }
00299 public float getFloatArrayElement(int findex) { return Types.intToFloat(getField(findex)); }
00300 public float getFloatField(String fname) { return Types.intToFloat(getField(fname)); }
00301 public int getIntArrayElement(int findex) { return getField(findex); }
00302 public int getIntField(String fname) { return getField(fname); }
00303 public int getLockCount() {
00304 return monitor.getLockCount();
00305 }
00306 public int getLockingThread() {
00307 return monitor.getLockingThread();
00308 }
00309 public long getLongArrayElement(int findex) { return getLongField(findex); }
00310 public long getLongField(int findex) {
00311 return fields.getLongField(findex);
00312 }
00313 public long getLongField(String fname) {
00314 return fields.getLongField(fname);
00315 }
00316 private int getMonitorIndex() {
00317 if(mIndex != -1) return mIndex;
00318
00319 HashPool.PoolEntry e = monitorPool.getEntry(monitor);
00320 monitor = (Monitor)e.getObject();
00321
00322 return mIndex = e.getIndex();
00323 }
00324 public Reference getObjectArrayElement(int findex) { return area.ks.da.get(getField(findex)); }
00325 public Reference getObjectField(String fname) { return area.ks.da.get(getField(fname)); }
00326 public Reflection getReflection() {
00327 return fields.getClassInfo().getReflection().instantiate(index);
00328 }
00329 public short getShortArrayElement(int findex) { return (short)getField(findex); }
00330
00331 public short getShortField(String fname) { return (short)getField(fname); }
00332 public int[] getStoringData() {
00333
00334
00335
00336 int[] data = new int[2];
00337
00338
00339 data[0] = getFieldsIndex();
00340 data[1] = getMonitorIndex();
00341
00342
00343
00344
00345 return data;
00346 }
00347 public String getStringArrayElement(int findex) { return area.ks.da.get(getField(findex)).asString(); }
00348 public String getStringField(String fname) { return area.ks.da.get(getField(fname)).asString(); }
00349 public String getType() {
00350 return fields.getType();
00351 }
00352 public int[] getWaitingThreads() {
00353 return monitor.getWaitingThreads();
00354 }
00355 public void hash(HashData hd) {
00356 fields.hash(hd);
00357 monitor.hash(hd);
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 public int hashCode() {
00388 HashData hd = new HashData();
00389
00390 hash(hd);
00391
00392 return hd.getValue();
00393 }
00394 public boolean instanceOf(String type) {
00395 return Types.instanceOf(fields.getType(), type);
00396 }
00397 public void interrupt() {
00398 area.ks.tl.locate(index).interrupt();
00399 }
00400 public boolean isFieldRef(int findex) {
00401 return fields.isRef(findex);
00402 }
00403
00404 public boolean isFieldRef(String fname) {
00405 return fields.isRef(fname);
00406 }
00407 public void lock(ThreadInfo th) {
00408 cloneMonitor().lock(th, area.isStatic ? (Ref)new ClassRef(index) : (Ref)new ObjRef(index));
00409 }
00410 public void lockNotified(ThreadInfo th) {
00411 cloneMonitor().lockNotified(th, area.isStatic ? (Ref)new ClassRef(index) : (Ref)new ObjRef(index));
00412 }
00413
00414
00415
00416
00417
00418
00419 public void log() {
00420 if(fIndex == -1) Debug.println(Debug.MESSAGE, "(fields have changed)");
00421 fields.log(index);
00422 if(mIndex == -1) Debug.println(Debug.MESSAGE, "(monitor has changed)");
00423 monitor.log();
00424 }
00425
00426 public void mark() {
00427 fields.mark(area.ks.da);
00428 }
00429 public void notifies() {
00430 cloneMonitor().notify(area.ks.ss);
00431 }
00432 public void notifiesAll() {
00433 cloneMonitor().notifyAll(area.ks.ss);
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 public boolean outOfBounds(int index) {
00446 if(!fields.isArray())
00447 throw new InternalErrorException("object is not an array");
00448
00449 return (index < 0 || index >= fields.size());
00450 }
00451 public void setField(int findex, int value) {
00452 cloneFields().setField(findex, value);
00453 }
00454 public void setField(String fname, int value) {
00455 cloneFields().setField(fname, value);
00456 }
00457 private void setFieldsIndex(int index) {
00458 if(fIndex == index) return;
00459
00460 fIndex = index;
00461 fields = (Fields)fieldsPool.getObject(index);
00462 }
00463 public void setLongField(int findex, long value) {
00464 cloneFields().setLongField(findex, value);
00465 }
00466 public void setLongField(String fname, long value) {
00467 cloneFields().setLongField(fname, value);
00468 }
00469 private void setMonitorIndex(int index) {
00470 if(mIndex == index) return;
00471
00472 mIndex = index;
00473 monitor = (Monitor)monitorPool.getObject(index);
00474 }
00475 public void unlock(ThreadInfo th) {
00476 cloneMonitor().unlock(th, area.isStatic ? (Ref)new ClassRef(index) : (Ref)new ObjRef(index));
00477 }
00478 public void wait(ThreadInfo th) {
00479 cloneMonitor().wait(th, area.isStatic ? (Ref)new ClassRef(index) : (Ref)new ObjRef(index));
00480 }
00481 }