287 } 288 } 289 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle)) { 290 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(obj.getObjectSize()) ); 291 } else { 292 handle = handle.addOffsetToAsOopHandle(obj.getObjectSize()); 293 } 294 } 295 } 296 catch (AddressException e) { 297 // This is okay at the top of these regions 298 } 299 catch (UnknownOopException e) { 300 // This is okay at the top of these regions 301 } 302 } 303 304 visitor.epilogue(); 305 } 306 307 private void addLiveRegions(String name, List input, List output) { 308 for (Iterator itr = input.iterator(); itr.hasNext();) { 309 MemRegion reg = (MemRegion) itr.next(); 310 Address top = reg.end(); 311 Address bottom = reg.start(); 312 if (Assert.ASSERTS_ENABLED) { 313 Assert.that(top != null, "top address in a live region should not be null"); 314 } 315 if (Assert.ASSERTS_ENABLED) { 316 Assert.that(bottom != null, "bottom address in a live region should not be null"); 317 } 318 output.add(top); 319 output.add(bottom); 320 if (DEBUG) { 321 System.err.println("Live region: " + name + ": " + bottom + ", " + top); 322 } 323 } 324 } 325 326 private class LiveRegionsCollector implements SpaceClosure { 327 LiveRegionsCollector(List l) { 328 liveRegions = l; 329 } 330 331 public void doSpace(Space s) { 332 addLiveRegions(s.toString(), s.getLiveRegions(), liveRegions); 333 } 334 private List liveRegions; 335 } 336 337 // Returns a List<Address> where the addresses come in pairs. These 338 // designate the live regions of the heap. 339 private List collectLiveRegions() { 340 // We want to iterate through all live portions of the heap, but 341 // do not want to abort the heap traversal prematurely if we find 342 // a problem (like an allocated but uninitialized object at the 343 // top of a generation). To do this we enumerate all generations' 344 // bottom and top regions, and factor in TLABs if necessary. 345 346 // List<Address>. Addresses come in pairs. 347 List liveRegions = new ArrayList(); 348 LiveRegionsCollector lrc = new LiveRegionsCollector(liveRegions); 349 350 CollectedHeap heap = VM.getVM().getUniverse().heap(); 351 352 if (heap instanceof GenCollectedHeap) { 353 GenCollectedHeap genHeap = (GenCollectedHeap) heap; 354 // Run through all generations, obtaining bottom-top pairs. 355 for (int i = 0; i < genHeap.nGens(); i++) { 356 Generation gen = genHeap.getGen(i); 357 gen.spaceIterate(lrc, true); 358 } 359 } else if (heap instanceof ParallelScavengeHeap) { 360 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; 361 PSYoungGen youngGen = psh.youngGen(); 362 // Add eden space 363 addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions); 364 // Add from-space but not to-space 365 addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions); 366 PSOldGen oldGen = psh.oldGen(); 367 addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions); 368 } else if (heap instanceof G1CollectedHeap) { 369 G1CollectedHeap g1h = (G1CollectedHeap) heap; 370 g1h.heapRegionIterate(lrc); 371 } else if (heap instanceof ShenandoahHeap) { 372 // Operation (currently) not supported with Shenandoah GC. Print 373 // a warning and leave the list of live regions empty. 374 System.err.println("Warning: Operation not supported with Shenandoah GC"); 375 } else if (heap instanceof ZCollectedHeap) { 376 // Operation (currently) not supported with ZGC. Print 377 // a warning and leave the list of live regions empty. 378 System.err.println("Warning: Operation not supported with ZGC"); 379 } else if (heap instanceof EpsilonHeap) { 380 EpsilonHeap eh = (EpsilonHeap) heap; 381 liveRegions.add(eh.space().top()); 382 liveRegions.add(eh.space().bottom()); 383 } else { 384 if (Assert.ASSERTS_ENABLED) { 385 Assert.that(false, "Unexpected CollectedHeap type: " + heap.getClass().getName()); 386 } 387 } 388 389 // If UseTLAB is enabled, snip out regions associated with TLABs' 390 // dead regions. Note that TLABs can be present in any generation. 391 392 // FIXME: consider adding fewer boundaries to live region list. 393 // Theoretically only need to stop at TLAB's top and resume at its 394 // end. 395 396 if (VM.getVM().getUseTLAB()) { 397 for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { 398 ThreadLocalAllocBuffer tlab = thread.tlab(); 399 if (tlab.start() != null) { 400 if ((tlab.top() == null) || (tlab.end() == null)) { 401 System.err.print("Warning: skipping invalid TLAB for thread "); 402 thread.printThreadIDOn(System.err); 403 System.err.println(); 404 } else { 405 if (DEBUG) { 406 System.err.print("TLAB for " + thread.getThreadName() + ", #"); 407 thread.printThreadIDOn(System.err); 423 424 // Now sort live regions 425 sortLiveRegions(liveRegions); 426 427 if (Assert.ASSERTS_ENABLED) { 428 Assert.that(liveRegions.size() % 2 == 0, "Must have even number of region boundaries"); 429 } 430 431 if (DEBUG) { 432 System.err.println("liveRegions:"); 433 for (int i = 0; i < liveRegions.size(); i += 2) { 434 Address bottom = (Address) liveRegions.get(i); 435 Address top = (Address) liveRegions.get(i+1); 436 System.err.println(" " + bottom + " - " + top); 437 } 438 } 439 440 return liveRegions; 441 } 442 443 private void sortLiveRegions(List liveRegions) { 444 Collections.sort(liveRegions, new Comparator() { 445 public int compare(Object o1, Object o2) { 446 Address a1 = (Address) o1; 447 Address a2 = (Address) o2; 448 if (AddressOps.lt(a1, a2)) { 449 return -1; 450 } else if (AddressOps.gt(a1, a2)) { 451 return 1; 452 } 453 return 0; 454 } 455 }); 456 } 457 } | 287 } 288 } 289 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle)) { 290 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(obj.getObjectSize()) ); 291 } else { 292 handle = handle.addOffsetToAsOopHandle(obj.getObjectSize()); 293 } 294 } 295 } 296 catch (AddressException e) { 297 // This is okay at the top of these regions 298 } 299 catch (UnknownOopException e) { 300 // This is okay at the top of these regions 301 } 302 } 303 304 visitor.epilogue(); 305 } 306 307 private static class LiveRegionsCollector implements LiveRegionsClosure { 308 LiveRegionsCollector(List<Address> l) { 309 liveRegions = l; 310 } 311 312 @Override 313 public void doLiveRegions(LiveRegionsProvider lrp) { 314 for (MemRegion reg : lrp.getLiveRegions()) { 315 Address top = reg.end(); 316 Address bottom = reg.start(); 317 if (Assert.ASSERTS_ENABLED) { 318 Assert.that(top != null, "top address in a live region should not be null"); 319 } 320 if (Assert.ASSERTS_ENABLED) { 321 Assert.that(bottom != null, "bottom address in a live region should not be null"); 322 } 323 liveRegions.add(top); 324 liveRegions.add(bottom); 325 if (DEBUG) { 326 System.err.println("Live region: " + lrp + ": " + bottom + ", " + top); 327 } 328 } 329 } 330 331 private List<Address> liveRegions; 332 } 333 334 // Returns a List<Address> where the addresses come in pairs. These 335 // designate the live regions of the heap. 336 private List<Address> collectLiveRegions() { 337 // We want to iterate through all live portions of the heap, but 338 // do not want to abort the heap traversal prematurely if we find 339 // a problem (like an allocated but uninitialized object at the 340 // top of a generation). To do this we enumerate all generations' 341 // bottom and top regions, and factor in TLABs if necessary. 342 343 // Addresses come in pairs. 344 List<Address> liveRegions = new ArrayList<>(); 345 LiveRegionsCollector lrc = new LiveRegionsCollector(liveRegions); 346 347 CollectedHeap heap = VM.getVM().getUniverse().heap(); 348 heap.liveRegionsIterate(lrc); 349 350 // If UseTLAB is enabled, snip out regions associated with TLABs' 351 // dead regions. Note that TLABs can be present in any generation. 352 353 // FIXME: consider adding fewer boundaries to live region list. 354 // Theoretically only need to stop at TLAB's top and resume at its 355 // end. 356 357 if (VM.getVM().getUseTLAB()) { 358 for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { 359 ThreadLocalAllocBuffer tlab = thread.tlab(); 360 if (tlab.start() != null) { 361 if ((tlab.top() == null) || (tlab.end() == null)) { 362 System.err.print("Warning: skipping invalid TLAB for thread "); 363 thread.printThreadIDOn(System.err); 364 System.err.println(); 365 } else { 366 if (DEBUG) { 367 System.err.print("TLAB for " + thread.getThreadName() + ", #"); 368 thread.printThreadIDOn(System.err); 384 385 // Now sort live regions 386 sortLiveRegions(liveRegions); 387 388 if (Assert.ASSERTS_ENABLED) { 389 Assert.that(liveRegions.size() % 2 == 0, "Must have even number of region boundaries"); 390 } 391 392 if (DEBUG) { 393 System.err.println("liveRegions:"); 394 for (int i = 0; i < liveRegions.size(); i += 2) { 395 Address bottom = (Address) liveRegions.get(i); 396 Address top = (Address) liveRegions.get(i+1); 397 System.err.println(" " + bottom + " - " + top); 398 } 399 } 400 401 return liveRegions; 402 } 403 404 private void sortLiveRegions(List<Address> liveRegions) { 405 Collections.sort(liveRegions, new Comparator<Address>() { 406 public int compare(Address a1, Address a2) { 407 if (AddressOps.lt(a1, a2)) { 408 return -1; 409 } else if (AddressOps.gt(a1, a2)) { 410 return 1; 411 } 412 return 0; 413 } 414 }); 415 } 416 } |