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 #include "precompiled.hpp"
26 #include "gc/shared/gcLocker.inline.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "oops/oop.inline.hpp"
29 #include "oops/fieldStreams.hpp"
30 #include "oops/method.hpp"
31 #include "oops/objArrayKlass.hpp"
32 #include "oops/valueKlass.hpp"
33 #include "oops/valueArrayKlass.hpp"
34 #include "runtime/signature.hpp"
35 #include "utilities/copy.hpp"
36
37 int ValueKlass::first_field_offset() const {
38 #ifdef ASSERT
39 int first_offset = INT_MAX;
40 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
41 if (fs.offset() < first_offset) first_offset= fs.offset();
42 }
43 #endif
44 int base_offset = instanceOopDesc::base_offset_in_bytes();
45 // The first field of value types is aligned on a long boundary
46 base_offset = align_size_up(base_offset, BytesPerLong);
47 assert(base_offset == first_offset, "inconsistent offsets");
69 if (fs.offset() > last_offset) {
70 BasicType type = fs.field_descriptor().field_type();
71 if (is_java_primitive(type)) {
72 last_tsz = type2aelembytes(type);
73 } else if (type == T_VALUETYPE) {
74 // Not just primitives. Layout aligns embedded value, so use jlong aligned it is
75 return heapOopAlignedSize;
76 } else {
77 guarantee(0, "Unknown type %d", type);
78 }
79 assert(last_tsz != 0, "Invariant");
80 last_offset = fs.offset();
81 }
82 }
83 // Assumes VT with no fields are meaningless and illegal
84 last_offset += last_tsz;
85 assert(last_offset > first_offset && last_tsz, "Invariant");
86 return 1 << upper_log2(last_offset - first_offset);
87 }
88
89 bool ValueKlass::is_atomic() {
90 return (nonstatic_field_size() * heapOopSize) <= longSize;
91 }
92
93 int ValueKlass::nonstatic_oop_count() {
94 int oops = 0;
95 int map_count = nonstatic_oop_map_count();
96 OopMapBlock* block = start_of_nonstatic_oop_maps();
97 OopMapBlock* end = block + map_count;
98 while (block != end) {
99 oops += block->count();
100 block++;
101 }
102 return oops;
103 }
104
105 // Arrays of...
106
107 bool ValueKlass::flatten_array() {
108 if (!ValueArrayFlatten) {
218 } else {
219 oopDesc::bs()->write_ref_array_pre((oop*) doop_address, map->count(), dst_uninitialized);
220 }
221 map++;
222 }
223
224 raw_field_copy(src, dst, raw_byte_size);
225
226 // Post-barriers...
227 map = start_of_nonstatic_oop_maps();
228 while (map != end) {
229 address doop_address = dst_oop_addr + map->offset();
230 oopDesc::bs()->write_ref_array((HeapWord*) doop_address, map->count());
231 map++;
232 }
233 } else { // Primitive-only case...
234 raw_field_copy(src, dst, raw_byte_size);
235 }
236 }
237
238 oop ValueKlass::derive_value_type_copy(Handle src, InstanceKlass* target_klass, TRAPS) {
239 assert(EnableMVT, "Only supported with the MVT programming model");
240 // assert(InstanceKlass::cast(src->klass())->derive_value_type_klass() == target_klass, "Not this DVT");
241 #ifdef ASSERT
242 if (InstanceKlass::cast(src->klass())->has_vcc_klass()) {
243 assert(InstanceKlass::cast(src->klass())->get_vcc_klass() == target_klass,
244 "VCC/DVT mismatch");
245 } else {
246 assert(target_klass->has_vcc_klass(), "Sanity check");
247 assert(target_klass->get_vcc_klass() == InstanceKlass::cast(src->klass()),
248 "VCC/DVT mismatch");
249 }
250 #endif // ASSERT
251
252 // Allocate new for safety, simply reinstalling the klass pointer is a little too risky
253 target_klass->initialize(CHECK_0);
254 instanceOop value = target_klass->allocate_instance(CHECK_0);
255 value_store(data_for_oop(src()), data_for_oop(value), true, true);
256 return value;
257 }
258
259 // Value type arguments are not passed by reference, instead each
260 // field of the value type is passed as an argument. This helper
261 // function collects the fields of the value types (including embedded
262 // value type's fields) in a list. Included with the field's type is
263 // the offset of each field in the value type: i2c and c2i adapters
264 // need that to load or store fields. Finally, the list of fields is
265 // sorted in order of increasing offsets: the adapters and the
266 // compiled code need and agreed upon order of fields.
267 //
268 // The list of basic types that is returned starts with a T_VALUETYPE
269 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as
270 // delimiters. Every entry between the two is a field of the value
271 // type. If there's an embedded value type in the list, it also starts
272 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
273 // generate a unique fingerprint for the method's adapters and we can
274 // generate the list of basic types from the interpreter point of view
275 // (value types passed as reference: iterate on the list until a
494 break;
495 }
496 default:
497 ShouldNotReachHere();
498 }
499 j++;
500 }
501 assert(j == nb_fields, "missed a field?");
502 assert(k == handles.length(), "missed an oop?");
503 return new_vt;
504 }
505
506 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
507 BasicType bt = T_METADATA;
508 VMRegPair pair;
509 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
510 assert(nb == 1, "broken");
511
512 address loc = map.location(pair.first());
513 intptr_t ptr = *(intptr_t*)loc;
514 if (Universe::heap()->is_in_reserved((void*)ptr)) {
515 return NULL;
516 }
517 return (ValueKlass*)ptr;
518 }
|
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 #include "precompiled.hpp"
26 #include "gc/shared/gcLocker.inline.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "logging/log.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "oops/fieldStreams.hpp"
31 #include "oops/method.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/valueKlass.hpp"
34 #include "oops/valueArrayKlass.hpp"
35 #include "runtime/signature.hpp"
36 #include "utilities/copy.hpp"
37
38 int ValueKlass::first_field_offset() const {
39 #ifdef ASSERT
40 int first_offset = INT_MAX;
41 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
42 if (fs.offset() < first_offset) first_offset= fs.offset();
43 }
44 #endif
45 int base_offset = instanceOopDesc::base_offset_in_bytes();
46 // The first field of value types is aligned on a long boundary
47 base_offset = align_size_up(base_offset, BytesPerLong);
48 assert(base_offset == first_offset, "inconsistent offsets");
70 if (fs.offset() > last_offset) {
71 BasicType type = fs.field_descriptor().field_type();
72 if (is_java_primitive(type)) {
73 last_tsz = type2aelembytes(type);
74 } else if (type == T_VALUETYPE) {
75 // Not just primitives. Layout aligns embedded value, so use jlong aligned it is
76 return heapOopAlignedSize;
77 } else {
78 guarantee(0, "Unknown type %d", type);
79 }
80 assert(last_tsz != 0, "Invariant");
81 last_offset = fs.offset();
82 }
83 }
84 // Assumes VT with no fields are meaningless and illegal
85 last_offset += last_tsz;
86 assert(last_offset > first_offset && last_tsz, "Invariant");
87 return 1 << upper_log2(last_offset - first_offset);
88 }
89
90 instanceOop ValueKlass::allocate_instance(TRAPS) {
91 int size = size_helper(); // Query before forming handle.
92
93 return (instanceOop)CollectedHeap::obj_allocate(this, size, CHECK_NULL);
94 }
95
96 instanceOop ValueKlass::allocate_buffered_or_heap_instance(bool* in_heap, TRAPS) {
97 assert(THREAD->is_Java_thread(), "Only Java threads can call this method");
98
99 instanceOop value = NULL;
100 if (is_bufferable()) {
101 value = (instanceOop)VTBuffer::allocate_value(this, CHECK_NULL);
102 *in_heap = false;
103 }
104 if (value == NULL) {
105 log_info(valuetypes)("Value buffering failed, allocating in the Java heap");
106 value = allocate_instance(CHECK_NULL);
107 *in_heap = true;
108 }
109 return value;
110 }
111
112 bool ValueKlass::is_atomic() {
113 return (nonstatic_field_size() * heapOopSize) <= longSize;
114 }
115
116 int ValueKlass::nonstatic_oop_count() {
117 int oops = 0;
118 int map_count = nonstatic_oop_map_count();
119 OopMapBlock* block = start_of_nonstatic_oop_maps();
120 OopMapBlock* end = block + map_count;
121 while (block != end) {
122 oops += block->count();
123 block++;
124 }
125 return oops;
126 }
127
128 // Arrays of...
129
130 bool ValueKlass::flatten_array() {
131 if (!ValueArrayFlatten) {
241 } else {
242 oopDesc::bs()->write_ref_array_pre((oop*) doop_address, map->count(), dst_uninitialized);
243 }
244 map++;
245 }
246
247 raw_field_copy(src, dst, raw_byte_size);
248
249 // Post-barriers...
250 map = start_of_nonstatic_oop_maps();
251 while (map != end) {
252 address doop_address = dst_oop_addr + map->offset();
253 oopDesc::bs()->write_ref_array((HeapWord*) doop_address, map->count());
254 map++;
255 }
256 } else { // Primitive-only case...
257 raw_field_copy(src, dst, raw_byte_size);
258 }
259 }
260
261 oop ValueKlass::box(Handle src, InstanceKlass* target_klass, TRAPS) {
262 assert(src()->klass()->is_value(), "src must be a value type");
263 assert(!target_klass->is_value(), "target_klass must not be a value type");
264
265 target_klass->initialize(CHECK_0);
266 instanceOop box = target_klass->allocate_instance(CHECK_0);
267 value_store(data_for_oop(src()), data_for_oop(box), true, false);
268
269 assert(!box->klass()->is_value(), "Sanity check");
270 return box;
271 }
272
273 oop ValueKlass::unbox(Handle src, InstanceKlass* target_klass, TRAPS) {
274 assert(!src()->klass()->is_value(), "src must not be a value type");
275 assert(target_klass->is_value(), "target_klass must be a value type");
276 ValueKlass* vtklass = ValueKlass::cast(target_klass);
277
278 vtklass->initialize(CHECK_0);
279 bool in_heap;
280 instanceOop value = vtklass->allocate_buffered_or_heap_instance(&in_heap, CHECK_0);
281 value_store(data_for_oop(src()), data_for_oop(value), in_heap, false);
282
283 assert(value->klass()->is_value(), "Sanity check");
284 return value;
285 }
286
287 // Value type arguments are not passed by reference, instead each
288 // field of the value type is passed as an argument. This helper
289 // function collects the fields of the value types (including embedded
290 // value type's fields) in a list. Included with the field's type is
291 // the offset of each field in the value type: i2c and c2i adapters
292 // need that to load or store fields. Finally, the list of fields is
293 // sorted in order of increasing offsets: the adapters and the
294 // compiled code need and agreed upon order of fields.
295 //
296 // The list of basic types that is returned starts with a T_VALUETYPE
297 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as
298 // delimiters. Every entry between the two is a field of the value
299 // type. If there's an embedded value type in the list, it also starts
300 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
301 // generate a unique fingerprint for the method's adapters and we can
302 // generate the list of basic types from the interpreter point of view
303 // (value types passed as reference: iterate on the list until a
522 break;
523 }
524 default:
525 ShouldNotReachHere();
526 }
527 j++;
528 }
529 assert(j == nb_fields, "missed a field?");
530 assert(k == handles.length(), "missed an oop?");
531 return new_vt;
532 }
533
534 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
535 BasicType bt = T_METADATA;
536 VMRegPair pair;
537 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
538 assert(nb == 1, "broken");
539
540 address loc = map.location(pair.first());
541 intptr_t ptr = *(intptr_t*)loc;
542 if (Metaspace::contains((void*)ptr)) {
543 return (ValueKlass*)ptr;
544 }
545 return NULL;
546 // if (Universe::heap()->is_in_reserved((void*)ptr)) {
547 // return NULL;
548 // }
549 // return (ValueKlass*)ptr;
550 }
551
|