2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.vm;
20 import gov.nasa.jpf.util.HashData;
21 import gov.nasa.jpf.util.IntVector;
22 import gov.nasa.jpf.util.Misc;
23 import gov.nasa.jpf.util.ObjectList;
27 * Represents the variable, hash-collapsed pooled data associated with an object
28 * that is related to the object values (as opposed to synchronization ->Monitor).
29 * Contains the values of the fields, not their descriptors. Descriptors are represented
30 * by gov.nasa.jpf.vm.FieldInfo objects, which are stored in the ClassInfo structure.
32 * @see gov.nasa.jpf.vm.FieldInfo
33 * @see gov.nasa.jpf.vm.Monitor
35 public abstract class Fields implements Cloneable {
38 * we use this to store arbitrary field attributes (like symbolic values),
39 * but only create this on demand
41 protected Object[] fieldAttrs;
44 * attribute attached to the object as a whole
46 protected Object objectAttr;
51 public boolean hasFieldAttr() {
52 return fieldAttrs != null;
55 public boolean hasFieldAttr (Class<?> attrType){
56 Object[] fa = fieldAttrs;
58 for (int i=0; i<fa.length; i++){
60 if (a != null && ObjectList.containsType(a, attrType)){
70 * this returns all of them - use either if you know there will be only
71 * one attribute at a time, or check/process result with ObjectList
73 public Object getFieldAttr(int fieldOrElementIndex){
74 if (fieldAttrs != null){
75 return fieldAttrs[fieldOrElementIndex];
81 * this replaces all of them - use only if you know
82 * - there will be only one attribute at a time
83 * - you obtained the value you set by a previous getXAttr()
84 * - you constructed a multi value list with ObjectList.createList()
86 public void setFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){
87 if (fieldAttrs == null){
89 return; // no need to waste an array object for storing null
91 fieldAttrs = new Object[nFieldsOrElements];
93 fieldAttrs[fieldOrElementIndex] = attr;
96 public void addFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){
98 if (fieldAttrs == null) {
99 fieldAttrs = new Object[nFieldsOrElements];
101 fieldAttrs[fieldOrElementIndex] = ObjectList.add(fieldAttrs[fieldOrElementIndex], attr);
105 public void removeFieldAttr (int fieldOrElementIndex, Object attr){
106 if (fieldAttrs != null){
107 fieldAttrs[fieldOrElementIndex] = ObjectList.remove(fieldAttrs[fieldOrElementIndex], attr);
111 public void replaceFieldAttr (int fieldOrElementIndex, Object oldAttr, Object newAttr){
112 if (fieldAttrs != null){
113 fieldAttrs[fieldOrElementIndex] = ObjectList.replace(fieldAttrs[fieldOrElementIndex], oldAttr, newAttr);
117 public boolean hasFieldAttr (int fieldOrElementIndex, Class<?> type){
118 if (fieldAttrs != null){
119 return ObjectList.containsType(fieldAttrs[fieldOrElementIndex], type);
125 * this only returns the first attr of this type, there can be more
126 * if you don't use client private types or the provided type is too general
128 public <T> T getFieldAttr (int fieldOrElementIndex, Class<T> type){
129 if (fieldAttrs != null){
130 return ObjectList.getFirst(fieldAttrs[fieldOrElementIndex], type);
135 public <T> T getNextFieldAttr (int fieldOrElementIndex, Class<T> type, Object prev){
136 if (fieldAttrs != null){
137 return ObjectList.getNext(fieldAttrs[fieldOrElementIndex], type, prev);
142 public ObjectList.Iterator fieldAttrIterator(int fieldOrElementIndex){
143 Object a = (fieldAttrs != null) ? fieldAttrs[fieldOrElementIndex] : null;
144 return ObjectList.iterator(a);
147 public <T> ObjectList.TypedIterator<T> fieldAttrIterator(int fieldOrElementIndex, Class<T> type){
148 Object a = (fieldAttrs != null) ? fieldAttrs[fieldOrElementIndex] : null;
149 return ObjectList.typedIterator(a, type);
153 //--- object attributes
154 public boolean hasObjectAttr () {
155 return (objectAttr != null);
158 public boolean hasObjectAttr (Class<?> attrType){
159 return ObjectList.containsType(objectAttr, attrType);
163 * this returns all of them - use either if you know there will be only
164 * one attribute at a time, or check/process result with ObjectList
166 public Object getObjectAttr(){
171 * this replaces all of them - use only if you know
172 * - there will be only one attribute at a time
173 * - you obtained the value you set by a previous getXAttr()
174 * - you constructed a multi value list with ObjectList.createList()
176 public void setObjectAttr (Object attr){
180 public void addObjectAttr (Object attr){
181 objectAttr = ObjectList.add(objectAttr, attr);
184 public void removeObjectAttr (Object attr){
185 objectAttr = ObjectList.remove(objectAttr, attr);
188 public void replaceObjectAttr (Object oldAttr, Object newAttr){
189 objectAttr = ObjectList.replace(objectAttr, oldAttr, newAttr);
193 * this only returns the first attr of this type, there can be more
194 * if you don't use client private types or the provided type is too general
196 public <T> T getObjectAttr (Class<T> attrType) {
197 return ObjectList.getFirst(objectAttr, attrType);
200 public <T> T getNextObjectAttr (Class<T> attrType, Object prev) {
201 return ObjectList.getNext(objectAttr, attrType, prev);
204 public ObjectList.Iterator objectAttrIterator(){
205 return ObjectList.iterator(objectAttr);
208 public <T> ObjectList.TypedIterator<T> objectAttrIterator(Class<T> attrType){
209 return ObjectList.typedIterator(objectAttr, attrType);
213 public abstract int[] asFieldSlots();
216 * give an approximation of the heap size in bytes - we assume fields are word
217 * aligned, hence the number of values*4 should be good. Note that this is
218 * overridden by ArrayFields (arrays would be packed)
220 public abstract int getHeapSize ();
223 public boolean isReferenceArray () {
227 // our low level getters and setters
228 public abstract int getIntValue (int index);
230 // same as getIntValue(), just here to make intentions clear
231 public abstract int getReferenceValue (int index);
233 public abstract long getLongValue (int index);
235 public abstract boolean getBooleanValue (int index);
237 public abstract byte getByteValue (int index);
239 public abstract char getCharValue (int index);
241 public abstract short getShortValue (int index);
243 public abstract float getFloatValue (int index);
245 public abstract double getDoubleValue (int index);
247 //--- the field modifier methods (both instance and static)
249 public abstract void setReferenceValue (int index, int newValue);
251 public abstract void setBooleanValue (int index, boolean newValue);
253 public abstract void setByteValue (int index, byte newValue);
255 public abstract void setCharValue (int index, char newValue);
257 public abstract void setShortValue (int index, short newValue);
259 public abstract void setFloatValue (int index, float newValue);
261 public abstract void setIntValue (int index, int newValue);
263 public abstract void setLongValue (int index, long newValue);
265 public abstract void setDoubleValue (int index, double newValue);
268 public abstract Fields clone ();
270 protected Fields cloneFields() {
272 Fields f = (Fields)super.clone();
274 if (fieldAttrs != null) {
275 f.fieldAttrs = fieldAttrs.clone();
278 if (objectAttr != null) {
279 f.objectAttr = objectAttr; //
283 } catch (CloneNotSupportedException cnsx){
289 public abstract boolean equals(Object o);
291 // <2do> not multi-attr aware yet
292 protected boolean compareAttrs(Fields f) {
293 if (fieldAttrs != null || f.fieldAttrs != null) {
294 if (!Misc.equals(fieldAttrs, f.fieldAttrs)) {
299 if (!ObjectList.equals(objectAttr, f.objectAttr)){
306 // serialization interface
307 public abstract void appendTo(IntVector v);
311 public int hashCode () {
312 HashData hd = new HashData();
315 return hd.getValue();
318 public abstract void hash(HashData hd);
321 * Adds some data to the computation of an hashcode.
323 public void hashAttrs (HashData hd) {
325 // it's debatable if we add the attributes to the state, but whatever it
326 // is, it should be kept consistent with the StackFrame.hash()
327 Object[] a = fieldAttrs;
329 for (int i=0, l=a.length; i < l; i++) {
330 ObjectList.hash(a[i], hd);
334 if (objectAttr != null){
335 ObjectList.hash(objectAttr, hd);
340 // <2do> not multi-attr aware yet
341 public void copyAttrs(Fields other) {
342 if (other.fieldAttrs != null){
343 if (fieldAttrs == null){
344 fieldAttrs = other.fieldAttrs.clone();
346 System.arraycopy(other.fieldAttrs, 0, fieldAttrs, 0, fieldAttrs.length);
350 objectAttr = other.objectAttr;