26 #include "gc/cms/compactibleFreeListSpace.hpp"
27 #include "gc/cms/promotionInfo.hpp"
28 #include "gc/shared/genOopClosures.hpp"
29 #include "oops/markOop.inline.hpp"
30 #include "oops/oop.inline.hpp"
31
32 /////////////////////////////////////////////////////////////////////////
33 //// PromotionInfo
34 /////////////////////////////////////////////////////////////////////////
35
36
37 PromotedObject* PromotedObject::next() const {
38 assert(!((FreeChunk*)this)->is_free(), "Error");
39 PromotedObject* res;
40 if (UseCompressedOops) {
41 // The next pointer is a compressed oop stored in the top 32 bits
42 res = (PromotedObject*)oopDesc::decode_heap_oop(_data._narrow_next);
43 } else {
44 res = (PromotedObject*)(_next & next_mask);
45 }
46 assert(oop(res)->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res)));
47 return res;
48 }
49
50 inline void PromotedObject::setNext(PromotedObject* x) {
51 assert(((intptr_t)x & ~next_mask) == 0, "Conflict in bit usage, "
52 "or insufficient alignment of objects");
53 if (UseCompressedOops) {
54 assert(_data._narrow_next == 0, "Overwrite?");
55 _data._narrow_next = oopDesc::encode_heap_oop(oop(x));
56 } else {
57 _next |= (intptr_t)x;
58 }
59 assert(!((FreeChunk*)this)->is_free(), "Error");
60 }
61
62 //////////////////////////////////////////////////////////////////////////////
63 // We go over the list of promoted objects, removing each from the list,
64 // and applying the closure (this may, in turn, add more elements to
65 // the tail of the promoted list, and these newly added objects will
66 // also be processed) until the list is empty.
282 void PromotionInfo::verify() const {
283 // Verify the following:
284 // 1. the number of displaced headers matches the number of promoted
285 // objects that have displaced headers
286 // 2. each promoted object lies in this space
287 debug_only(
288 PromotedObject* junk = NULL;
289 assert(junk->next_addr() == (void*)(oop(junk)->mark_addr()),
290 "Offset of PromotedObject::_next is expected to align with "
291 " the OopDesc::_mark within OopDesc");
292 )
293 // FIXME: guarantee????
294 guarantee(_spoolHead == NULL || _spoolTail != NULL ||
295 _splice_point != NULL, "list consistency");
296 guarantee(_promoHead == NULL || _promoTail != NULL, "list consistency");
297 // count the number of objects with displaced headers
298 size_t numObjsWithDisplacedHdrs = 0;
299 for (PromotedObject* curObj = _promoHead; curObj != NULL; curObj = curObj->next()) {
300 guarantee(space()->is_in_reserved((HeapWord*)curObj), "Containment");
301 // the last promoted object may fail the mark() != NULL test of is_oop().
302 guarantee(curObj->next() == NULL || oop(curObj)->is_oop(), "must be an oop");
303 if (curObj->hasDisplacedMark()) {
304 numObjsWithDisplacedHdrs++;
305 }
306 }
307 // Count the number of displaced headers
308 size_t numDisplacedHdrs = 0;
309 for (SpoolBlock* curSpool = _spoolHead;
310 curSpool != _spoolTail && curSpool != NULL;
311 curSpool = curSpool->nextSpoolBlock) {
312 // the first entry is just a self-pointer; indices 1 through
313 // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
314 guarantee((void*)curSpool->displacedHdr == (void*)&curSpool->displacedHdr,
315 "first entry of displacedHdr should be self-referential");
316 numDisplacedHdrs += curSpool->bufferSize - 1;
317 }
318 guarantee((_spoolHead == _spoolTail) == (numDisplacedHdrs == 0),
319 "internal consistency");
320 guarantee(_spoolTail != NULL || _nextIndex == 1,
321 "Inconsistency between _spoolTail and _nextIndex");
322 // We overcounted (_firstIndex-1) worth of slots in block
|
26 #include "gc/cms/compactibleFreeListSpace.hpp"
27 #include "gc/cms/promotionInfo.hpp"
28 #include "gc/shared/genOopClosures.hpp"
29 #include "oops/markOop.inline.hpp"
30 #include "oops/oop.inline.hpp"
31
32 /////////////////////////////////////////////////////////////////////////
33 //// PromotionInfo
34 /////////////////////////////////////////////////////////////////////////
35
36
37 PromotedObject* PromotedObject::next() const {
38 assert(!((FreeChunk*)this)->is_free(), "Error");
39 PromotedObject* res;
40 if (UseCompressedOops) {
41 // The next pointer is a compressed oop stored in the top 32 bits
42 res = (PromotedObject*)oopDesc::decode_heap_oop(_data._narrow_next);
43 } else {
44 res = (PromotedObject*)(_next & next_mask);
45 }
46 assert(oopDesc::is_oop_or_null(oop(res), true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res)));
47 return res;
48 }
49
50 inline void PromotedObject::setNext(PromotedObject* x) {
51 assert(((intptr_t)x & ~next_mask) == 0, "Conflict in bit usage, "
52 "or insufficient alignment of objects");
53 if (UseCompressedOops) {
54 assert(_data._narrow_next == 0, "Overwrite?");
55 _data._narrow_next = oopDesc::encode_heap_oop(oop(x));
56 } else {
57 _next |= (intptr_t)x;
58 }
59 assert(!((FreeChunk*)this)->is_free(), "Error");
60 }
61
62 //////////////////////////////////////////////////////////////////////////////
63 // We go over the list of promoted objects, removing each from the list,
64 // and applying the closure (this may, in turn, add more elements to
65 // the tail of the promoted list, and these newly added objects will
66 // also be processed) until the list is empty.
282 void PromotionInfo::verify() const {
283 // Verify the following:
284 // 1. the number of displaced headers matches the number of promoted
285 // objects that have displaced headers
286 // 2. each promoted object lies in this space
287 debug_only(
288 PromotedObject* junk = NULL;
289 assert(junk->next_addr() == (void*)(oop(junk)->mark_addr()),
290 "Offset of PromotedObject::_next is expected to align with "
291 " the OopDesc::_mark within OopDesc");
292 )
293 // FIXME: guarantee????
294 guarantee(_spoolHead == NULL || _spoolTail != NULL ||
295 _splice_point != NULL, "list consistency");
296 guarantee(_promoHead == NULL || _promoTail != NULL, "list consistency");
297 // count the number of objects with displaced headers
298 size_t numObjsWithDisplacedHdrs = 0;
299 for (PromotedObject* curObj = _promoHead; curObj != NULL; curObj = curObj->next()) {
300 guarantee(space()->is_in_reserved((HeapWord*)curObj), "Containment");
301 // the last promoted object may fail the mark() != NULL test of is_oop().
302 guarantee(curObj->next() == NULL || oopDesc::is_oop(oop(curObj)), "must be an oop");
303 if (curObj->hasDisplacedMark()) {
304 numObjsWithDisplacedHdrs++;
305 }
306 }
307 // Count the number of displaced headers
308 size_t numDisplacedHdrs = 0;
309 for (SpoolBlock* curSpool = _spoolHead;
310 curSpool != _spoolTail && curSpool != NULL;
311 curSpool = curSpool->nextSpoolBlock) {
312 // the first entry is just a self-pointer; indices 1 through
313 // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
314 guarantee((void*)curSpool->displacedHdr == (void*)&curSpool->displacedHdr,
315 "first entry of displacedHdr should be self-referential");
316 numDisplacedHdrs += curSpool->bufferSize - 1;
317 }
318 guarantee((_spoolHead == _spoolTail) == (numDisplacedHdrs == 0),
319 "internal consistency");
320 guarantee(_spoolTail != NULL || _nextIndex == 1,
321 "Inconsistency between _spoolTail and _nextIndex");
322 // We overcounted (_firstIndex-1) worth of slots in block
|