1 package gov.nasa.jpf.jvm; 20 21 import gov.nasa.jpf.JPFException; 22 import gov.nasa.jpf.util.HashData; 23 24 import java.util.BitSet ; 25 import java.util.NoSuchElementException ; 26 27 32 public abstract class Area implements Storable { 33 36 private final int delta; 37 38 41 protected ElementInfo[] elements; 42 43 47 private int nElements; 48 49 52 private int lastElement; 53 54 57 public KernelState ks; 58 59 62 public BitSet hasChanged; 63 64 67 public boolean anyChanged; 68 69 72 public int[] data; 73 74 78 public class Iterator implements java.util.Iterator { 79 int i, visited; 80 81 public void remove() { 82 throw new UnsupportedOperationException ("illegal operation, only GC can remove objects"); 83 } 84 85 public boolean hasNext() { 86 return (i < elements.length) && (visited < nElements); 87 } 88 89 public Object next() { 90 for (; i<elements.length; i++) { 91 ElementInfo ei = elements[i]; 92 if (ei != null) { 93 i++; visited++; 94 return ei; 95 } 96 } 97 98 throw new NoSuchElementException (); 99 } 100 } 101 102 public Area (KernelState ks, int elementLength) { 103 this.ks = ks; 104 elements = new ElementInfo[0]; 105 nElements = 0; 106 lastElement = -1; 107 hasChanged = new BitSet (); 108 anyChanged = false; 109 data = new int[0]; 110 111 delta = elementLength; 112 } 113 114 protected Area (Area a) { 115 int l = a.elements.length; 116 elements = new ElementInfo[l]; 117 118 for (int i = 0; i < l; i++) { 119 if (a.elements[i] != null) { 120 elements[i] = (ElementInfo) a.elements[i].clone(); 121 elements[i].setArea(this); 122 elements[i].setIndex(i); 123 } else { 124 elements[i] = null; 125 } 126 } 127 128 delta = a.delta; 129 130 nElements = a.nElements; 131 lastElement = a.lastElement; 132 ks = null; 133 hasChanged = (BitSet ) a.hasChanged.clone(); 134 anyChanged = a.anyChanged; 135 l = a.data.length; 136 data = new int[l]; 137 System.arraycopy(a.data, 0, data, 0, l); 138 } 139 140 145 public abstract boolean isStatic (); 146 147 public Iterator iterator() { 148 return new Iterator(); 149 } 150 151 public Object getBacktrackData () { 152 int length = elements.length; 154 Object [] data = new Object [length]; 155 156 return data; 157 } 158 159 public int[] getStoringData () { 160 if (!anyChanged) { 161 return data; 162 } 163 164 int length = lastElement + 1; 165 int size = length * delta; 166 int s = data.length - 1; 167 168 if (s != size) { 169 if (s > size) { 170 s = size; 171 } 172 173 int[] n = new int[size + 1]; 174 175 if (s > 0) { 176 System.arraycopy(data, 1, n, 1, s); 177 } 178 179 data = n; 180 } 181 182 data[0] = length; 183 184 for (int i = 0, j = 1; i < length; i++, j += delta) { 185 if (elements[i] == null) { 186 int l = j; 187 int l1 = j + delta; 188 189 for (; l < l1; l++) { 190 data[l] = 0; 191 } 192 } else if (hasChanged.get(i)) { 193 elements[i].storeDataTo(data, j); 194 } 195 } 196 197 anyChanged = false; 198 hasChanged = new BitSet (); 199 200 return data; 201 } 202 203 207 void resetVolatiles () { 208 } 210 211 public void backtrackTo (ArrayOffset storing, Object backtrack) { 212 Object [] b = (Object []) backtrack; 213 int length = storing.get(); 214 int l = elements.length; 215 int s = length * delta; 216 217 resetVolatiles(); 218 219 if (data.length != (s + 1)) { 220 data = new int[s + 1]; 221 } 222 223 if (s > 0) { 224 System.arraycopy(storing.data, storing.offset, data, 1, s); 225 } 226 227 anyChanged = false; 228 hasChanged = new BitSet (); 229 data[0] = length; 230 231 lastElement = length - 1; 232 233 if (length != l) { 234 if (l > length) { 235 l = length; 236 } 237 238 ElementInfo[] n = new ElementInfo[length]; 239 System.arraycopy(elements, 0, n, 0, l); 240 241 elements = n; 242 } 243 244 for (int i = 0; i < length; i++) { 245 ElementInfo e = elements[i]; 246 247 if (storing.peek() != 0) { 248 if (e == null) { 249 e = elements[i] = createElementInfo(); 250 e.setArea(this); 251 e.setIndex(i); 252 } 253 254 e.backtrackTo(storing, b[i]); 255 } else { 256 elements[i] = null; 257 258 for (int j = 0; j < delta; j++) { 259 storing.get(); 260 } 261 } 262 } 263 } 264 265 public int count () { 266 return nElements; 267 } 268 269 public ElementInfo get (int index) { 270 if ((index < 0) || (elements.length <= index)) { 271 return null; 272 } 273 274 return elements[index]; 275 } 276 277 public void hash (HashData hd) { 278 int length = elements.length; 279 280 for (int i = 0; i < length; i++) { 281 if (elements[i] != null) { 282 elements[i].hash(hd); 283 } 284 } 285 } 286 287 public int hashCode () { 288 HashData hd = new HashData(); 289 290 hash(hd); 291 292 return hd.getValue(); 293 } 294 295 public void removeAll () { 296 int l = elements.length; 297 298 for (int i = 0; i < l; i++) { 299 if (elements[i] != null) { 300 remove(i); 301 } 302 } 303 } 304 305 protected void add (int index, ElementInfo e) { 308 e.setArea(this); 309 e.setIndex(index); 310 311 if (index >= elements.length) { 312 ElementInfo[] n = new ElementInfo[index + 10]; 313 System.arraycopy(elements, 0, n, 0, elements.length); 314 elements = n; 315 } 316 317 if (index > lastElement) { 318 lastElement = index; 319 } 320 321 if (elements[index] == null) { 324 nElements++; 325 } else { 326 throw new JPFException("overwriting non-null object reference: " + index); 330 } 331 332 elements[index] = e; 333 hasChanged.set(index); 334 anyChanged = true; 335 ks.data = null; 336 } 337 338 protected void remove (int index) { 339 elements[index].setArea(null); 340 elements[index].setIndex(-1); 341 elements[index] = null; 342 nElements--; 343 hasChanged.set(index); 344 anyChanged = true; 345 346 if (lastElement == index) { 347 while ((lastElement >= 0) && (elements[lastElement] == null)) { 348 lastElement--; 349 } 350 } 351 352 ks.data = null; 353 } 354 355 abstract ElementInfo createElementInfo (); 356 } 357 | Popular Tags |