< prev index next >

src/share/vm/oops/valueKlass.cpp

Print this page




 350   const GrowableArray<SigEntry>& sig_vk = collect_fields();
 351   int nb_fields = SigEntry::count_fields(sig_vk)+1;
 352   Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
 353   *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
 354   for (int i = 0; i < sig_vk.length(); i++ ) {
 355     extended_sig->at_put(i, sig_vk.at(i));
 356   }
 357 
 358   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
 359   sig_bt[0] = T_METADATA;
 360   SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
 361   VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
 362   int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
 363 
 364   if (total > 0) {
 365     Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR);
 366     *((Array<VMRegPair>**)adr_return_regs()) = return_regs;
 367     for (int i = 0; i < nb_fields; i++ ) {
 368       return_regs->at_put(i, regs[i]);
 369     }


































 370   }
 371 }
 372 
 373 // Create handles for all oop fields returned in registers that are
 374 // going to be live across a safepoint.
 375 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
 376   if (ValueTypeReturnedAsFields) {
 377     if (return_regs() != NULL) {
 378       save_oop_fields(reg_map, handles);
 379       return true;
 380     }
 381   }
 382   return false;
 383 }
 384 
 385 // Same as above but with pre-computed return convention
 386 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
 387   Thread* thread = Thread::current();
 388   const Array<SigEntry>* sig_vk = extended_sig();
 389   const Array<VMRegPair>* regs = return_regs();


 427       int off = sig_vk->at(i)._offset;
 428       VMRegPair pair = regs->at(j);
 429       address loc = reg_map.location(pair.first());
 430       *(oop*)loc = handles.at(k++)();
 431     }
 432     if (bt == T_VALUETYPE) {
 433       continue;
 434     }
 435     if (bt == T_VOID &&
 436         sig_vk->at(i-1)._bt != T_LONG &&
 437         sig_vk->at(i-1)._bt != T_DOUBLE) {
 438       continue;
 439     }
 440     j++;
 441   }
 442   assert(j == regs->length(), "missed a field?");
 443 }
 444 
 445 // Fields are in registers. Create an instance of the value type and
 446 // initialize it with the values of the fields.
 447 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) {
 448   oop new_vt = allocate_instance(CHECK_NULL);






 449 
 450   const Array<SigEntry>* sig_vk = extended_sig();
 451   const Array<VMRegPair>* regs = return_regs();
 452 
 453   int j = 1;
 454   int k = 0;
 455   for (int i = 0; i < sig_vk->length(); i++) {
 456     BasicType bt = sig_vk->at(i)._bt;
 457     if (bt == T_VALUETYPE) {
 458       continue;
 459     }
 460     if (bt == T_VOID) {
 461       if (sig_vk->at(i-1)._bt == T_LONG ||
 462           sig_vk->at(i-1)._bt == T_DOUBLE) {
 463         j++;
 464       }
 465       continue;
 466     }
 467     int off = sig_vk->at(i)._offset;
 468     VMRegPair pair = regs->at(j);


 511         oopDesc::store_heap_oop(p, v);
 512       } else {
 513         narrowOop* p = (narrowOop*)((address)new_vt + off);
 514         oopDesc::encode_store_heap_oop(p, v);
 515       }
 516       break;
 517     }
 518     case T_FLOAT: {
 519       jfloat v = *(jfloat*)loc;
 520       *(jfloat*)((address)new_vt + off) = v;
 521       break;
 522     }
 523     case T_DOUBLE: {
 524       jdouble v = *(jdouble*)loc;
 525       *(jdouble*)((address)new_vt + off) = v;
 526       break;
 527     }
 528     default:
 529       ShouldNotReachHere();
 530     }

 531     j++;
 532   }
 533   assert(j == regs->length(), "missed a field?");
 534   assert(k == handles.length(), "missed an oop?");
 535   return new_vt;
 536 }
 537 
 538 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
 539   BasicType bt = T_METADATA;
 540   VMRegPair pair;
 541   int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
 542   assert(nb == 1, "broken");
 543 
 544   address loc = map.location(pair.first());
 545   intptr_t ptr = *(intptr_t*)loc;
 546   if (is_set_nth_bit(ptr, 0)) {
 547     clear_nth_bit(ptr, 0);
 548     assert(Metaspace::contains((void*)ptr), "should be klass");
 549     return (ValueKlass*)ptr;
 550   }


 350   const GrowableArray<SigEntry>& sig_vk = collect_fields();
 351   int nb_fields = SigEntry::count_fields(sig_vk)+1;
 352   Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
 353   *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
 354   for (int i = 0; i < sig_vk.length(); i++ ) {
 355     extended_sig->at_put(i, sig_vk.at(i));
 356   }
 357 
 358   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
 359   sig_bt[0] = T_METADATA;
 360   SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
 361   VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
 362   int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
 363 
 364   if (total > 0) {
 365     Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR);
 366     *((Array<VMRegPair>**)adr_return_regs()) = return_regs;
 367     for (int i = 0; i < nb_fields; i++ ) {
 368       return_regs->at_put(i, regs[i]);
 369     }
 370 
 371     BufferedValueTypeBlob* buffered_blob = SharedRuntime::generate_buffered_value_type_adapter(this);
 372     *((address*)adr_pack_handler()) = buffered_blob->pack_fields();
 373     *((address*)adr_unpack_handler()) = buffered_blob->unpack_fields();
 374     assert(CodeCache::find_blob(pack_handler()) == buffered_blob, "lost track of blob");
 375   }
 376   assert(vtable_length() == 0, "a value klass with a vtable?");
 377 }
 378 
 379 void ValueKlass::deallocate_contents(ClassLoaderData* loader_data) {
 380   if (extended_sig() != NULL) {
 381     MetadataFactory::free_array<SigEntry>(loader_data, extended_sig());
 382   }
 383   if (return_regs() != NULL) {
 384     MetadataFactory::free_array<VMRegPair>(loader_data, return_regs());
 385   }
 386   if (pack_handler() != NULL) {
 387     CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
 388     assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
 389     BufferBlob::free((BufferBlob*)buffered_blob);
 390   }
 391   InstanceKlass::deallocate_contents(loader_data);
 392 }
 393 
 394 void ValueKlass::cleanup(ValueKlass* ik) {
 395   ik->cleanup_blobs();
 396 }
 397 
 398 
 399 void ValueKlass::cleanup_blobs() {
 400   if (pack_handler() != NULL) {
 401     CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
 402     assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
 403     BufferBlob::free((BufferBlob*)buffered_blob);
 404   }
 405 }
 406 
 407 // Create handles for all oop fields returned in registers that are
 408 // going to be live across a safepoint.
 409 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
 410   if (ValueTypeReturnedAsFields) {
 411     if (return_regs() != NULL) {
 412       save_oop_fields(reg_map, handles);
 413       return true;
 414     }
 415   }
 416   return false;
 417 }
 418 
 419 // Same as above but with pre-computed return convention
 420 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
 421   Thread* thread = Thread::current();
 422   const Array<SigEntry>* sig_vk = extended_sig();
 423   const Array<VMRegPair>* regs = return_regs();


 461       int off = sig_vk->at(i)._offset;
 462       VMRegPair pair = regs->at(j);
 463       address loc = reg_map.location(pair.first());
 464       *(oop*)loc = handles.at(k++)();
 465     }
 466     if (bt == T_VALUETYPE) {
 467       continue;
 468     }
 469     if (bt == T_VOID &&
 470         sig_vk->at(i-1)._bt != T_LONG &&
 471         sig_vk->at(i-1)._bt != T_DOUBLE) {
 472       continue;
 473     }
 474     j++;
 475   }
 476   assert(j == regs->length(), "missed a field?");
 477 }
 478 
 479 // Fields are in registers. Create an instance of the value type and
 480 // initialize it with the values of the fields.
 481 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, bool buffered, TRAPS) {
 482   bool ignored = false;
 483   oop new_vt = NULL;
 484   if (buffered) {
 485     new_vt = allocate_buffered_or_heap_instance(&ignored, CHECK_NULL);
 486   } else {
 487     new_vt = allocate_instance(CHECK_NULL);
 488   }
 489 
 490   const Array<SigEntry>* sig_vk = extended_sig();
 491   const Array<VMRegPair>* regs = return_regs();
 492 
 493   int j = 1;
 494   int k = 0;
 495   for (int i = 0; i < sig_vk->length(); i++) {
 496     BasicType bt = sig_vk->at(i)._bt;
 497     if (bt == T_VALUETYPE) {
 498       continue;
 499     }
 500     if (bt == T_VOID) {
 501       if (sig_vk->at(i-1)._bt == T_LONG ||
 502           sig_vk->at(i-1)._bt == T_DOUBLE) {
 503         j++;
 504       }
 505       continue;
 506     }
 507     int off = sig_vk->at(i)._offset;
 508     VMRegPair pair = regs->at(j);


 551         oopDesc::store_heap_oop(p, v);
 552       } else {
 553         narrowOop* p = (narrowOop*)((address)new_vt + off);
 554         oopDesc::encode_store_heap_oop(p, v);
 555       }
 556       break;
 557     }
 558     case T_FLOAT: {
 559       jfloat v = *(jfloat*)loc;
 560       *(jfloat*)((address)new_vt + off) = v;
 561       break;
 562     }
 563     case T_DOUBLE: {
 564       jdouble v = *(jdouble*)loc;
 565       *(jdouble*)((address)new_vt + off) = v;
 566       break;
 567     }
 568     default:
 569       ShouldNotReachHere();
 570     }
 571     *(intptr_t*)loc = 0xDEAD;
 572     j++;
 573   }
 574   assert(j == regs->length(), "missed a field?");
 575   assert(k == handles.length(), "missed an oop?");
 576   return new_vt;
 577 }
 578 
 579 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
 580   BasicType bt = T_METADATA;
 581   VMRegPair pair;
 582   int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
 583   assert(nb == 1, "broken");
 584 
 585   address loc = map.location(pair.first());
 586   intptr_t ptr = *(intptr_t*)loc;
 587   if (is_set_nth_bit(ptr, 0)) {
 588     clear_nth_bit(ptr, 0);
 589     assert(Metaspace::contains((void*)ptr), "should be klass");
 590     return (ValueKlass*)ptr;
 591   }
< prev index next >