Mercurial > hg > Members > kono > jpf-core
comparison src/main/gov/nasa/jpf/vm/Fields.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:61d41facf527 |
---|---|
1 /* | |
2 * Copyright (C) 2014, United States Government, as represented by the | |
3 * Administrator of the National Aeronautics and Space Administration. | |
4 * All rights reserved. | |
5 * | |
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 | |
9 * | |
10 * http://www.apache.org/licenses/LICENSE-2.0. | |
11 * | |
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. | |
17 */ | |
18 package gov.nasa.jpf.vm; | |
19 | |
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; | |
24 | |
25 | |
26 /** | |
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. | |
31 * | |
32 * @see gov.nasa.jpf.vm.FieldInfo | |
33 * @see gov.nasa.jpf.vm.Monitor | |
34 */ | |
35 public abstract class Fields implements Cloneable { | |
36 | |
37 /** | |
38 * we use this to store arbitrary field attributes (like symbolic values), | |
39 * but only create this on demand | |
40 */ | |
41 protected Object[] fieldAttrs; | |
42 | |
43 /** | |
44 * attribute attached to the object as a whole | |
45 */ | |
46 protected Object objectAttr; | |
47 | |
48 | |
49 protected Fields() {} | |
50 | |
51 public boolean hasFieldAttr() { | |
52 return fieldAttrs != null; | |
53 } | |
54 | |
55 public boolean hasFieldAttr (Class<?> attrType){ | |
56 Object[] fa = fieldAttrs; | |
57 if (fa != null){ | |
58 for (int i=0; i<fa.length; i++){ | |
59 Object a = fa[i]; | |
60 if (a != null && ObjectList.containsType(a, attrType)){ | |
61 return true; | |
62 } | |
63 } | |
64 } | |
65 return false; | |
66 } | |
67 | |
68 | |
69 /** | |
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 | |
72 */ | |
73 public Object getFieldAttr(int fieldOrElementIndex){ | |
74 if (fieldAttrs != null){ | |
75 return fieldAttrs[fieldOrElementIndex]; | |
76 } | |
77 return null; | |
78 } | |
79 | |
80 /** | |
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() | |
85 */ | |
86 public void setFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){ | |
87 if (fieldAttrs == null){ | |
88 if (attr == null){ | |
89 return; // no need to waste an array object for storing null | |
90 } | |
91 fieldAttrs = new Object[nFieldsOrElements]; | |
92 } | |
93 fieldAttrs[fieldOrElementIndex] = attr; | |
94 } | |
95 | |
96 public void addFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){ | |
97 if (attr != null){ | |
98 if (fieldAttrs == null) { | |
99 fieldAttrs = new Object[nFieldsOrElements]; | |
100 } | |
101 fieldAttrs[fieldOrElementIndex] = ObjectList.add(fieldAttrs[fieldOrElementIndex], attr); | |
102 } | |
103 } | |
104 | |
105 public void removeFieldAttr (int fieldOrElementIndex, Object attr){ | |
106 if (fieldAttrs != null){ | |
107 fieldAttrs[fieldOrElementIndex] = ObjectList.remove(fieldAttrs[fieldOrElementIndex], attr); | |
108 } | |
109 } | |
110 | |
111 public void replaceFieldAttr (int fieldOrElementIndex, Object oldAttr, Object newAttr){ | |
112 if (fieldAttrs != null){ | |
113 fieldAttrs[fieldOrElementIndex] = ObjectList.replace(fieldAttrs[fieldOrElementIndex], oldAttr, newAttr); | |
114 } | |
115 } | |
116 | |
117 public boolean hasFieldAttr (int fieldOrElementIndex, Class<?> type){ | |
118 if (fieldAttrs != null){ | |
119 return ObjectList.containsType(fieldAttrs[fieldOrElementIndex], type); | |
120 } | |
121 return false; | |
122 } | |
123 | |
124 /** | |
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 | |
127 */ | |
128 public <T> T getFieldAttr (int fieldOrElementIndex, Class<T> type){ | |
129 if (fieldAttrs != null){ | |
130 return ObjectList.getFirst(fieldAttrs[fieldOrElementIndex], type); | |
131 } | |
132 return null; | |
133 } | |
134 | |
135 public <T> T getNextFieldAttr (int fieldOrElementIndex, Class<T> type, Object prev){ | |
136 if (fieldAttrs != null){ | |
137 return ObjectList.getNext(fieldAttrs[fieldOrElementIndex], type, prev); | |
138 } | |
139 return null; | |
140 } | |
141 | |
142 public ObjectList.Iterator fieldAttrIterator(int fieldOrElementIndex){ | |
143 Object a = (fieldAttrs != null) ? fieldAttrs[fieldOrElementIndex] : null; | |
144 return ObjectList.iterator(a); | |
145 } | |
146 | |
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); | |
150 } | |
151 | |
152 | |
153 //--- object attributes | |
154 public boolean hasObjectAttr () { | |
155 return (objectAttr != null); | |
156 } | |
157 | |
158 public boolean hasObjectAttr (Class<?> attrType){ | |
159 return ObjectList.containsType(objectAttr, attrType); | |
160 } | |
161 | |
162 /** | |
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 | |
165 */ | |
166 public Object getObjectAttr(){ | |
167 return objectAttr; | |
168 } | |
169 | |
170 /** | |
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() | |
175 */ | |
176 public void setObjectAttr (Object attr){ | |
177 objectAttr = attr; | |
178 } | |
179 | |
180 public void addObjectAttr (Object attr){ | |
181 objectAttr = ObjectList.add(objectAttr, attr); | |
182 } | |
183 | |
184 public void removeObjectAttr (Object attr){ | |
185 objectAttr = ObjectList.remove(objectAttr, attr); | |
186 } | |
187 | |
188 public void replaceObjectAttr (Object oldAttr, Object newAttr){ | |
189 objectAttr = ObjectList.replace(objectAttr, oldAttr, newAttr); | |
190 } | |
191 | |
192 /** | |
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 | |
195 */ | |
196 public <T> T getObjectAttr (Class<T> attrType) { | |
197 return ObjectList.getFirst(objectAttr, attrType); | |
198 } | |
199 | |
200 public <T> T getNextObjectAttr (Class<T> attrType, Object prev) { | |
201 return ObjectList.getNext(objectAttr, attrType, prev); | |
202 } | |
203 | |
204 public ObjectList.Iterator objectAttrIterator(){ | |
205 return ObjectList.iterator(objectAttr); | |
206 } | |
207 | |
208 public <T> ObjectList.TypedIterator<T> objectAttrIterator(Class<T> attrType){ | |
209 return ObjectList.typedIterator(objectAttr, attrType); | |
210 } | |
211 | |
212 | |
213 public abstract int[] asFieldSlots(); | |
214 | |
215 /** | |
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) | |
219 */ | |
220 public abstract int getHeapSize (); | |
221 | |
222 | |
223 public boolean isReferenceArray () { | |
224 return false; | |
225 } | |
226 | |
227 // our low level getters and setters | |
228 public abstract int getIntValue (int index); | |
229 | |
230 // same as getIntValue(), just here to make intentions clear | |
231 public abstract int getReferenceValue (int index); | |
232 | |
233 public abstract long getLongValue (int index); | |
234 | |
235 public abstract boolean getBooleanValue (int index); | |
236 | |
237 public abstract byte getByteValue (int index); | |
238 | |
239 public abstract char getCharValue (int index); | |
240 | |
241 public abstract short getShortValue (int index); | |
242 | |
243 public abstract float getFloatValue (int index); | |
244 | |
245 public abstract double getDoubleValue (int index); | |
246 | |
247 //--- the field modifier methods (both instance and static) | |
248 | |
249 public abstract void setReferenceValue (int index, int newValue); | |
250 | |
251 public abstract void setBooleanValue (int index, boolean newValue); | |
252 | |
253 public abstract void setByteValue (int index, byte newValue); | |
254 | |
255 public abstract void setCharValue (int index, char newValue); | |
256 | |
257 public abstract void setShortValue (int index, short newValue); | |
258 | |
259 public abstract void setFloatValue (int index, float newValue); | |
260 | |
261 public abstract void setIntValue (int index, int newValue); | |
262 | |
263 public abstract void setLongValue (int index, long newValue); | |
264 | |
265 public abstract void setDoubleValue (int index, double newValue); | |
266 | |
267 @Override | |
268 public abstract Fields clone (); | |
269 | |
270 protected Fields cloneFields() { | |
271 try { | |
272 Fields f = (Fields)super.clone(); | |
273 | |
274 if (fieldAttrs != null) { | |
275 f.fieldAttrs = fieldAttrs.clone(); | |
276 } | |
277 | |
278 if (objectAttr != null) { | |
279 f.objectAttr = objectAttr; // | |
280 } | |
281 | |
282 return f; | |
283 } catch (CloneNotSupportedException cnsx){ | |
284 return null; | |
285 } | |
286 } | |
287 | |
288 @Override | |
289 public abstract boolean equals(Object o); | |
290 | |
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)) { | |
295 return false; | |
296 } | |
297 } | |
298 | |
299 if (!ObjectList.equals(objectAttr, f.objectAttr)){ | |
300 return false; | |
301 } | |
302 | |
303 return true; | |
304 } | |
305 | |
306 // serialization interface | |
307 public abstract void appendTo(IntVector v); | |
308 | |
309 | |
310 @Override | |
311 public int hashCode () { | |
312 HashData hd = new HashData(); | |
313 hash(hd); | |
314 hashAttrs(hd); | |
315 return hd.getValue(); | |
316 } | |
317 | |
318 public abstract void hash(HashData hd); | |
319 | |
320 /** | |
321 * Adds some data to the computation of an hashcode. | |
322 */ | |
323 public void hashAttrs (HashData hd) { | |
324 | |
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; | |
328 if (a != null) { | |
329 for (int i=0, l=a.length; i < l; i++) { | |
330 ObjectList.hash(a[i], hd); | |
331 } | |
332 } | |
333 | |
334 if (objectAttr != null){ | |
335 ObjectList.hash(objectAttr, hd); | |
336 } | |
337 } | |
338 | |
339 | |
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(); | |
345 } else { | |
346 System.arraycopy(other.fieldAttrs, 0, fieldAttrs, 0, fieldAttrs.length); | |
347 } | |
348 } | |
349 | |
350 objectAttr = other.objectAttr; | |
351 } | |
352 } |