1 | /* |
2 | * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_OOPS_ARRAYOOP_HPP |
26 | #define SHARE_OOPS_ARRAYOOP_HPP |
27 | |
28 | #include "oops/oop.hpp" |
29 | #include "utilities/align.hpp" |
30 | |
31 | // arrayOopDesc is the abstract baseclass for all arrays. It doesn't |
32 | // declare pure virtual to enforce this because that would allocate a vtbl |
33 | // in each instance, which we don't want. |
34 | |
35 | // The layout of array Oops is: |
36 | // |
37 | // markOop |
38 | // Klass* // 32 bits if compressed but declared 64 in LP64. |
39 | // length // shares klass memory or allocated after declared fields. |
40 | |
41 | |
42 | class arrayOopDesc : public oopDesc { |
43 | friend class VMStructs; |
44 | friend class arrayOopDescTest; |
45 | |
46 | // Interpreter/Compiler offsets |
47 | |
48 | // Header size computation. |
49 | // The header is considered the oop part of this type plus the length. |
50 | // Returns the aligned header_size_in_bytes. This is not equivalent to |
51 | // sizeof(arrayOopDesc) which should not appear in the code. |
52 | static int () { |
53 | size_t hs = align_up(length_offset_in_bytes() + sizeof(int), |
54 | HeapWordSize); |
55 | #ifdef ASSERT |
56 | // make sure it isn't called before UseCompressedOops is initialized. |
57 | static size_t arrayoopdesc_hs = 0; |
58 | if (arrayoopdesc_hs == 0) arrayoopdesc_hs = hs; |
59 | assert(arrayoopdesc_hs == hs, "header size can't change" ); |
60 | #endif // ASSERT |
61 | return (int)hs; |
62 | } |
63 | |
64 | // Check whether an element of a typeArrayOop with the given type must be |
65 | // aligned 0 mod 8. The typeArrayOop itself must be aligned at least this |
66 | // strongly. |
67 | static bool element_type_should_be_aligned(BasicType type) { |
68 | return type == T_DOUBLE || type == T_LONG; |
69 | } |
70 | |
71 | public: |
72 | // The _length field is not declared in C++. It is allocated after the |
73 | // declared nonstatic fields in arrayOopDesc if not compressed, otherwise |
74 | // it occupies the second half of the _klass field in oopDesc. |
75 | static int length_offset_in_bytes() { |
76 | return UseCompressedClassPointers ? klass_gap_offset_in_bytes() : |
77 | sizeof(arrayOopDesc); |
78 | } |
79 | |
80 | // Returns the offset of the first element. |
81 | static int base_offset_in_bytes(BasicType type) { |
82 | return header_size(type) * HeapWordSize; |
83 | } |
84 | |
85 | // Returns the address of the first element. The elements in the array will not |
86 | // relocate from this address until a subsequent thread transition. |
87 | inline void* base(BasicType type) const; |
88 | inline void* base_raw(BasicType type) const; // GC barrier invariant |
89 | |
90 | template <typename T> |
91 | static T* obj_offset_to_raw(arrayOop obj, size_t offset_in_bytes, T* raw) { |
92 | if (obj != NULL) { |
93 | assert(raw == NULL, "either raw or in-heap" ); |
94 | char* base = reinterpret_cast<char*>((void*) obj); |
95 | raw = reinterpret_cast<T*>(base + offset_in_bytes); |
96 | } else { |
97 | assert(raw != NULL, "either raw or in-heap" ); |
98 | } |
99 | return raw; |
100 | } |
101 | |
102 | // Tells whether index is within bounds. |
103 | bool is_within_bounds(int index) const { return 0 <= index && index < length(); } |
104 | |
105 | // Accessors for instance variable which is not a C++ declared nonstatic |
106 | // field. |
107 | int length() const { |
108 | return *(int*)(((intptr_t)this) + length_offset_in_bytes()); |
109 | } |
110 | void set_length(int length) { |
111 | set_length((HeapWord*)this, length); |
112 | } |
113 | static void set_length(HeapWord* mem, int length) { |
114 | *(int*)(((char*)mem) + length_offset_in_bytes()) = length; |
115 | } |
116 | |
117 | // Should only be called with constants as argument |
118 | // (will not constant fold otherwise) |
119 | // Returns the header size in words aligned to the requirements of the |
120 | // array object type. |
121 | static int (BasicType type) { |
122 | size_t typesize_in_bytes = header_size_in_bytes(); |
123 | return (int)(element_type_should_be_aligned(type) |
124 | ? align_object_offset(typesize_in_bytes/HeapWordSize) |
125 | : typesize_in_bytes/HeapWordSize); |
126 | } |
127 | |
128 | // Return the maximum length of an array of BasicType. The length can passed |
129 | // to typeArrayOop::object_size(scale, length, header_size) without causing an |
130 | // overflow. We also need to make sure that this will not overflow a size_t on |
131 | // 32 bit platforms when we convert it to a byte size. |
132 | static int32_t max_array_length(BasicType type) { |
133 | assert(type >= 0 && type < T_CONFLICT, "wrong type" ); |
134 | assert(type2aelembytes(type) != 0, "wrong type" ); |
135 | |
136 | const size_t max_element_words_per_size_t = |
137 | align_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment); |
138 | const size_t max_elements_per_size_t = |
139 | HeapWordSize * max_element_words_per_size_t / type2aelembytes(type); |
140 | if ((size_t)max_jint < max_elements_per_size_t) { |
141 | // It should be ok to return max_jint here, but parts of the code |
142 | // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for |
143 | // passing around the size (in words) of an object. So, we need to avoid |
144 | // overflowing an int when we add the header. See CRs 4718400 and 7110613. |
145 | return align_down(max_jint - header_size(type), MinObjAlignment); |
146 | } |
147 | return (int32_t)max_elements_per_size_t; |
148 | } |
149 | |
150 | }; |
151 | |
152 | #endif // SHARE_OOPS_ARRAYOOP_HPP |
153 | |