< prev index next > src/hotspot/share/gc/x/xObjArrayAllocator.cpp
Print this page
// A max segment size of 64K was chosen because microbenchmarking
// suggested that it offered a good trade-off between allocation
// time and time-to-safepoint
const size_t segment_max = XUtils::bytes_to_words(64 * K);
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
! const size_t header = arrayOopDesc::header_size(element_type);
const size_t payload_size = _word_size - header;
if (payload_size <= segment_max) {
// To small to use segmented clearing
return ObjArrayAllocator::initialize(mem);
// A max segment size of 64K was chosen because microbenchmarking
// suggested that it offered a good trade-off between allocation
// time and time-to-safepoint
const size_t segment_max = XUtils::bytes_to_words(64 * K);
const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
!
+ // Clear leading 32 bits, if necessary.
+ int base_offset = arrayOopDesc::base_offset_in_bytes(element_type);
+ if (!is_aligned(base_offset, HeapWordSize)) {
+ assert(is_aligned(base_offset, BytesPerInt), "array base must be 32 bit aligned");
+ *reinterpret_cast<jint*>(reinterpret_cast<char*>(mem) + base_offset) = 0;
+ base_offset += BytesPerInt;
+ }
+ assert(is_aligned(base_offset, HeapWordSize), "remaining array base must be 64 bit aligned");
+
+ const size_t header = heap_word_size(base_offset);
const size_t payload_size = _word_size - header;
if (payload_size <= segment_max) {
// To small to use segmented clearing
return ObjArrayAllocator::initialize(mem);
// Segmented clearing
// The array is going to be exposed before it has been completely
// cleared, therefore we can't expose the header at the end of this
// function. Instead explicitly initialize it according to our needs.
! arrayOopDesc::set_mark(mem, markWord::prototype());
! arrayOopDesc::release_set_klass(mem, _klass);
assert(_length >= 0, "length should be non-negative");
arrayOopDesc::set_length(mem, _length);
// Keep the array alive across safepoints through an invisible
// root. Invisible roots are not visited by the heap itarator
// Segmented clearing
// The array is going to be exposed before it has been completely
// cleared, therefore we can't expose the header at the end of this
// function. Instead explicitly initialize it according to our needs.
! if (UseCompactObjectHeaders) {
! arrayOopDesc::release_set_mark(mem, _klass->prototype_header());
+ } else {
+ arrayOopDesc::set_mark(mem, markWord::prototype());
+ arrayOopDesc::release_set_klass(mem, _klass);
+ }
assert(_length >= 0, "length should be non-negative");
arrayOopDesc::set_length(mem, _length);
// Keep the array alive across safepoints through an invisible
// root. Invisible roots are not visited by the heap itarator
< prev index next >