1 /*
2 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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 }
|
1 /*
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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 }
|