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 *
23 */
24
25 //
26 // The ObjectHeap is an abstraction over all generations in the VM
27 // It gives access to all present objects and classes.
28 //
29
30 package sun.jvm.hotspot.oops;
31
32 import java.util.*;
33
34 import sun.jvm.hotspot.debugger.*;
35 import sun.jvm.hotspot.gc.cms.*;
36 import sun.jvm.hotspot.gc.shared.*;
37 import sun.jvm.hotspot.gc.epsilon.*;
38 import sun.jvm.hotspot.gc.g1.*;
39 import sun.jvm.hotspot.gc.parallel.*;
40 import sun.jvm.hotspot.gc.z.*;
41 import sun.jvm.hotspot.memory.*;
42 import sun.jvm.hotspot.runtime.*;
43 import sun.jvm.hotspot.types.*;
44 import sun.jvm.hotspot.utilities.*;
45
46 public class ObjectHeap {
47
48 private static final boolean DEBUG;
49
50 static {
51 DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null;
52 }
53
54 public ObjectHeap(TypeDataBase db) throws WrongTypeException {
55 // Get commonly used sizes of basic types
56 oopSize = VM.getVM().getOopSize();
57 byteSize = db.getJByteType().getSize();
58 charSize = db.getJCharType().getSize();
228 long totalSize = 0;
229 for (int i = 0; i < liveRegions.size(); i += 2) {
230 Address bottom = (Address) liveRegions.get(i);
231 Address top = (Address) liveRegions.get(i+1);
232 totalSize += top.minus(bottom);
233 }
234 visitor.prologue(totalSize);
235
236 CompactibleFreeListSpace cmsSpaceOld = null;
237 CollectedHeap heap = VM.getVM().getUniverse().heap();
238
239 if (heap instanceof GenCollectedHeap) {
240 GenCollectedHeap genHeap = (GenCollectedHeap) heap;
241 Generation genOld = genHeap.getGen(1);
242 if (genOld instanceof ConcurrentMarkSweepGeneration) {
243 ConcurrentMarkSweepGeneration concGen = (ConcurrentMarkSweepGeneration)genOld;
244 cmsSpaceOld = concGen.cmsSpace();
245 }
246 }
247
248 for (int i = 0; i < liveRegions.size(); i += 2) {
249 Address bottom = (Address) liveRegions.get(i);
250 Address top = (Address) liveRegions.get(i+1);
251
252 try {
253 // Traverses the space from bottom to top
254 OopHandle handle = bottom.addOffsetToAsOopHandle(0);
255
256 while (handle.lessThan(top)) {
257 Oop obj = null;
258
259 try {
260 obj = newOop(handle);
261 } catch (UnknownOopException exp) {
262 if (DEBUG) {
263 throw new RuntimeException(" UnknownOopException " + exp);
264 }
265 }
266 if (obj == null) {
267 //Find the object size using Printezis bits and skip over
268 long size = 0;
269
270 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle) ){
271 size = cmsSpaceOld.collector().blockSizeUsingPrintezisBits(handle);
272 }
273
274 if (size <= 0) {
275 //Either Printezis bits not set or handle is not in cms space.
276 throw new UnknownOopException();
277 }
278
279 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(size));
280 continue;
281 }
282 if (of == null || of.canInclude(obj)) {
283 if (visitor.doObj(obj)) {
284 // doObj() returns true to abort this loop.
285 break;
286 }
287 }
288 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle)) {
289 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(obj.getObjectSize()) );
290 } else {
291 handle = handle.addOffsetToAsOopHandle(obj.getObjectSize());
292 }
293 }
294 }
295 catch (AddressException e) {
296 // This is okay at the top of these regions
297 }
298 catch (UnknownOopException e) {
299 // This is okay at the top of these regions
300 }
301 }
302
303 visitor.epilogue();
304 }
305
306 private void addLiveRegions(String name, List input, List output) {
307 for (Iterator itr = input.iterator(); itr.hasNext();) {
308 MemRegion reg = (MemRegion) itr.next();
309 Address top = reg.end();
310 Address bottom = reg.start();
311 if (Assert.ASSERTS_ENABLED) {
350
351 if (heap instanceof GenCollectedHeap) {
352 GenCollectedHeap genHeap = (GenCollectedHeap) heap;
353 // Run through all generations, obtaining bottom-top pairs.
354 for (int i = 0; i < genHeap.nGens(); i++) {
355 Generation gen = genHeap.getGen(i);
356 gen.spaceIterate(lrc, true);
357 }
358 } else if (heap instanceof ParallelScavengeHeap) {
359 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap;
360 PSYoungGen youngGen = psh.youngGen();
361 // Add eden space
362 addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions);
363 // Add from-space but not to-space
364 addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions);
365 PSOldGen oldGen = psh.oldGen();
366 addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions);
367 } else if (heap instanceof G1CollectedHeap) {
368 G1CollectedHeap g1h = (G1CollectedHeap) heap;
369 g1h.heapRegionIterate(lrc);
370 } else if (heap instanceof ZCollectedHeap) {
371 // Operation (currently) not supported with ZGC. Print
372 // a warning and leave the list of live regions empty.
373 System.err.println("Warning: Operation not supported with ZGC");
374 } else if (heap instanceof EpsilonHeap) {
375 EpsilonHeap eh = (EpsilonHeap) heap;
376 liveRegions.add(eh.space().top());
377 liveRegions.add(eh.space().bottom());
378 } else {
379 if (Assert.ASSERTS_ENABLED) {
380 Assert.that(false, "Unexpected CollectedHeap type: " + heap.getClass().getName());
381 }
382 }
383
384 // If UseTLAB is enabled, snip out regions associated with TLABs'
385 // dead regions. Note that TLABs can be present in any generation.
386
387 // FIXME: consider adding fewer boundaries to live region list.
388 // Theoretically only need to stop at TLAB's top and resume at its
389 // end.
|
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 *
23 */
24
25 //
26 // The ObjectHeap is an abstraction over all generations in the VM
27 // It gives access to all present objects and classes.
28 //
29
30 package sun.jvm.hotspot.oops;
31
32 import java.util.*;
33
34 import sun.jvm.hotspot.debugger.*;
35 import sun.jvm.hotspot.gc.cms.*;
36 import sun.jvm.hotspot.gc.shared.*;
37 import sun.jvm.hotspot.gc.epsilon.*;
38 import sun.jvm.hotspot.gc.g1.*;
39 import sun.jvm.hotspot.gc.shenandoah.*;
40 import sun.jvm.hotspot.gc.parallel.*;
41 import sun.jvm.hotspot.gc.z.*;
42 import sun.jvm.hotspot.memory.*;
43 import sun.jvm.hotspot.runtime.*;
44 import sun.jvm.hotspot.types.*;
45 import sun.jvm.hotspot.utilities.*;
46
47 public class ObjectHeap {
48
49 private static final boolean DEBUG;
50
51 static {
52 DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null;
53 }
54
55 public ObjectHeap(TypeDataBase db) throws WrongTypeException {
56 // Get commonly used sizes of basic types
57 oopSize = VM.getVM().getOopSize();
58 byteSize = db.getJByteType().getSize();
59 charSize = db.getJCharType().getSize();
229 long totalSize = 0;
230 for (int i = 0; i < liveRegions.size(); i += 2) {
231 Address bottom = (Address) liveRegions.get(i);
232 Address top = (Address) liveRegions.get(i+1);
233 totalSize += top.minus(bottom);
234 }
235 visitor.prologue(totalSize);
236
237 CompactibleFreeListSpace cmsSpaceOld = null;
238 CollectedHeap heap = VM.getVM().getUniverse().heap();
239
240 if (heap instanceof GenCollectedHeap) {
241 GenCollectedHeap genHeap = (GenCollectedHeap) heap;
242 Generation genOld = genHeap.getGen(1);
243 if (genOld instanceof ConcurrentMarkSweepGeneration) {
244 ConcurrentMarkSweepGeneration concGen = (ConcurrentMarkSweepGeneration)genOld;
245 cmsSpaceOld = concGen.cmsSpace();
246 }
247 }
248
249 int cell_header_size = heap.cell_header_size();
250
251 for (int i = 0; i < liveRegions.size(); i += 2) {
252 Address bottom = (Address) liveRegions.get(i);
253 Address top = (Address) liveRegions.get(i+1);
254
255 try {
256 // Traverses the space from bottom to top
257 OopHandle handle = bottom.addOffsetToAsOopHandle(cell_header_size);
258
259 while (handle.lessThan(top)) {
260 Oop obj = null;
261
262 try {
263 obj = newOop(handle);
264 } catch (UnknownOopException exp) {
265 if (DEBUG) {
266 throw new RuntimeException(" UnknownOopException " + exp);
267 }
268 }
269 if (obj == null) {
270 //Find the object size using Printezis bits and skip over
271 long size = 0;
272
273 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle) ){
274 size = cmsSpaceOld.collector().blockSizeUsingPrintezisBits(handle);
275 }
276
277 if (size <= 0) {
278 //Either Printezis bits not set or handle is not in cms space.
279 throw new UnknownOopException();
280 }
281
282 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(size));
283 continue;
284 }
285 if (of == null || of.canInclude(obj)) {
286 if (visitor.doObj(obj)) {
287 // doObj() returns true to abort this loop.
288 break;
289 }
290 }
291 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle)) {
292 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(obj.getObjectSize()) );
293 } else {
294 handle = handle.addOffsetToAsOopHandle(obj.getObjectSize() + cell_header_size);
295 }
296 }
297 }
298 catch (AddressException e) {
299 // This is okay at the top of these regions
300 }
301 catch (UnknownOopException e) {
302 // This is okay at the top of these regions
303 }
304 }
305
306 visitor.epilogue();
307 }
308
309 private void addLiveRegions(String name, List input, List output) {
310 for (Iterator itr = input.iterator(); itr.hasNext();) {
311 MemRegion reg = (MemRegion) itr.next();
312 Address top = reg.end();
313 Address bottom = reg.start();
314 if (Assert.ASSERTS_ENABLED) {
353
354 if (heap instanceof GenCollectedHeap) {
355 GenCollectedHeap genHeap = (GenCollectedHeap) heap;
356 // Run through all generations, obtaining bottom-top pairs.
357 for (int i = 0; i < genHeap.nGens(); i++) {
358 Generation gen = genHeap.getGen(i);
359 gen.spaceIterate(lrc, true);
360 }
361 } else if (heap instanceof ParallelScavengeHeap) {
362 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap;
363 PSYoungGen youngGen = psh.youngGen();
364 // Add eden space
365 addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions);
366 // Add from-space but not to-space
367 addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions);
368 PSOldGen oldGen = psh.oldGen();
369 addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions);
370 } else if (heap instanceof G1CollectedHeap) {
371 G1CollectedHeap g1h = (G1CollectedHeap) heap;
372 g1h.heapRegionIterate(lrc);
373 } else if (heap instanceof ShenandoahHeap) {
374 ShenandoahHeap sh = (ShenandoahHeap) heap;
375 sh.heapRegionIterate(lrc);
376 } else if (heap instanceof ZCollectedHeap) {
377 // Operation (currently) not supported with ZGC. Print
378 // a warning and leave the list of live regions empty.
379 System.err.println("Warning: Operation not supported with ZGC");
380 } else if (heap instanceof EpsilonHeap) {
381 EpsilonHeap eh = (EpsilonHeap) heap;
382 liveRegions.add(eh.space().top());
383 liveRegions.add(eh.space().bottom());
384 } else {
385 if (Assert.ASSERTS_ENABLED) {
386 Assert.that(false, "Unexpected CollectedHeap type: " + heap.getClass().getName());
387 }
388 }
389
390 // If UseTLAB is enabled, snip out regions associated with TLABs'
391 // dead regions. Note that TLABs can be present in any generation.
392
393 // FIXME: consider adding fewer boundaries to live region list.
394 // Theoretically only need to stop at TLAB's top and resume at its
395 // end.
|