20 * CA 95054 USA or visit www.sun.com if you need additional information or |
20 * CA 95054 USA or visit www.sun.com if you need additional information or |
21 * have any questions. |
21 * have any questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 // arrayOopDesc is the abstract baseclass for all arrays. |
25 // arrayOopDesc is the abstract baseclass for all arrays. It doesn't |
|
26 // declare pure virtual to enforce this because that would allocate a vtbl |
|
27 // in each instance, which we don't want. |
|
28 |
|
29 // The layout of array Oops is: |
|
30 // |
|
31 // markOop |
|
32 // klassOop // 32 bits if compressed but declared 64 in LP64. |
|
33 // length // shares klass memory or allocated after declared fields. |
|
34 |
26 |
35 |
27 class arrayOopDesc : public oopDesc { |
36 class arrayOopDesc : public oopDesc { |
28 friend class VMStructs; |
37 friend class VMStructs; |
29 private: |
38 |
30 int _length; // number of elements in the array |
39 // Interpreter/Compiler offsets |
|
40 |
|
41 // Header size computation. |
|
42 // The header is considered the oop part of this type plus the length. |
|
43 // Returns the aligned header_size_in_bytes. This is not equivalent to |
|
44 // sizeof(arrayOopDesc) which should not appear in the code, except here. |
|
45 static int header_size_in_bytes() { |
|
46 size_t hs = UseCompressedOops ? |
|
47 sizeof(arrayOopDesc) : |
|
48 align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize); |
|
49 #ifdef ASSERT |
|
50 // make sure it isn't called before UseCompressedOops is initialized. |
|
51 static size_t arrayoopdesc_hs = 0; |
|
52 if (arrayoopdesc_hs == 0) arrayoopdesc_hs = hs; |
|
53 assert(arrayoopdesc_hs == hs, "header size can't change"); |
|
54 #endif // ASSERT |
|
55 return (int)hs; |
|
56 } |
31 |
57 |
32 public: |
58 public: |
33 // Interpreter/Compiler offsets |
59 // The _length field is not declared in C++. It is allocated after the |
34 static int length_offset_in_bytes() { return offset_of(arrayOopDesc, _length); } |
60 // declared nonstatic fields in arrayOopDesc if not compressed, otherwise |
35 static int base_offset_in_bytes(BasicType type) { return header_size(type) * HeapWordSize; } |
61 // it occupies the second half of the _klass field in oopDesc. |
|
62 static int length_offset_in_bytes() { |
|
63 return UseCompressedOops ? klass_gap_offset_in_bytes() : |
|
64 sizeof(arrayOopDesc); |
|
65 } |
|
66 |
|
67 // Returns the offset of the first element. |
|
68 static int base_offset_in_bytes(BasicType type) { |
|
69 return header_size(type) * HeapWordSize; |
|
70 } |
36 |
71 |
37 // Returns the address of the first element. |
72 // Returns the address of the first element. |
38 void* base(BasicType type) const { return (void*) (((intptr_t) this) + base_offset_in_bytes(type)); } |
73 void* base(BasicType type) const { |
|
74 return (void*) (((intptr_t) this) + base_offset_in_bytes(type)); |
|
75 } |
39 |
76 |
40 // Tells whether index is within bounds. |
77 // Tells whether index is within bounds. |
41 bool is_within_bounds(int index) const { return 0 <= index && index < length(); } |
78 bool is_within_bounds(int index) const { return 0 <= index && index < length(); } |
42 |
79 |
43 // Accessores for instance variable |
80 // Accessors for instance variable which is not a C++ declared nonstatic |
44 int length() const { return _length; } |
81 // field. |
45 void set_length(int length) { _length = length; } |
82 int length() const { |
|
83 return *(int*)(((intptr_t)this) + length_offset_in_bytes()); |
|
84 } |
|
85 void set_length(int length) { |
|
86 *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length; |
|
87 } |
46 |
88 |
47 // Header size computation. |
89 // Should only be called with constants as argument |
48 // Should only be called with constants as argument (will not constant fold otherwise) |
90 // (will not constant fold otherwise) |
|
91 // Returns the header size in words aligned to the requirements of the |
|
92 // array object type. |
49 static int header_size(BasicType type) { |
93 static int header_size(BasicType type) { |
50 return Universe::element_type_should_be_aligned(type) |
94 size_t typesize_in_bytes = header_size_in_bytes(); |
51 ? align_object_size(sizeof(arrayOopDesc)/HeapWordSize) |
95 return (int)(Universe::element_type_should_be_aligned(type) |
52 : sizeof(arrayOopDesc)/HeapWordSize; |
96 ? align_object_size(typesize_in_bytes/HeapWordSize) |
|
97 : typesize_in_bytes/HeapWordSize); |
53 } |
98 } |
54 |
99 |
55 // This method returns the maximum length that can passed into |
100 // This method returns the maximum length that can passed into |
56 // typeArrayOop::object_size(scale, length, header_size) without causing an |
101 // typeArrayOop::object_size(scale, length, header_size) without causing an |
57 // overflow. We substract an extra 2*wordSize to guard against double word |
102 // overflow. We substract an extra 2*wordSize to guard against double word |
60 assert(type >= 0 && type < T_CONFLICT, "wrong type"); |
105 assert(type >= 0 && type < T_CONFLICT, "wrong type"); |
61 assert(type2aelembytes(type) != 0, "wrong type"); |
106 assert(type2aelembytes(type) != 0, "wrong type"); |
62 // We use max_jint, since object_size is internally represented by an 'int' |
107 // We use max_jint, since object_size is internally represented by an 'int' |
63 // This gives us an upper bound of max_jint words for the size of the oop. |
108 // This gives us an upper bound of max_jint words for the size of the oop. |
64 int32_t max_words = (max_jint - header_size(type) - 2); |
109 int32_t max_words = (max_jint - header_size(type) - 2); |
65 int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type); |
110 int elembytes = type2aelembytes(type); |
66 jlong len = ((jlong)max_words * HeapWordSize) / elembytes; |
111 jlong len = ((jlong)max_words * HeapWordSize) / elembytes; |
67 return (len > max_jint) ? max_jint : (int32_t)len; |
112 return (len > max_jint) ? max_jint : (int32_t)len; |
68 } |
113 } |
69 |
114 |
70 }; |
115 }; |