< prev index next >

src/hotspot/share/oops/valueKlass.cpp

Print this page




 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;


< prev index next >