/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "oops/markOop.inline.hpp"
#include "oops/oop.inline.hpp"
/////////////////////////////////////////////////////////////////////////
//// PromotionInfo
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// We go over the list of promoted objects, removing each from the list,
// and applying the closure (this may, in turn, add more elements to
// the tail of the promoted list, and these newly added objects will
// also be processed) until the list is empty.
// To aid verification and debugging, in the non-product builds
// we actually forward _promoHead each time we process a promoted oop.
// Note that this is not necessary in general (i.e. when we don't need to
// call PromotionInfo::verify()) because oop_iterate can only add to the
// end of _promoTail, and never needs to look at _promoHead.
\
NOT_PRODUCT(verify()); \
/* protect ourselves against additions due to closure application \
below by resetting the list. */ \
} \
if (curObj->hasDisplacedMark()) { \
/* restore displaced header */ \
} else { \
/* restore prototypical header */ \
} \
/* The "promoted_mark" should now not be set */ \
"Should have been cleared by restoring displaced mark-word"); \
nextObj = _promoHead; \
} \
} \
}
// This should have been ALL_SINCE_...() just like the others,
// but, because the body of the method above is somehwat longer,
// the MSVC compiler cannot cope; as a workaround, we split the
// macro into its 3 constituent parts below (see original macro
// definition in specializedOopClosures.hpp).
// Return the next displaced header, incrementing the pointer and
// recycling spool area as necessary.
"Empty spool space: no displaced header can be fetched");
// Spool forward
// forward to next block, recycling this block into spare spool buffer
_spoolHead = tmp;
_firstIndex = 1;
"spool buffers processing inconsistency");
}
)
}
return hdr;
}
}
// make a copy of header as it may need to be spooled
trackOop->clear_next();
// save non-prototypical header, and mark oop
} else {
// we'd like to assert something like the following:
// assert(mark == markOopDesc::prototype(), "consistency check");
// ... but the above won't work because the age bits have not (yet) been
// cleared. The remainder of the check would be identical to the
// condition checked in must_be_preserved() above, so we don't really
// have anything useful to check here!
}
if (_promoTail != NULL) {
} else {
}
// Mask as newly promoted, so we can skip over such objects
// when scanning dirty cards
}
// Save the given displaced header, incrementing the pointer and
// obtaining more spool area as necessary.
"promotionInfo inconsistency");
// Spool forward
// get a new spooling block
// ... but will attempt filling before next promotion attempt
_nextIndex = 1;
}
}
// Ensure that spooling space exists. Return false if spooling space
// could not be obtained.
// Try and obtain more spooling space
"getSpoolBlock() sanity check");
return false;
}
_nextIndex = 1;
if (_spoolTail == NULL) {
if (_spoolHead == NULL) {
_firstIndex = 1;
} else {
"Splice point invariant");
// Extra check that _splice_point is connected to list
#ifdef ASSERT
{
"Splice point incorrect");
}
#endif // ASSERT
}
} else {
}
return true;
}
// Get a free spool buffer from the free pool, getting a new block
// from the heap if necessary.
} else { // spare spool exhausted, get some from heap
}
}
return res;
}
"spooling inconsistency?");
_tracking = true;
}
"spooling inconsistency?");
_tracking = false;
if (CMSPrintPromoBlockInfo > 1) {
}
}
"Else will undercount");
// Count the number of blocks and slots in the free pool
// the first entry is just a self-pointer; indices 1 through
// bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
"first entry of displacedHdr should be self-referential");
blocks++;
}
if (_spoolHead != NULL) {
blocks++;
}
}
// When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex>
// points to the next slot available for filling.
// The set of slots holding displaced headers are then all those in the
// right-open interval denoted by:
//
// [ <_spoolHead, _firstIndex>, <_spoolTail, _nextIndex> )
//
// When _spoolTail is NULL, then the set of slots with displaced headers
// is all those starting at the slot <_spoolHead, _firstIndex> and
// going up to the last slot of last block in the linked list.
// In this lartter case, _splice_point points to the tail block of
// this linked list of blocks holding displaced headers.
// Verify the following:
// 1. the number of displaced headers matches the number of promoted
// objects that have displaced headers
// 2. each promoted object lies in this space
"Offset of PromotedObject::_next is expected to align with "
" the OopDesc::_mark within OopDesc");
)
// FIXME: guarantee????
// count the number of objects with displaced headers
// the last promoted object may fail the mark() != NULL test of is_oop().
if (curObj->hasDisplacedMark()) {
}
}
// Count the number of displaced headers
// the first entry is just a self-pointer; indices 1 through
// bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
"first entry of displacedHdr should be self-referential");
}
"internal consistency");
"Inconsistency between _spoolTail and _nextIndex");
// We overcounted (_firstIndex-1) worth of slots in block
// _spoolHead and we undercounted (_nextIndex-1) worth of
// slots in block _spoolTail. We make an appropriate
// adjustment by subtracting the first and adding the
// second: - (_firstIndex - 1) + (_nextIndex - 1)
}
size_t i = 0;
i++;
}
i++;
}
i++;
}
}
}