312 if (fs.access_flags().is_static()) continue;
313 fieldDescriptor& fd = fs.field_descriptor();
314 BasicType bt = fd.field_type();
315 int offset = base_off + fd.offset() - (base_off > 0 ? first_field_offset() : 0);
316 if (bt == T_VALUETYPE) {
317 if (fd.is_flatten()) {
318 Symbol* signature = fd.signature();
319 JavaThread* THREAD = JavaThread::current();
320 oop loader = class_loader();
321 oop domain = protection_domain();
322 ResetNoHandleMark rnhm;
323 HandleMark hm;
324 NoSafepointVerifier nsv;
325 Klass* klass = SystemDictionary::resolve_or_null(signature,
326 Handle(THREAD, loader), Handle(THREAD, domain),
327 THREAD);
328 assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail");
329 const GrowableArray<SigEntry>& embedded = ValueKlass::cast(klass)->collect_fields(offset);
330 sig_extended.appendAll(&embedded);
331 } else {
332 sig_extended.push(SigEntry(T_OBJECT, offset));
333 }
334 } else {
335 sig_extended.push(SigEntry(bt, offset));
336 if (bt == T_LONG || bt == T_DOUBLE) {
337 sig_extended.push(SigEntry(T_VOID, offset));
338 }
339 }
340 }
341 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
342 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields
343 if (base_off == 0) {
344 sig_extended.sort(SigEntry::compare);
345 }
346 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure");
347 return sig_extended;
348 }
349
350 void ValueKlass::initialize_calling_convention() {
351 // Because the pack and unpack handler addresses need to be loadable from generated code,
352 // they are stored at a fixed offset in the klass metadata. Since value type klasses do
416 // going to be live across a safepoint.
417 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
418 if (ValueTypeReturnedAsFields) {
419 if (return_regs() != NULL) {
420 save_oop_fields(reg_map, handles);
421 return true;
422 }
423 }
424 return false;
425 }
426
427 // Same as above but with pre-computed return convention
428 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
429 Thread* thread = Thread::current();
430 const Array<SigEntry>* sig_vk = extended_sig();
431 const Array<VMRegPair>* regs = return_regs();
432 int j = 1;
433
434 for (int i = 0; i < sig_vk->length(); i++) {
435 BasicType bt = sig_vk->at(i)._bt;
436 if (bt == T_OBJECT || bt == T_ARRAY) {
437 int off = sig_vk->at(i)._offset;
438 VMRegPair pair = regs->at(j);
439 address loc = reg_map.location(pair.first());
440 oop v = *(oop*)loc;
441 assert(v == NULL || oopDesc::is_oop(v), "not an oop?");
442 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer");
443 handles.push(Handle(thread, v));
444 }
445 if (bt == T_VALUETYPE) {
446 continue;
447 }
448 if (bt == T_VOID &&
449 sig_vk->at(i-1)._bt != T_LONG &&
450 sig_vk->at(i-1)._bt != T_DOUBLE) {
451 continue;
452 }
453 j++;
454 }
455 assert(j == regs->length(), "missed a field?");
456 }
534 case T_SHORT: {
535 jshort v = *(intptr_t*)loc;
536 *(jshort*)((address)new_vt + off) = v;
537 break;
538 }
539 case T_INT: {
540 jint v = *(intptr_t*)loc;
541 *(jint*)((address)new_vt + off) = v;
542 break;
543 }
544 case T_LONG: {
545 #ifdef _LP64
546 jlong v = *(intptr_t*)loc;
547 *(jlong*)((address)new_vt + off) = v;
548 #else
549 Unimplemented();
550 #endif
551 break;
552 }
553 case T_OBJECT:
554 case T_ARRAY: {
555 Handle handle = handles.at(k++);
556 oop v = handle();
557 if (!UseCompressedOops) {
558 oop* p = (oop*)((address)new_vt + off);
559 oopDesc::store_heap_oop(p, v);
560 } else {
561 narrowOop* p = (narrowOop*)((address)new_vt + off);
562 oopDesc::encode_store_heap_oop(p, v);
563 }
564 break;
565 }
566 case T_FLOAT: {
567 jfloat v = *(jfloat*)loc;
568 *(jfloat*)((address)new_vt + off) = v;
569 break;
570 }
571 case T_DOUBLE: {
572 jdouble v = *(jdouble*)loc;
573 *(jdouble*)((address)new_vt + off) = v;
|
312 if (fs.access_flags().is_static()) continue;
313 fieldDescriptor& fd = fs.field_descriptor();
314 BasicType bt = fd.field_type();
315 int offset = base_off + fd.offset() - (base_off > 0 ? first_field_offset() : 0);
316 if (bt == T_VALUETYPE) {
317 if (fd.is_flatten()) {
318 Symbol* signature = fd.signature();
319 JavaThread* THREAD = JavaThread::current();
320 oop loader = class_loader();
321 oop domain = protection_domain();
322 ResetNoHandleMark rnhm;
323 HandleMark hm;
324 NoSafepointVerifier nsv;
325 Klass* klass = SystemDictionary::resolve_or_null(signature,
326 Handle(THREAD, loader), Handle(THREAD, domain),
327 THREAD);
328 assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail");
329 const GrowableArray<SigEntry>& embedded = ValueKlass::cast(klass)->collect_fields(offset);
330 sig_extended.appendAll(&embedded);
331 } else {
332 sig_extended.push(SigEntry(T_VALUETYPEPTR, offset));
333 }
334 } else {
335 sig_extended.push(SigEntry(bt, offset));
336 if (bt == T_LONG || bt == T_DOUBLE) {
337 sig_extended.push(SigEntry(T_VOID, offset));
338 }
339 }
340 }
341 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
342 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields
343 if (base_off == 0) {
344 sig_extended.sort(SigEntry::compare);
345 }
346 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure");
347 return sig_extended;
348 }
349
350 void ValueKlass::initialize_calling_convention() {
351 // Because the pack and unpack handler addresses need to be loadable from generated code,
352 // they are stored at a fixed offset in the klass metadata. Since value type klasses do
416 // going to be live across a safepoint.
417 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
418 if (ValueTypeReturnedAsFields) {
419 if (return_regs() != NULL) {
420 save_oop_fields(reg_map, handles);
421 return true;
422 }
423 }
424 return false;
425 }
426
427 // Same as above but with pre-computed return convention
428 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
429 Thread* thread = Thread::current();
430 const Array<SigEntry>* sig_vk = extended_sig();
431 const Array<VMRegPair>* regs = return_regs();
432 int j = 1;
433
434 for (int i = 0; i < sig_vk->length(); i++) {
435 BasicType bt = sig_vk->at(i)._bt;
436 if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) {
437 int off = sig_vk->at(i)._offset;
438 VMRegPair pair = regs->at(j);
439 address loc = reg_map.location(pair.first());
440 oop v = *(oop*)loc;
441 assert(v == NULL || oopDesc::is_oop(v), "not an oop?");
442 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer");
443 handles.push(Handle(thread, v));
444 }
445 if (bt == T_VALUETYPE) {
446 continue;
447 }
448 if (bt == T_VOID &&
449 sig_vk->at(i-1)._bt != T_LONG &&
450 sig_vk->at(i-1)._bt != T_DOUBLE) {
451 continue;
452 }
453 j++;
454 }
455 assert(j == regs->length(), "missed a field?");
456 }
534 case T_SHORT: {
535 jshort v = *(intptr_t*)loc;
536 *(jshort*)((address)new_vt + off) = v;
537 break;
538 }
539 case T_INT: {
540 jint v = *(intptr_t*)loc;
541 *(jint*)((address)new_vt + off) = v;
542 break;
543 }
544 case T_LONG: {
545 #ifdef _LP64
546 jlong v = *(intptr_t*)loc;
547 *(jlong*)((address)new_vt + off) = v;
548 #else
549 Unimplemented();
550 #endif
551 break;
552 }
553 case T_OBJECT:
554 case T_VALUETYPEPTR:
555 case T_ARRAY: {
556 Handle handle = handles.at(k++);
557 oop v = handle();
558 if (!UseCompressedOops) {
559 oop* p = (oop*)((address)new_vt + off);
560 oopDesc::store_heap_oop(p, v);
561 } else {
562 narrowOop* p = (narrowOop*)((address)new_vt + off);
563 oopDesc::encode_store_heap_oop(p, v);
564 }
565 break;
566 }
567 case T_FLOAT: {
568 jfloat v = *(jfloat*)loc;
569 *(jfloat*)((address)new_vt + off) = v;
570 break;
571 }
572 case T_DOUBLE: {
573 jdouble v = *(jdouble*)loc;
574 *(jdouble*)((address)new_vt + off) = v;
|