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_VM_OOPS_VALUEKLASS_HPP
26 #define SHARE_VM_OOPS_VALUEKLASS_HPP
27
28 #include "classfile/javaClasses.hpp"
29 #include "oops/instanceKlass.hpp"
30 #include "oops/method.hpp"
31 #include "oops/oop.inline.hpp"
32
33 // A ValueKlass is a specialized InstanceKlass for value types.
34
35
36 class ValueKlass: public InstanceKlass {
37 friend class VMStructs;
38 friend class InstanceKlass;
39
40 private:
41
42 // Constructor
43 ValueKlass(const ClassFileParser& parser)
44 : InstanceKlass(parser, InstanceKlass::_misc_kind_value_type, InstanceKlass::ID) {
45 _adr_valueklass_fixed_block = valueklass_static_block();
46 // Addresses used for value type calling convention
47 *((Array<SigEntry>**)adr_extended_sig()) = NULL;
48 *((Array<VMRegPair>**)adr_return_regs()) = NULL;
49 *((address*)adr_pack_handler()) = NULL;
50 *((address*)adr_unpack_handler()) = NULL;
51 assert(pack_handler() == NULL, "pack handler not null");
52 *((int*)adr_default_value_offset()) = 0;
53 *((Klass**)adr_value_array_klass()) = NULL;
54 set_prototype_header(markWord::always_locked_prototype());
55 }
56
57 ValueKlassFixedBlock* valueklass_static_block() const {
58 address adr_jf = adr_value_fields_klasses();
59 if (adr_jf != NULL) {
60 return (ValueKlassFixedBlock*)(adr_jf + this->java_fields_count() * sizeof(Klass*));
61 }
62
63 address adr_fing = adr_fingerprint();
64 if (adr_fing != NULL) {
65 return (ValueKlassFixedBlock*)(adr_fingerprint() + sizeof(u8));
66 }
67
68 InstanceKlass** adr_host = adr_unsafe_anonymous_host();
69 if (adr_host != NULL) {
70 return (ValueKlassFixedBlock*)(adr_host + 1);
71 }
72
73 Klass* volatile* adr_impl = adr_implementor();
74 if (adr_impl != NULL) {
75 return (ValueKlassFixedBlock*)(adr_impl + 1);
136
137 public:
138 int get_alignment() const {
139 return *(int*)adr_alignment();
140 }
141
142 void set_alignment(int alignment) {
143 *(int*)adr_alignment() = alignment;
144 }
145
146 int first_field_offset() const {
147 int offset = *(int*)adr_first_field_offset();
148 assert(offset != 0, "Must be initialized before use");
149 return *(int*)adr_first_field_offset();
150 }
151
152 void set_first_field_offset(int offset) {
153 *(int*)adr_first_field_offset() = offset;
154 }
155
156 int get_exact_size_in_bytes() {
157 return *(int*)adr_exact_size_in_bytes();
158 }
159
160 void set_exact_size_in_bytes(int exact_size) {
161 *(int*)adr_exact_size_in_bytes() = exact_size;
162 }
163
164 int first_field_offset_old();
165
166 private:
167 int collect_fields(GrowableArray<SigEntry>* sig, int base_off = 0);
168
169 void cleanup_blobs();
170
171
172 protected:
173 // Returns the array class for the n'th dimension
174 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS);
175
176 // Returns the array class with this class as element type
177 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, TRAPS);
178
179 // Specifically flat array klass
180 Klass* value_array_klass(ArrayStorageProperties storage_props, bool or_null, int rank, TRAPS);
181
182 public:
183 // Type testing
184 bool is_value_slow() const { return true; }
185
186 // value_mirror is the primary mirror
187 oop value_mirror() const { return java_lang_Class::inline_type_mirror(java_mirror()); }
188 oop indirect_mirror() const { return java_lang_Class::indirect_type_mirror(java_mirror()); }
189
190 // Casting from Klass*
191 static ValueKlass* cast(Klass* k) {
192 assert(k->is_value(), "cast to ValueKlass");
193 return (ValueKlass*) k;
194 }
195
196 // Use this to return the size of an instance in heap words
197 // Implementation is currently simple because all value types are allocated
198 // in Java heap like Java objects.
199 virtual int size_helper() const {
200 return layout_helper_to_size_helper(layout_helper());
201 }
202
203 // Metadata iterators
204 void array_klasses_do(void f(Klass* k));
205
206 // allocate_instance() allocates a stand alone value in the Java heap
207 instanceOop allocate_instance(TRAPS);
208
209 // minimum number of bytes occupied by nonstatic fields, HeapWord aligned or pow2
210 int raw_value_byte_size();
211
212 address data_for_oop(oop o) const {
213 return ((address) (void*) o) + first_field_offset();
214 }
215
216 oop oop_for_data(address data) const {
217 oop o = (oop) (data - first_field_offset());
218 assert(oopDesc::is_oop(o, false), "Not an oop");
219 return o;
220 }
221
222 // Query if h/w provides atomic load/store
223 bool is_atomic();
224
225 bool flatten_array();
226
227 bool contains_oops() const { return nonstatic_oop_map_count() > 0; }
228 int nonstatic_oop_count();
229
230 // Prototype general store methods...
231
232 // copy the fields, with no concern for GC barriers
233 void raw_field_copy(void* src, void* dst, size_t raw_byte_size);
234
235 void value_store(void* src, void* dst, bool dst_is_heap, bool dst_uninitialized) {
236 value_store(src, dst, nonstatic_field_size() << LogBytesPerHeapOop, dst_is_heap, dst_uninitialized);
237 }
238
239 // store the value of this klass contained with src into dst, raw data ptr
240 void value_store(void* src, void* dst, size_t raw_byte_size, bool dst_is_heap, bool dst_uninitialized);
241
242 // oop iterate raw value type data pointer (where oop_addr may not be an oop, but backing/array-element)
243 template <typename T, class OopClosureType>
244 inline void oop_iterate_specialized(const address oop_addr, OopClosureType* closure);
245
246 template <typename T, class OopClosureType>
247 inline void oop_iterate_specialized_bounded(const address oop_addr, OopClosureType* closure, void* lo, void* hi);
248
249 // calling convention support
250 void initialize_calling_convention(TRAPS);
251 Array<SigEntry>* extended_sig() const {
252 return *((Array<SigEntry>**)adr_extended_sig());
253 }
254 Array<VMRegPair>* return_regs() const {
255 return *((Array<VMRegPair>**)adr_return_regs());
256 }
257 bool is_scalarizable() const;
258 bool can_be_returned_as_fields() const;
259 void save_oop_fields(const RegisterMap& map, GrowableArray<Handle>& handles) const;
260 void restore_oop_results(RegisterMap& map, GrowableArray<Handle>& handles) const;
281
282 static ByteSize default_value_offset_offset() {
283 return byte_offset_of(ValueKlassFixedBlock, _default_value_offset);
284 }
285
286 void set_default_value_offset(int offset) {
287 *((int*)adr_default_value_offset()) = offset;
288 }
289
290 int default_value_offset() {
291 int offset = *((int*)adr_default_value_offset());
292 assert(offset != 0, "must not be called if not initialized");
293 return offset;
294 }
295
296 void set_default_value(oop val) {
297 java_mirror()->obj_field_put(default_value_offset(), val);
298 indirect_mirror()->obj_field_put(default_value_offset(), val);
299 }
300
301 oop default_value() {
302 oop val = java_mirror()->obj_field_acquire(default_value_offset());
303 assert(oopDesc::is_oop(val), "Sanity check");
304 assert(val->is_value(), "Sanity check");
305 assert(val->klass() == this, "sanity check");
306 return val;
307 }
308
309 void deallocate_contents(ClassLoaderData* loader_data);
310 static void cleanup(ValueKlass* ik) ;
311
312 // Verification
313 void verify_on(outputStream* st);
314 void oop_verify_on(oop obj, outputStream* st);
315
316 };
317
318 #endif /* SHARE_VM_OOPS_VALUEKLASS_HPP */
|
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_VM_OOPS_VALUEKLASS_HPP
26 #define SHARE_VM_OOPS_VALUEKLASS_HPP
27
28 #include "classfile/javaClasses.hpp"
29 #include "oops/instanceKlass.hpp"
30 #include "oops/method.hpp"
31 //#include "oops/oop.inline.hpp"
32
33 // A ValueKlass is a specialized InstanceKlass for value types.
34
35
36 class ValueKlass: public InstanceKlass {
37 friend class VMStructs;
38 friend class InstanceKlass;
39
40 private:
41
42 // Constructor
43 ValueKlass(const ClassFileParser& parser);
44
45 ValueKlassFixedBlock* valueklass_static_block() const {
46 address adr_jf = adr_value_fields_klasses();
47 if (adr_jf != NULL) {
48 return (ValueKlassFixedBlock*)(adr_jf + this->java_fields_count() * sizeof(Klass*));
49 }
50
51 address adr_fing = adr_fingerprint();
52 if (adr_fing != NULL) {
53 return (ValueKlassFixedBlock*)(adr_fingerprint() + sizeof(u8));
54 }
55
56 InstanceKlass** adr_host = adr_unsafe_anonymous_host();
57 if (adr_host != NULL) {
58 return (ValueKlassFixedBlock*)(adr_host + 1);
59 }
60
61 Klass* volatile* adr_impl = adr_implementor();
62 if (adr_impl != NULL) {
63 return (ValueKlassFixedBlock*)(adr_impl + 1);
124
125 public:
126 int get_alignment() const {
127 return *(int*)adr_alignment();
128 }
129
130 void set_alignment(int alignment) {
131 *(int*)adr_alignment() = alignment;
132 }
133
134 int first_field_offset() const {
135 int offset = *(int*)adr_first_field_offset();
136 assert(offset != 0, "Must be initialized before use");
137 return *(int*)adr_first_field_offset();
138 }
139
140 void set_first_field_offset(int offset) {
141 *(int*)adr_first_field_offset() = offset;
142 }
143
144 int get_exact_size_in_bytes() const {
145 return *(int*)adr_exact_size_in_bytes();
146 }
147
148 void set_exact_size_in_bytes(int exact_size) {
149 *(int*)adr_exact_size_in_bytes() = exact_size;
150 }
151
152 int first_field_offset_old();
153
154 private:
155 int collect_fields(GrowableArray<SigEntry>* sig, int base_off = 0);
156
157 void cleanup_blobs();
158
159
160 protected:
161 // Returns the array class for the n'th dimension
162 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS);
163
164 // Returns the array class with this class as element type
165 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, TRAPS);
166
167 // Specifically flat array klass
168 Klass* value_array_klass(ArrayStorageProperties storage_props, bool or_null, int rank, TRAPS);
169
170 public:
171 // Type testing
172 bool is_value_slow() const { return true; }
173
174 // value_mirror is the primary mirror
175 oop value_mirror() const { return java_lang_Class::inline_type_mirror(java_mirror()); }
176 oop indirect_mirror() const { return java_lang_Class::indirect_type_mirror(java_mirror()); }
177
178 // Casting from Klass*
179 static ValueKlass* cast(Klass* k);
180
181 // Use this to return the size of an instance in heap words
182 // Implementation is currently simple because all value types are allocated
183 // in Java heap like Java objects.
184 virtual int size_helper() const {
185 return layout_helper_to_size_helper(layout_helper());
186 }
187
188 // Metadata iterators
189 void array_klasses_do(void f(Klass* k));
190
191 // allocate_instance() allocates a stand alone value in the Java heap
192 instanceOop allocate_instance(TRAPS);
193
194 // minimum number of bytes occupied by nonstatic fields, HeapWord aligned or pow2
195 int raw_value_byte_size();
196
197 address data_for_oop(oop o) const;
198 oop oop_for_data(address data) const;
199
200 // Query if h/w provides atomic load/store
201 bool is_atomic();
202
203 bool flatten_array();
204
205 bool contains_oops() const { return nonstatic_oop_map_count() > 0; }
206 int nonstatic_oop_count();
207
208 // General store methods
209 //
210 // Normally loads and store methods would be found in *Oops classes, but since values can be
211 // "in-lined" (flattened) into containing oops, these methods reside here in ValueKlass.
212 //
213 // "value_copy_*_to_new_*" assume new memory (i.e. IS_DEST_UNINITIALIZED for write barriers)
214
215 void value_copy_payload_to_new_oop(void* src, oop dst);
216 void value_copy_oop_to_new_oop(oop src, oop dst);
217 void value_copy_oop_to_new_payload(oop src, void* dst);
218
219 void value_copy_oop_to_payload(oop src, void* dst);
220
221 // oop iterate raw value type data pointer (where oop_addr may not be an oop, but backing/array-element)
222 template <typename T, class OopClosureType>
223 inline void oop_iterate_specialized(const address oop_addr, OopClosureType* closure);
224
225 template <typename T, class OopClosureType>
226 inline void oop_iterate_specialized_bounded(const address oop_addr, OopClosureType* closure, void* lo, void* hi);
227
228 // calling convention support
229 void initialize_calling_convention(TRAPS);
230 Array<SigEntry>* extended_sig() const {
231 return *((Array<SigEntry>**)adr_extended_sig());
232 }
233 Array<VMRegPair>* return_regs() const {
234 return *((Array<VMRegPair>**)adr_return_regs());
235 }
236 bool is_scalarizable() const;
237 bool can_be_returned_as_fields() const;
238 void save_oop_fields(const RegisterMap& map, GrowableArray<Handle>& handles) const;
239 void restore_oop_results(RegisterMap& map, GrowableArray<Handle>& handles) const;
260
261 static ByteSize default_value_offset_offset() {
262 return byte_offset_of(ValueKlassFixedBlock, _default_value_offset);
263 }
264
265 void set_default_value_offset(int offset) {
266 *((int*)adr_default_value_offset()) = offset;
267 }
268
269 int default_value_offset() {
270 int offset = *((int*)adr_default_value_offset());
271 assert(offset != 0, "must not be called if not initialized");
272 return offset;
273 }
274
275 void set_default_value(oop val) {
276 java_mirror()->obj_field_put(default_value_offset(), val);
277 indirect_mirror()->obj_field_put(default_value_offset(), val);
278 }
279
280 oop default_value();
281 void deallocate_contents(ClassLoaderData* loader_data);
282 static void cleanup(ValueKlass* ik) ;
283
284 // Verification
285 void verify_on(outputStream* st);
286 void oop_verify_on(oop obj, outputStream* st);
287
288 };
289
290 #endif /* SHARE_VM_OOPS_VALUEKLASS_HPP */
|