< prev index next >

src/hotspot/share/gc/z/zObjArrayAllocator.cpp

Print this page
*** 48,11 ***
    // 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 = ZUtils::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);
--- 48,21 ---
    // 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 = ZUtils::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);

*** 64,12 ***
    // cleared, therefore we can't expose the header at the end of this
    // function. Instead explicitly initialize it according to our needs.
  
    // Signal to the ZIterator that this is an invisible root, by setting
    // the mark word to "marked". Reset to prototype() after the clearing.
!   arrayOopDesc::set_mark(mem, markWord::prototype().set_marked());
!   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 iterator
--- 74,16 ---
    // cleared, therefore we can't expose the header at the end of this
    // function. Instead explicitly initialize it according to our needs.
  
    // Signal to the ZIterator that this is an invisible root, by setting
    // the mark word to "marked". Reset to prototype() after the clearing.
!   if (UseCompactObjectHeaders) {
!     arrayOopDesc::release_set_mark(mem, _klass->prototype_header().set_marked());
+   } else {
+     arrayOopDesc::set_mark(mem, markWord::prototype().set_marked());
+     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 iterator

*** 133,9 ***
    }
  
    ZThreadLocalData::clear_invisible_root(_thread);
  
    // Signal to the ZIterator that this is no longer an invisible root
!   oopDesc::release_set_mark(mem, markWord::prototype());
  
    return cast_to_oop(mem);
  }
--- 147,13 ---
    }
  
    ZThreadLocalData::clear_invisible_root(_thread);
  
    // Signal to the ZIterator that this is no longer an invisible root
!   if (UseCompactObjectHeaders) {
+     oopDesc::release_set_mark(mem, _klass->prototype_header());
+   } else {
+     oopDesc::release_set_mark(mem, markWord::prototype());
+   }
  
    return cast_to_oop(mem);
  }
< prev index next >