< prev index next > src/hotspot/share/oops/arrayOop.hpp
Print this page
// Header size computation.
// The header is considered the oop part of this type plus the length.
// Returns the aligned header_size_in_bytes. This is not equivalent to
// sizeof(arrayOopDesc) which should not appear in the code.
static int header_size_in_bytes() {
- size_t hs = align_up(length_offset_in_bytes() + sizeof(int),
- HeapWordSize);
+ size_t hs = length_offset_in_bytes() + sizeof(int);
#ifdef ASSERT
// make sure it isn't called before UseCompressedOops is initialized.
static size_t arrayoopdesc_hs = 0;
if (arrayoopdesc_hs == 0) arrayoopdesc_hs = hs;
assert(arrayoopdesc_hs == hs, "header size can't change");
// Check whether an element of a typeArrayOop with the given type must be
// aligned 0 mod 8. The typeArrayOop itself must be aligned at least this
// strongly.
static bool element_type_should_be_aligned(BasicType type) {
+ #ifdef _LP64
+ if (type == T_OBJECT || type == T_ARRAY) {
+ return !UseCompressedOops;
+ }
+ #endif
return type == T_DOUBLE || type == T_LONG;
}
public:
// The _length field is not declared in C++. It is allocated after the
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise
// it occupies the second half of the _klass field in oopDesc.
static int length_offset_in_bytes() {
- return UseCompressedClassPointers ? klass_gap_offset_in_bytes() :
- sizeof(arrayOopDesc);
+ return oopDesc::base_offset_in_bytes();
}
// Returns the offset of the first element.
static int base_offset_in_bytes(BasicType type) {
- return header_size(type) * HeapWordSize;
+ size_t typesize_in_bytes = header_size_in_bytes();
+ return (int)(element_type_should_be_aligned(type)
+ ? align_up(typesize_in_bytes, BytesPerLong)
+ : typesize_in_bytes);
}
// Returns the address of the first element. The elements in the array will not
// relocate from this address until a subsequent thread transition.
void* base(BasicType type) const {
// Should only be called with constants as argument
// (will not constant fold otherwise)
// Returns the header size in words aligned to the requirements of the
// array object type.
static int header_size(BasicType type) {
+ assert(!UseCompactObjectHeaders, "Don't use this with compact headers");
size_t typesize_in_bytes = header_size_in_bytes();
return (int)(element_type_should_be_aligned(type)
? align_object_offset(typesize_in_bytes/HeapWordSize)
: typesize_in_bytes/HeapWordSize);
}
// 32 bit platforms when we convert it to a byte size.
static int32_t max_array_length(BasicType type) {
assert(type >= 0 && type < T_CONFLICT, "wrong type");
assert(type2aelembytes(type) != 0, "wrong type");
- const size_t max_element_words_per_size_t =
- align_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
- const size_t max_elements_per_size_t =
- HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
+ const size_t max_size_bytes = align_down(SIZE_MAX - base_offset_in_bytes(type), MinObjAlignmentInBytes);
+ const size_t max_elements_per_size_t = max_size_bytes / type2aelembytes(type);
if ((size_t)max_jint < max_elements_per_size_t) {
// It should be ok to return max_jint here, but parts of the code
// (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
// passing around the size (in words) of an object. So, we need to avoid
// overflowing an int when we add the header. See CRs 4718400 and 7110613.
- return align_down(max_jint - header_size(type), MinObjAlignment);
+ int header_size_words = align_up(base_offset_in_bytes(type), HeapWordSize) / HeapWordSize;
+ return align_down(max_jint - header_size_words, MinObjAlignment);
}
return (int32_t)max_elements_per_size_t;
}
};
< prev index next >