1 package gov.nasa.jpf.jvm; 20 21 import gov.nasa.jpf.Config; 22 import gov.nasa.jpf.jvm.bytecode.Instruction; 23 import gov.nasa.jpf.util.Debug; 24 25 import java.util.ArrayList ; 26 import java.util.BitSet ; 27 import java.util.Vector ; 28 29 import java.util.HashMap ; 31 import gov.nasa.jpf.util.DynamicIntArray; 32 33 34 38 public class DynamicArea extends Area { 39 40 static DynamicArea heap; 41 42 45 BitSet isUsed; 46 BitSet isRoot; 47 DynamicIntArray refThread; 48 DynamicIntArray lastAttrs; 49 50 boolean runFinalizer; 51 52 int markLevel; 54 55 boolean outOfMemory; 57 58 private HashMap String2Object = new HashMap (); 59 60 61 private ArrayList weakRefs; 62 63 public static void init (Config config) { 64 DynamicMap.init(); 65 } 66 67 70 public DynamicArea (Config config, KernelState ks) { 71 super(ks, DynamicElementInfo.storingDataLength); 72 73 runFinalizer = config.getBoolean("vm.finalize", true); 74 75 heap = this; 80 } 81 82 public boolean isStatic () { 83 return false; 84 } 85 86 public static DynamicArea getHeap () { 87 return heap; 88 } 89 90 public boolean getOutOfMemory () { 91 return outOfMemory; 92 } 93 94 public void setOutOfMemory (boolean isOutOfMemory) { 95 outOfMemory = isOutOfMemory; 96 } 97 98 public void gc () { 99 analyzeHeap(true); 100 } 101 102 117 118 public void analyzeHeap (boolean sweep) { 119 122 int i; 123 int length = elements.length; 124 ElementInfo ei; 125 weakRefs = null; 126 127 JVM.getVM().notifyGCBegin(); 128 129 initGc(); 130 131 for (i=0; i<length; i++) { 137 ei = elements[i]; 138 if (ei != null) { 139 lastAttrs.set( i, ei.attributes); 140 ei.attributes &= ~ElementInfo.ATTR_PROP_MASK; 141 142 if ((ei.attributes & ElementInfo.ATTR_PINDOWN) != 0){ 143 markPinnedDown(i); 144 } 145 } 146 } 147 148 ks.tl.markRoots(); ks.sa.markRoots(); 156 for (i=0; i<length; i++) { 160 if (isRoot.get(i)) { 161 markRecursive(i); 162 } 163 } 164 165 if (sweep && runFinalizer) { 170 for (i = 0; i < length; i++) { 171 ei = elements[i]; 172 if ((ei != null) && !isUsed.get(i)) { 173 if (!JVM.getVM().finalizeObject(ei)) { 178 markRecursive(i); 179 } 180 } 181 } 182 } 183 184 int count = 0; 187 boolean heapModified = anyChanged; 188 189 for (i = 0; i < length; i++) { 190 ei = elements[i]; 191 if (ei != null) { 192 if (isUsed.get(i)) { 193 198 if (lastAttrs.get(i) != ei.attributes) { 205 213 214 anyChanged = true; 215 hasChanged.set(i); 216 } 217 } else if (sweep) { 218 count++; 220 JVM.getVM().notifyObjectReleased(ei); 221 remove(i); 222 } 223 } 224 } 225 226 if (sweep) { 227 checkWeakRefs(); } 229 230 JVM.getVM().notifyGCEnd(); 231 } 232 233 void initGc () { 234 int len = elements.length; 235 236 if ((isRoot == null) || (isRoot.size() < len)) { 237 isRoot = new BitSet (len); 238 } else { 239 isRoot.clear(); 240 } 241 242 if ((isUsed == null) || (isUsed.size() < len)) { 243 isUsed = new BitSet (len); 244 } else { 245 isUsed.clear(); 246 } 247 248 if (refThread == null) { 251 refThread = new DynamicIntArray(); 252 } 253 254 if (lastAttrs == null) { 255 lastAttrs = new DynamicIntArray(); 256 } 257 } 258 259 void logMark (FieldInfo fi, ElementInfo ei, int tid, int attrMask) { 260 261 for (int i=0; i<=markLevel; i++) System.out.print(" "); 262 263 if (fi != null) { 264 System.out.print('\''); 265 System.out.print(fi.getName()); 266 System.out.print("': "); 267 } 268 269 System.out.print( ei); 270 271 System.out.print( " ,attr:"); 272 System.out.print( Integer.toHexString(ei.attributes)); 273 274 System.out.print( " ,mask:"); 275 System.out.print( Integer.toHexString(attrMask)); 276 277 System.out.print( " ,thread:"); 278 System.out.print( tid); 279 System.out.print( "/"); 280 System.out.print( refThread.get(ei.index)); 281 System.out.print( " "); 282 283 if (isRoot.get(ei.index)) System.out.print( "R"); 284 if (isUsed.get(ei.index)) System.out.print( "V"); 285 286 System.out.println(); 287 288 } 289 290 301 void markRecursive (int objref) { 302 int tid = refThread.get(objref); 303 ElementInfo ei = elements[objref]; 304 int attrMask = ElementInfo.ATTR_PROP_MASK; 305 306 markLevel = 0; 307 308 isUsed.set(objref); 309 ei.markRecursive(tid, attrMask); 311 } 312 313 void markRecursive (int objref, int refTid, int refAttr, int attrMask, FieldInfo fi) { 314 if (objref == -1) { 315 return; 316 } 317 ElementInfo ei = elements[objref]; 318 319 if (fi != null) { 320 attrMask &= fi.getAttributes(); 321 } 322 323 markLevel++; 324 325 if (isRoot.get(objref)) { 326 if (!ei.isShared() && (refThread.get(objref) != refTid)) { 327 ei.setShared(attrMask); 328 } 330 } else { 331 if (!isUsed.get(objref) || !ei.hasEqualPropagatedAttributes(refAttr, attrMask)) { 332 isUsed.set(objref); 333 refThread.set(objref, refTid); 334 ei.propagateAttributes(refAttr, attrMask); 335 336 ei.markRecursive(refTid, attrMask); 338 } 339 } 340 341 markLevel--; 342 } 343 344 349 void markThreadRoot (int objref, int tid) { 350 if (objref == -1) { 351 return; 352 } 353 354 if (isRoot.get(objref)) { 355 int rt = refThread.get(objref); 356 if ((rt != tid) && (rt != -1)) { 357 elements[objref].setShared(); 358 } 359 } else { 360 isRoot.set(objref); 361 refThread.set(objref, tid); 362 } 363 } 364 365 370 void markStaticRoot (int objref) { 371 if (objref == -1) { 372 return; 373 } 374 375 isRoot.set(objref); 376 refThread.set(objref, -1); 377 elements[objref].setShared(); 378 } 379 380 void markPinnedDown (int objref){ 381 isRoot.set(objref); 382 refThread.set(objref, -1); 383 } 385 386 public boolean isSchedulingRelevantObject (int objRef) { 387 if (objRef == -1) return false; 388 389 return elements[objRef].isSchedulingRelevant(); 390 } 391 392 public ElementInfo get (int index) { 393 if ((index < 0) || (index >= elements.length)) { 394 return null; 395 } 396 397 return super.get(index); 398 } 399 400 public void log () { 401 Debug.println(Debug.MESSAGE, "DA"); 402 403 for (int i = 0; i < elements.length; i++) { 404 if (elements[i] != null) { 405 elements[i].log(); 406 } 407 } 408 } 409 410 411 414 public int newArray (String type, int size, ThreadInfo th) { 415 if (!Types.isTypeCode(type)) { 417 type = Types.getTypeCode(type); 418 } 419 420 int idx = newArray(indexFor(th), type, size); 421 422 if (th != null) { JVM.getVM().notifyObjectCreated(th, elements[idx]); 424 } 425 426 428 return idx; 429 } 430 431 435 public int newConstantString (String str) { 436 Integer objValue = (Integer ) String2Object.get(str); 437 438 if (objValue == null) { 439 int newObjRef = newString(str, null); 441 String2Object.put(str, new Integer (newObjRef)); 442 443 return newObjRef; 444 } else { 445 int objRef = objValue.intValue(); 446 447 ElementInfo ei = get(objRef); 449 450 if (ei == null) { 451 int newObjRef = newString(str, null); 453 String2Object.remove(str); 454 String2Object.put(str, new Integer (newObjRef)); 455 456 return newObjRef; 457 } else { 458 if (!(ei.getClassInfo().getName().equals("java.lang.String") && ei.asString() 459 .equals(str))) { 460 int newObjRef = newString(str, null); 462 String2Object.remove(str); 463 String2Object.put(str, new Integer (newObjRef)); 464 465 return newObjRef; 466 } 467 } 468 469 return objRef; 470 } 471 } 472 473 476 public int newObject (ClassInfo ci, ThreadInfo th) { 477 int index; 478 479 if (!ks.sa.containsClass(ci.getName())) { 484 ks.sa.newClass(ci); 485 } 486 487 Fields f = ci.createInstanceFields(); 489 Monitor m = new Monitor(); 490 491 DynamicElementInfo dei = new DynamicElementInfo(f, m); 492 493 index = indexFor(th); 497 498 add(index, dei); 500 501 if (th != null) { JVM.getVM().notifyObjectCreated(th, dei); 503 } 504 505 510 return index; 511 } 512 513 516 public int newString (String str, ThreadInfo th) { 517 int length = str.length(); 518 int index = newObject(ClassInfo.getClassInfo("java.lang.String"),th); 519 int value = newArray("C", length, th); 520 521 ElementInfo e = get(index); 522 e.setReferenceField("value", value); 525 e.setIntField("offset", 0); 526 e.setIntField("count", length); 527 528 e = get(value); 529 for (int i = 0; i < length; i++) { 530 e.setElement(i, str.charAt(i)); 531 } 532 533 return index; 534 } 535 536 541 void checkWeakRefs () { 542 if (weakRefs != null) { 543 int len = weakRefs.size(); 544 545 for (int i = 0; i < len; i++) { 546 Fields f = (Fields) weakRefs.get(i); 547 int ref = f.getIntValue(0); if (ref != -1) { 549 if ((elements[ref] == null) || (elements[ref].isNull())) { 550 f.setReferenceValue(0, -1); 551 } 552 } 553 } 554 555 weakRefs = null; 556 } 557 } 558 559 ElementInfo createElementInfo () { 560 return new DynamicElementInfo(); 561 } 562 563 void registerWeakReference (Fields f) { 564 if (weakRefs == null) { 565 weakRefs = new ArrayList (); 566 } 567 568 weakRefs.add(f); 569 } 570 571 private int indexFor (ThreadInfo th) { 572 Instruction pc = (th != null) ? th.getPC() : null; 573 synchronized (DynamicMap.class) { 574 int index; 575 int length; 576 577 DynamicMapIndex i = new DynamicMapIndex(pc, (th == null) ? 0 : th.index, 0); 578 579 if (!DynamicMap.hasEntry(i)) { 580 index = DynamicMap.addEntry(i); 581 } else { 582 index = DynamicMap.getEntry(i); 583 length = elements.length; 584 585 while ((index < length) && (elements[index] != null)) { 586 i.next(); 587 588 if (!DynamicMap.hasEntry(i)) { 589 index = DynamicMap.addEntry(i); 590 591 break; 592 } 593 594 index = DynamicMap.getEntry(i); 595 } 596 } 597 598 return index; 599 } 600 } 601 602 605 private int newArray (int index, String type, int size) { 606 int ts = Types.getTypeSize(type); 607 boolean ir = Types.isReference(type); 608 String clsName = "[" + type; 609 610 Fields f = new ArrayFields(clsName, ClassInfo.getClassInfo(clsName), 611 size * ts, size, ir); 612 Monitor m = new Monitor(); 613 614 ElementInfo e = new DynamicElementInfo(f, m); 615 add(index, e); 616 617 return index; 618 } 619 620 623 private int newObject (int index, ClassInfo ci) { 624 ks.sa.get(ci.getName()); 627 628 Fields f = ci.createInstanceFields(); 629 Monitor m = new Monitor(); 630 631 add(index, new DynamicElementInfo(f, m)); 632 633 return index; 634 } 635 636 641 642 private HashMap Object2Value; 643 644 private int lincount; 645 646 private PredicateMap pMap = null; 647 648 public Vector linearizeRoot(int objref) { 649 Object2Value = new HashMap (); 650 lincount = 0; 651 Vector result = new Vector (); 652 return linearize(objref,result); 653 } 654 655 public Vector linearizeRoot(int objref, PredicateMap obj) { 656 Object2Value = new HashMap (); 657 lincount = 0; 658 Vector result = new Vector (); 659 pMap = obj; 660 return linearize(objref,result); 661 } 662 667 class structureMap extends PredicateMap { 668 public void evaluate() { 669 } 670 public String getRep() { 671 return ""; 672 } 673 } 674 675 public Vector linearize(int objref, Vector result) { 676 677 PredicateMap mapObj = pMap; 678 679 if (objref == -1) { 680 result.addElement("-1"); 681 return result; 682 } 683 684 if (mapObj == null) 685 mapObj = new structureMap(); 686 687 mapObj.setRef(objref); 688 String refRep = "" + mapObj.getRef(); 689 690 String objRep; 691 692 if (Object2Value.containsKey(refRep)) { 693 objRep = Object2Value.get(refRep).toString(); 694 result.addElement(objRep); 695 return result; 696 } 697 else { 698 Object2Value.put(refRep,new Integer (lincount)); 699 mapObj.evaluate(); 700 objRep = "" + lincount + mapObj.getRep(); 701 lincount++; 702 } 703 704 result.addElement(objRep); 705 706 ElementInfo ei = elements[objref]; 707 return ei.linearize(result); 708 } 709 } 710 711 712 | Popular Tags |