aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/oops/arrayOop.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/vm/oops/arrayOop.hpp')
-rw-r--r--src/share/vm/oops/arrayOop.hpp77
1 files changed, 61 insertions, 16 deletions
diff --git a/src/share/vm/oops/arrayOop.hpp b/src/share/vm/oops/arrayOop.hpp
index 49fc566a9..5e54a86ee 100644
--- a/src/share/vm/oops/arrayOop.hpp
+++ b/src/share/vm/oops/arrayOop.hpp
@@ -22,34 +22,79 @@
*
*/
-// arrayOopDesc is the abstract baseclass for all arrays.
+// arrayOopDesc is the abstract baseclass for all arrays. It doesn't
+// declare pure virtual to enforce this because that would allocate a vtbl
+// in each instance, which we don't want.
+
+// The layout of array Oops is:
+//
+// markOop
+// klassOop // 32 bits if compressed but declared 64 in LP64.
+// length // shares klass memory or allocated after declared fields.
+
class arrayOopDesc : public oopDesc {
friend class VMStructs;
- private:
- int _length; // number of elements in the array
- public:
// Interpreter/Compiler offsets
- static int length_offset_in_bytes() { return offset_of(arrayOopDesc, _length); }
- static int base_offset_in_bytes(BasicType type) { return header_size(type) * HeapWordSize; }
+
+ // 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, except here.
+ static int header_size_in_bytes() {
+ size_t hs = UseCompressedOops ?
+ sizeof(arrayOopDesc) :
+ align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize);
+#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");
+#endif // ASSERT
+ return (int)hs;
+ }
+
+ 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 UseCompressedOops ? klass_gap_offset_in_bytes() :
+ sizeof(arrayOopDesc);
+ }
+
+ // Returns the offset of the first element.
+ static int base_offset_in_bytes(BasicType type) {
+ return header_size(type) * HeapWordSize;
+ }
// Returns the address of the first element.
- void* base(BasicType type) const { return (void*) (((intptr_t) this) + base_offset_in_bytes(type)); }
+ void* base(BasicType type) const {
+ return (void*) (((intptr_t) this) + base_offset_in_bytes(type));
+ }
// Tells whether index is within bounds.
bool is_within_bounds(int index) const { return 0 <= index && index < length(); }
- // Accessores for instance variable
- int length() const { return _length; }
- void set_length(int length) { _length = length; }
+ // Accessors for instance variable which is not a C++ declared nonstatic
+ // field.
+ int length() const {
+ return *(int*)(((intptr_t)this) + length_offset_in_bytes());
+ }
+ void set_length(int length) {
+ *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
+ }
- // Header size computation.
- // Should only be called with constants as argument (will not constant fold otherwise)
+ // 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) {
- return Universe::element_type_should_be_aligned(type)
- ? align_object_size(sizeof(arrayOopDesc)/HeapWordSize)
- : sizeof(arrayOopDesc)/HeapWordSize;
+ size_t typesize_in_bytes = header_size_in_bytes();
+ return (int)(Universe::element_type_should_be_aligned(type)
+ ? align_object_size(typesize_in_bytes/HeapWordSize)
+ : typesize_in_bytes/HeapWordSize);
}
// This method returns the maximum length that can passed into
@@ -62,7 +107,7 @@ class arrayOopDesc : public oopDesc {
// We use max_jint, since object_size is internally represented by an 'int'
// This gives us an upper bound of max_jint words for the size of the oop.
int32_t max_words = (max_jint - header_size(type) - 2);
- int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type);
+ int elembytes = type2aelembytes(type);
jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
return (len > max_jint) ? max_jint : (int32_t)len;
}