36 #include "oops/valueKlass.hpp"
37 #include "oops/valueArrayKlass.hpp"
38 #include "runtime/signature.hpp"
39 #include "utilities/copy.hpp"
40
41 int ValueKlass::first_field_offset() const {
42 #ifdef ASSERT
43 int first_offset = INT_MAX;
44 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
45 if (fs.offset() < first_offset) first_offset= fs.offset();
46 }
47 #endif
48 int base_offset = instanceOopDesc::base_offset_in_bytes();
49 // The first field of value types is aligned on a long boundary
50 base_offset = align_up(base_offset, BytesPerLong);
51 assert(base_offset == first_offset, "inconsistent offsets");
52 return base_offset;
53 }
54
55 int ValueKlass::raw_value_byte_size() const {
56 assert(!is__Value(), "This is not the value type klass you are looking for");
57 int heapOopAlignedSize = nonstatic_field_size() << LogBytesPerHeapOop;
58 // If bigger than 64 bits or needs oop alignment, then use jlong aligned
59 // which for values should be jlong aligned, asserts in raw_field_copy otherwise
60 if (heapOopAlignedSize >= longSize || contains_oops()) {
61 return heapOopAlignedSize;
62 }
63 // Small primitives...
64 // If a few small basic type fields, return the actual size, i.e.
65 // 1 byte = 1
66 // 2 byte = 2
67 // 3 byte = 4, because pow2 needed for element stores
68 int first_offset = first_field_offset();
69 int last_offset = 0; // find the last offset, add basic type size
70 int last_tsz = 0;
71 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
72 if (fs.offset() > last_offset) {
73 BasicType type = fs.field_descriptor().field_type();
74 if (is_java_primitive(type)) {
75 last_tsz = type2aelembytes(type);
76 } else if (type == T_VALUETYPE) {
248 map++;
249 }
250
251 raw_field_copy(src, dst, raw_byte_size);
252
253 // Post-barriers...
254 map = start_of_nonstatic_oop_maps();
255 while (map != end) {
256 address doop_address = dst_oop_addr + map->offset();
257 BarrierSet::barrier_set()->write_ref_array((HeapWord*) doop_address, map->count());
258 map++;
259 }
260 } else { // Buffered value case
261 raw_field_copy(src, dst, raw_byte_size);
262 }
263 } else { // Primitive-only case...
264 raw_field_copy(src, dst, raw_byte_size);
265 }
266 }
267
268 oop ValueKlass::box(Handle src, InstanceKlass* target_klass, TRAPS) {
269 assert(src()->klass()->is_value(), "src must be a value type");
270 assert(!target_klass->is_value(), "target_klass must not be a value type");
271
272 target_klass->initialize(CHECK_0);
273 instanceOop box = target_klass->allocate_instance(CHECK_0);
274 value_store(data_for_oop(src()), data_for_oop(box), true, false);
275
276 assert(!box->klass()->is_value(), "Sanity check");
277 return box;
278 }
279
280 oop ValueKlass::unbox(Handle src, InstanceKlass* target_klass, TRAPS) {
281 assert(!src()->klass()->is_value(), "src must not be a value type");
282 assert(target_klass->is_value(), "target_klass must be a value type");
283 ValueKlass* vtklass = ValueKlass::cast(target_klass);
284
285 vtklass->initialize(CHECK_0);
286 bool in_heap;
287 instanceOop value = vtklass->allocate_buffered_or_heap_instance(&in_heap, CHECK_0);
288 value_store(data_for_oop(src()), data_for_oop(value), in_heap, false);
289
290 assert(value->klass()->is_value(), "Sanity check");
291 return value;
292 }
293
294 // Value type arguments are not passed by reference, instead each
295 // field of the value type is passed as an argument. This helper
296 // function collects the fields of the value types (including embedded
297 // value type's fields) in a list. Included with the field's type is
298 // the offset of each field in the value type: i2c and c2i adapters
299 // need that to load or store fields. Finally, the list of fields is
300 // sorted in order of increasing offsets: the adapters and the
301 // compiled code need and agreed upon order of fields.
302 //
303 // The list of basic types that is returned starts with a T_VALUETYPE
304 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as
305 // delimiters. Every entry between the two is a field of the value
306 // type. If there's an embedded value type in the list, it also starts
307 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
308 // generate a unique fingerprint for the method's adapters and we can
309 // generate the list of basic types from the interpreter point of view
310 // (value types passed as reference: iterate on the list until a
311 // T_VALUETYPE, drop everything until and including the closing
312 // T_VOID) or the compiler point of view (each field of the value
313 // types is an argument: drop all T_VALUETYPE/T_VOID from the list).
340 } else {
341 sig_extended.push(SigEntry(bt, offset));
342 if (bt == T_LONG || bt == T_DOUBLE) {
343 sig_extended.push(SigEntry(T_VOID, offset));
344 }
345 }
346 }
347 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
348 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields
349 if (base_off == 0) {
350 sig_extended.sort(SigEntry::compare);
351 }
352 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure");
353 return sig_extended;
354 }
355
356 void ValueKlass::initialize_calling_convention() {
357 // Because the pack and unpack handler addresses need to be loadable from generated code,
358 // they are stored at a fixed offset in the klass metadata. Since value type klasses do
359 // not have a vtable, the vtable offset is used to store these addresses.
360 guarantee(vtable_length() == 0, "vtables are not supported in value klasses");
361 if (ValueTypeReturnedAsFields || ValueTypePassFieldsAsArgs) {
362 Thread* THREAD = Thread::current();
363 assert(!HAS_PENDING_EXCEPTION, "should have no exception");
364 ResourceMark rm;
365 const GrowableArray<SigEntry>& sig_vk = collect_fields();
366 int nb_fields = SigEntry::count_fields(sig_vk)+1;
367 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
368 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
369 for (int i = 0; i < sig_vk.length(); i++) {
370 extended_sig->at_put(i, sig_vk.at(i));
371 }
372
373 if (ValueTypeReturnedAsFields) {
374 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
375 sig_bt[0] = T_METADATA;
376 SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
377 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
378 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
379
380 if (total > 0) {
403 cleanup_blobs();
404 InstanceKlass::deallocate_contents(loader_data);
405 }
406
407 void ValueKlass::cleanup(ValueKlass* ik) {
408 ik->cleanup_blobs();
409 }
410
411 void ValueKlass::cleanup_blobs() {
412 if (pack_handler() != NULL) {
413 CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
414 assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
415 BufferBlob::free((BufferBlob*)buffered_blob);
416 *((address*)adr_pack_handler()) = NULL;
417 *((address*)adr_unpack_handler()) = NULL;
418 }
419 }
420
421 // Can this value type be returned as multiple values?
422 bool ValueKlass::can_be_returned_as_fields() const {
423 return !is__Value() && (return_regs() != NULL);
424 }
425
426 // Create handles for all oop fields returned in registers that are going to be live across a safepoint
427 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
428 Thread* thread = Thread::current();
429 const Array<SigEntry>* sig_vk = extended_sig();
430 const Array<VMRegPair>* regs = return_regs();
431 int j = 1;
432
433 for (int i = 0; i < sig_vk->length(); i++) {
434 BasicType bt = sig_vk->at(i)._bt;
435 if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) {
436 int off = sig_vk->at(i)._offset;
437 VMRegPair pair = regs->at(j);
438 address loc = reg_map.location(pair.first());
439 oop v = *(oop*)loc;
440 assert(v == NULL || oopDesc::is_oop(v), "not an oop?");
441 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer");
442 handles.push(Handle(thread, v));
443 }
|
36 #include "oops/valueKlass.hpp"
37 #include "oops/valueArrayKlass.hpp"
38 #include "runtime/signature.hpp"
39 #include "utilities/copy.hpp"
40
41 int ValueKlass::first_field_offset() const {
42 #ifdef ASSERT
43 int first_offset = INT_MAX;
44 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
45 if (fs.offset() < first_offset) first_offset= fs.offset();
46 }
47 #endif
48 int base_offset = instanceOopDesc::base_offset_in_bytes();
49 // The first field of value types is aligned on a long boundary
50 base_offset = align_up(base_offset, BytesPerLong);
51 assert(base_offset == first_offset, "inconsistent offsets");
52 return base_offset;
53 }
54
55 int ValueKlass::raw_value_byte_size() const {
56 int heapOopAlignedSize = nonstatic_field_size() << LogBytesPerHeapOop;
57 // If bigger than 64 bits or needs oop alignment, then use jlong aligned
58 // which for values should be jlong aligned, asserts in raw_field_copy otherwise
59 if (heapOopAlignedSize >= longSize || contains_oops()) {
60 return heapOopAlignedSize;
61 }
62 // Small primitives...
63 // If a few small basic type fields, return the actual size, i.e.
64 // 1 byte = 1
65 // 2 byte = 2
66 // 3 byte = 4, because pow2 needed for element stores
67 int first_offset = first_field_offset();
68 int last_offset = 0; // find the last offset, add basic type size
69 int last_tsz = 0;
70 for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
71 if (fs.offset() > last_offset) {
72 BasicType type = fs.field_descriptor().field_type();
73 if (is_java_primitive(type)) {
74 last_tsz = type2aelembytes(type);
75 } else if (type == T_VALUETYPE) {
247 map++;
248 }
249
250 raw_field_copy(src, dst, raw_byte_size);
251
252 // Post-barriers...
253 map = start_of_nonstatic_oop_maps();
254 while (map != end) {
255 address doop_address = dst_oop_addr + map->offset();
256 BarrierSet::barrier_set()->write_ref_array((HeapWord*) doop_address, map->count());
257 map++;
258 }
259 } else { // Buffered value case
260 raw_field_copy(src, dst, raw_byte_size);
261 }
262 } else { // Primitive-only case...
263 raw_field_copy(src, dst, raw_byte_size);
264 }
265 }
266
267 // Value type arguments are not passed by reference, instead each
268 // field of the value type is passed as an argument. This helper
269 // function collects the fields of the value types (including embedded
270 // value type's fields) in a list. Included with the field's type is
271 // the offset of each field in the value type: i2c and c2i adapters
272 // need that to load or store fields. Finally, the list of fields is
273 // sorted in order of increasing offsets: the adapters and the
274 // compiled code need and agreed upon order of fields.
275 //
276 // The list of basic types that is returned starts with a T_VALUETYPE
277 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as
278 // delimiters. Every entry between the two is a field of the value
279 // type. If there's an embedded value type in the list, it also starts
280 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
281 // generate a unique fingerprint for the method's adapters and we can
282 // generate the list of basic types from the interpreter point of view
283 // (value types passed as reference: iterate on the list until a
284 // T_VALUETYPE, drop everything until and including the closing
285 // T_VOID) or the compiler point of view (each field of the value
286 // types is an argument: drop all T_VALUETYPE/T_VOID from the list).
313 } else {
314 sig_extended.push(SigEntry(bt, offset));
315 if (bt == T_LONG || bt == T_DOUBLE) {
316 sig_extended.push(SigEntry(T_VOID, offset));
317 }
318 }
319 }
320 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
321 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields
322 if (base_off == 0) {
323 sig_extended.sort(SigEntry::compare);
324 }
325 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure");
326 return sig_extended;
327 }
328
329 void ValueKlass::initialize_calling_convention() {
330 // Because the pack and unpack handler addresses need to be loadable from generated code,
331 // they are stored at a fixed offset in the klass metadata. Since value type klasses do
332 // not have a vtable, the vtable offset is used to store these addresses.
333 //guarantee(vtable_length() == 0, "vtables are not supported in value klasses");
334 if (ValueTypeReturnedAsFields || ValueTypePassFieldsAsArgs) {
335 Thread* THREAD = Thread::current();
336 assert(!HAS_PENDING_EXCEPTION, "should have no exception");
337 ResourceMark rm;
338 const GrowableArray<SigEntry>& sig_vk = collect_fields();
339 int nb_fields = SigEntry::count_fields(sig_vk)+1;
340 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
341 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
342 for (int i = 0; i < sig_vk.length(); i++) {
343 extended_sig->at_put(i, sig_vk.at(i));
344 }
345
346 if (ValueTypeReturnedAsFields) {
347 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
348 sig_bt[0] = T_METADATA;
349 SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
350 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
351 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
352
353 if (total > 0) {
376 cleanup_blobs();
377 InstanceKlass::deallocate_contents(loader_data);
378 }
379
380 void ValueKlass::cleanup(ValueKlass* ik) {
381 ik->cleanup_blobs();
382 }
383
384 void ValueKlass::cleanup_blobs() {
385 if (pack_handler() != NULL) {
386 CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
387 assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
388 BufferBlob::free((BufferBlob*)buffered_blob);
389 *((address*)adr_pack_handler()) = NULL;
390 *((address*)adr_unpack_handler()) = NULL;
391 }
392 }
393
394 // Can this value type be returned as multiple values?
395 bool ValueKlass::can_be_returned_as_fields() const {
396 return return_regs() != NULL;
397 }
398
399 // Create handles for all oop fields returned in registers that are going to be live across a safepoint
400 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
401 Thread* thread = Thread::current();
402 const Array<SigEntry>* sig_vk = extended_sig();
403 const Array<VMRegPair>* regs = return_regs();
404 int j = 1;
405
406 for (int i = 0; i < sig_vk->length(); i++) {
407 BasicType bt = sig_vk->at(i)._bt;
408 if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) {
409 int off = sig_vk->at(i)._offset;
410 VMRegPair pair = regs->at(j);
411 address loc = reg_map.location(pair.first());
412 oop v = *(oop*)loc;
413 assert(v == NULL || oopDesc::is_oop(v), "not an oop?");
414 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer");
415 handles.push(Handle(thread, v));
416 }
|