< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page




  55 #include "runtime/biasedLocking.hpp"
  56 #include "runtime/compilationPolicy.hpp"
  57 #include "runtime/deoptimization.hpp"
  58 #include "runtime/fieldDescriptor.hpp"
  59 #include "runtime/handles.inline.hpp"
  60 #include "runtime/icache.hpp"
  61 #include "runtime/interfaceSupport.hpp"
  62 #include "runtime/java.hpp"
  63 #include "runtime/jfieldIDWorkaround.hpp"
  64 #include "runtime/osThread.hpp"
  65 #include "runtime/sharedRuntime.hpp"
  66 #include "runtime/stubRoutines.hpp"
  67 #include "runtime/synchronizer.hpp"
  68 #include "runtime/threadCritical.hpp"
  69 #include "utilities/align.hpp"
  70 #include "utilities/events.hpp"
  71 #include "utilities/globalDefinitions.hpp"
  72 #ifdef COMPILER2
  73 #include "opto/runtime.hpp"
  74 #endif



  75 
  76 class UnlockFlagSaver {
  77   private:
  78     JavaThread* _thread;
  79     bool _do_not_unlock;
  80   public:
  81     UnlockFlagSaver(JavaThread* t) {
  82       _thread = t;
  83       _do_not_unlock = t->do_not_unlock_if_synchronized();
  84       t->set_do_not_unlock_if_synchronized(false);
  85     }
  86     ~UnlockFlagSaver() {
  87       _thread->set_do_not_unlock_if_synchronized(_do_not_unlock);
  88     }
  89 };
  90 
  91 //------------------------------------------------------------------------------------------------------------------------
  92 // State accessors
  93 
  94 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {


 247   frame f = last_frame(thread);
 248   jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
 249   int vt_offset = type2size[field_type];
 250   oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
 251   assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
 252   Handle old_value_h(THREAD, old_value);
 253 
 254   // Creating new value by copying the one passed in argument
 255   bool in_heap;
 256   instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap,
 257       CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 258   Handle new_value_h = Handle(THREAD, new_value);
 259   int first_offset = vklass->first_field_offset();
 260   vklass->value_store(vklass->data_for_oop(old_value_h()),
 261       vklass->data_for_oop(new_value_h()), in_heap, false);
 262 
 263   // Updating the field specified in arguments
 264   if (field_type == T_OBJECT || field_type == T_ARRAY) {
 265     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 266     assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type");

 267     new_value_h()->obj_field_put(field_offset, aoop);












 268   } else if (field_type == T_VALUETYPE) {
 269     if (cp_entry->is_flatten()) {
 270       Klass* field_k = vklass->get_value_field_klass(field_index);
 271       ValueKlass* field_vk = ValueKlass::cast(field_k);
 272       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 273       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 274       assert(field_vk == vt_oop->klass(), "Must match");
 275       field_vk->value_store(field_vk->data_for_oop(vt_oop),
 276           ((char*)(oopDesc*)new_value_h()) + field_offset, true, false);
 277     } else {
 278       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 279       assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");



















 280       new_value_h()->obj_field_put(field_offset, voop);







 281     }
 282   } else {
 283     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 284     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 285   }
 286 
 287   // returning result
 288   thread->set_vm_result(new_value_h());
 289   return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize;
 290 IRT_END
 291 
 292 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value))
 293   assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled");
 294   if (value == NULL) {
 295     THROW(vmSymbols::java_lang_NullPointerException());
 296   }
 297 
 298   // Since the verifier is probably disabled, a few extra type check
 299   Klass* target_klass = pool->klass_at(index, CHECK);
 300   if (target_klass->is_value()) {


 341   InstanceKlass* klass = InstanceKlass::cast(field_holder);
 342 
 343   Klass* field_k = klass->get_value_field_klass(index);
 344   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 345   field_vklass->initialize(THREAD);
 346 
 347   instanceOop res;
 348   bool in_heap;
 349   if (klass->is_field_flatten(index)) {
 350     // allocate instance
 351     res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 352     instanceHandle res_h(THREAD, res);
 353     // copy value
 354     field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index),
 355                               field_vklass->data_for_oop(res), in_heap, false);
 356     thread->set_vm_result(res_h());
 357   } else {
 358     oop res = value_h()->obj_field_acquire(klass->field_offset(index));
 359     if (res == NULL) {
 360       res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);



 361     }
 362     thread->set_vm_result(res);
 363   }

 364 IRT_END
 365 
 366 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
 367   instanceHandle mirror_h(THREAD, (instanceOop)mirror);
 368   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
 369   int offset = klass->field_offset(index);
 370   assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
 371 
 372   Klass* field_k = klass->get_value_field_klass_or_null(index);
 373   if (field_k == NULL) {
 374     field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index),
 375                                                 Handle(THREAD, klass->class_loader()),
 376                                                 Handle(THREAD, klass->protection_domain()), true, CHECK);
 377     assert(field_k != NULL, "Sanity check");
 378     assert(field_k->access_flags().is_value_type(), "Value type expected");
 379     klass->set_value_field_klass(index, field_k);
 380   }
 381   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 382   // allocate instance, because it is going to be assigned to a static field
 383   // it must not be a buffered value


 385   instanceHandle res_h(THREAD, res);
 386   mirror_h()->obj_field_put(offset, res_h());
 387   thread->set_vm_result(res_h());
 388 IRT_END
 389 
 390 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, ConstantPoolCache* cp_cache))
 391   Handle value_h(THREAD, value);
 392   Handle obj_h(THREAD, obj);
 393   assert(!obj_h()->klass()->is_value(), "obj must be an object");
 394   assert(value_h()->klass()->is_value(), "value must be an value type");
 395 
 396   int idx = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putfield));
 397   ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(idx);
 398 
 399   int index = cp_entry->field_index();
 400   bool flatten = cp_entry->is_flatten();
 401 
 402   InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
 403   Klass* field_k = klass->get_value_field_klass(index);
 404   ValueKlass* field_vklass = ValueKlass::cast(value->klass());

 405   assert(field_k == field_vklass, "Field descriptor and argument must match");
 406   if (flatten) {
 407     // copy value
 408     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 409                               ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);
 410   } else {
 411     if (Universe::heap()->is_in_reserved(value_h())) {
 412       obj_h()->obj_field_put(klass->field_offset(index), value_h());
 413     } else {
 414       // allocate heap instance
 415       instanceOop val = field_vklass->allocate_instance(CHECK);
 416       instanceHandle res_h(THREAD, val);
 417       // copy value
 418       field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 419                                 field_vklass->data_for_oop(res_h()), true, false);
 420 
 421 
 422       obj_h()->obj_field_put(klass->field_offset(index), res_h());
 423     }
 424   }
 425 IRT_END
 426 
 427 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
 428   instanceHandle value_h(THREAD, (instanceOop)value);
 429   assert(value_h()->is_value(), "qputstatic only deals with value arguments");
 430   if (Universe::heap()->is_in_reserved(value_h())) {
 431       mirror->obj_field_put(offset, value_h());
 432   } else {
 433     // The argument is a buffered value, a copy must be created in the Java heap
 434     // because a static field cannot point to a thread-local buffered value
 435     ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
 436     Handle mirror_h(THREAD, mirror);
 437     // allocate heap instance
 438     instanceOop res = field_vklass->allocate_instance(CHECK);
 439     assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
 440     instanceHandle res_h(THREAD, res);
 441     // copy value
 442     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 443                               field_vklass->data_for_oop(res), true, false);
 444     // writing static field
 445     mirror_h->obj_field_put(offset, res_h());
 446     assert(mirror_h->obj_field(offset) != NULL,"Sanity check");
 447   }
 448 IRT_END
 449 
 450 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
 451   oop obj = oopFactory::new_typeArray(type, size, CHECK);
 452   thread->set_vm_result(obj);
 453 IRT_END
 454 
 455 
 456 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 457   Klass*    klass = pool->klass_at(index, CHECK);
 458   if (klass->is_value()) { // Logically creates elements, ensure klass init
 459     klass->initialize(CHECK);
 460   }
 461   arrayOop obj = oopFactory::new_array(klass, size, CHECK);
 462   thread->set_vm_result(obj);
 463 IRT_END
 464 
 465 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 466   Klass* klass = array->klass();
 467   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
 468 
 469   if (klass->is_objArray_klass()) {
 470     thread->set_vm_result(((objArrayOop) array)->obj_at(index));
 471   }
 472   else {
 473     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 474     ValueKlass* vklass = vaklass->element_klass();
 475     arrayHandle ah(THREAD, array);
 476     bool in_heap;
 477     instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 478     void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
 479     vklass->value_store(src, vklass->data_for_oop(value_holder),
 480                           vaklass->element_byte_size(), in_heap, false);
 481     thread->set_vm_result(value_holder);
 482   }
 483 IRT_END
 484 
 485 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))
 486   Klass* klass = array->klass();
 487   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");

 488 
 489   if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) {
 490     THROW(vmSymbols::java_lang_ArrayStoreException());
 491   }
 492   if (klass->is_objArray_klass()) {
 493     if(!Universe::heap()->is_in_reserved(val)) {
 494       // A Java heap allocated copy must be made because an array cannot
 495       // reference a thread-local buffered value
 496       Handle val_h(THREAD, (oop)val);
 497       ObjArrayKlass* aklass = ObjArrayKlass::cast(klass);
 498       Klass* eklass = aklass->element_klass();
 499       assert(eklass->is_value(), "Sanity check");
 500       assert(eklass == ((oop)val)->klass(), "Sanity check");
 501       ValueKlass* vklass = ValueKlass::cast(eklass);
 502       // allocate heap instance
 503       instanceOop res = vklass->allocate_instance(CHECK);
 504       Handle res_h(THREAD, res);
 505       // copy value
 506       vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(),
 507                             ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false);
 508       val = res_h();
 509     }
 510     ((objArrayOop) array)->obj_at_put(index, (oop)val);
 511   } else {
 512     valueArrayOop varray = (valueArrayOop)array;
 513     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 514     ValueKlass* vklass = vaklass->element_klass();
 515     const int lh = vaklass->layout_helper();
 516     vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
 517                         vaklass->element_byte_size(), true, false);
 518   }
 519 IRT_END
 520 
 521 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 522   // We may want to pass in more arguments - could make this slightly faster
 523   ConstantPool* constants = method(thread)->constants();
 524   int          i = get_index_u2(thread, Bytecodes::_multianewarray);
 525   Klass* klass = constants->klass_at(i, CHECK);
 526   int   nof_dims = number_of_dimensions(thread);
 527   assert(klass->is_klass(), "not a class");
 528   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 529 
 530   if (klass->is_value()) { // Logically creates elements, ensure klass init
 531     klass->initialize(CHECK);
 532   }
 533 
 534   // We must create an array of jints to pass to multi_allocate.
 535   ResourceMark rm(thread);
 536   const int small_dims = 10;
 537   jint dim_array[small_dims];
 538   jint *dims = &dim_array[0];
 539   if (nof_dims > small_dims) {
 540     dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
 541   }
 542   for (int index = 0; index < nof_dims; index++) {
 543     // offset from first_size_address is addressed as local[index]
 544     int n = Interpreter::local_offset_in_bytes(index)/jintSize;
 545     dims[index] = first_size_address[n];
 546   }
 547   oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
 548   thread->set_vm_result(obj);
 549 IRT_END
 550 
 551 IRT_ENTRY(void, InterpreterRuntime::recycle_vtbuffer(JavaThread* thread))
 552   VTBuffer::recycle_vtbuffer(thread, last_frame(thread));

 553 IRT_END
 554 
 555 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
 556   frame f = thread->last_frame();
 557   assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
 558   VTBuffer::recycle_vt_in_frame(thread, &f);
 559 IRT_END
 560 
 561 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
 562   frame f = thread->last_frame();
 563   VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
 564 IRT_END
 565 
 566 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
 567   if (Universe::heap()->is_in_reserved(obj)) {
 568     thread->set_vm_result(obj);
 569     return;
 570   }
 571   assert(obj->klass()->is_value(), "Sanity check");
 572   ValueKlass* vk = ValueKlass::cast(obj->klass());
 573   RegisterMap reg_map(thread, false);
 574   frame current_frame = last_frame(thread);
 575   frame caller_frame = current_frame.sender(&reg_map);
 576   if (!caller_frame.is_interpreted_frame()) {
 577     // caller is not an interpreted frame, creating a new value in Java heap
 578     Handle obj_h(THREAD, obj);
 579     instanceOop res = vk->allocate_instance(CHECK);
 580     Handle res_h(THREAD, res);
 581     // copy value
 582     vk->value_store(vk->data_for_oop(obj_h()),
 583                     vk->data_for_oop(res_h()), true, false);
 584     thread->set_vm_result(res_h());
 585     return;
 586   } else {
 587     oop dest = VTBuffer::relocate_return_value(thread, current_frame, obj);
 588     thread->set_vm_result(dest);





 589   }











 590 IRT_END
 591 
 592 IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj))
 593   if (obj != NULL) {
 594     Klass* k = obj->klass();
 595     if (k->is_value()) {
 596       ResourceMark rm(thread);
 597       tty->print_cr("areturn used on a value from %s", k->name()->as_C_string());
 598     }
 599     assert(!k->is_value(), "areturn should never be used on values");
 600   }
 601   thread->set_vm_result(obj);
 602 IRT_END
 603 
 604 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
 605   assert(oopDesc::is_oop(obj), "must be a valid oop");
 606   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
 607   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
 608 IRT_END
 609 




  55 #include "runtime/biasedLocking.hpp"
  56 #include "runtime/compilationPolicy.hpp"
  57 #include "runtime/deoptimization.hpp"
  58 #include "runtime/fieldDescriptor.hpp"
  59 #include "runtime/handles.inline.hpp"
  60 #include "runtime/icache.hpp"
  61 #include "runtime/interfaceSupport.hpp"
  62 #include "runtime/java.hpp"
  63 #include "runtime/jfieldIDWorkaround.hpp"
  64 #include "runtime/osThread.hpp"
  65 #include "runtime/sharedRuntime.hpp"
  66 #include "runtime/stubRoutines.hpp"
  67 #include "runtime/synchronizer.hpp"
  68 #include "runtime/threadCritical.hpp"
  69 #include "utilities/align.hpp"
  70 #include "utilities/events.hpp"
  71 #include "utilities/globalDefinitions.hpp"
  72 #ifdef COMPILER2
  73 #include "opto/runtime.hpp"
  74 #endif
  75 #if INCLUDE_ALL_GCS
  76 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  77 #endif // INCLUDE_ALL_GCS
  78 
  79 class UnlockFlagSaver {
  80   private:
  81     JavaThread* _thread;
  82     bool _do_not_unlock;
  83   public:
  84     UnlockFlagSaver(JavaThread* t) {
  85       _thread = t;
  86       _do_not_unlock = t->do_not_unlock_if_synchronized();
  87       t->set_do_not_unlock_if_synchronized(false);
  88     }
  89     ~UnlockFlagSaver() {
  90       _thread->set_do_not_unlock_if_synchronized(_do_not_unlock);
  91     }
  92 };
  93 
  94 //------------------------------------------------------------------------------------------------------------------------
  95 // State accessors
  96 
  97 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {


 250   frame f = last_frame(thread);
 251   jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
 252   int vt_offset = type2size[field_type];
 253   oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
 254   assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
 255   Handle old_value_h(THREAD, old_value);
 256 
 257   // Creating new value by copying the one passed in argument
 258   bool in_heap;
 259   instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap,
 260       CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 261   Handle new_value_h = Handle(THREAD, new_value);
 262   int first_offset = vklass->first_field_offset();
 263   vklass->value_store(vklass->data_for_oop(old_value_h()),
 264       vklass->data_for_oop(new_value_h()), in_heap, false);
 265 
 266   // Updating the field specified in arguments
 267   if (field_type == T_OBJECT || field_type == T_ARRAY) {
 268     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 269     assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type");
 270     if (in_heap) {
 271       new_value_h()->obj_field_put(field_offset, aoop);
 272     } else {
 273       if (UseG1GC) {
 274         if (aoop != NULL) {
 275           G1SATBCardTableModRefBS::enqueue(aoop);
 276         }
 277         oop old = new_value_h()->obj_field_acquire(field_offset);
 278         if (old != NULL) {
 279           G1SATBCardTableModRefBS::enqueue(old);
 280         }
 281       }
 282       new_value_h()->obj_field_put_raw(field_offset, aoop);
 283     }
 284   } else if (field_type == T_VALUETYPE) {
 285     if (cp_entry->is_flatten()) {
 286       Klass* field_k = vklass->get_value_field_klass(field_index);
 287       ValueKlass* field_vk = ValueKlass::cast(field_k);
 288       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 289       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 290       assert(field_vk == vt_oop->klass(), "Must match");
 291       field_vk->value_store(field_vk->data_for_oop(vt_oop),
 292           ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
 293     } else {
 294       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 295       assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");
 296       if (VTBuffer::is_in_vt_buffer(voop)) {
 297         // new value field is currently allocated in a TLVB, a heap allocated
 298         // copy must be created because a field must never point to a TLVB allocated value
 299         Handle voop_h = Handle(THREAD, voop);
 300         ValueKlass* field_vk = ValueKlass::cast(voop->klass());
 301         assert(field_vk == vklass->get_value_field_klass(field_index), "Sanity check");
 302         instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 303         Handle field_copy_h = Handle(THREAD, field_copy);
 304         field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false);
 305         if (in_heap) {
 306           new_value_h()->obj_field_put(field_offset, field_copy_h());
 307         } else {
 308           new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
 309           if (UseG1GC) {
 310             G1SATBCardTableModRefBS::enqueue(field_copy_h());
 311           }
 312         }
 313       } else {
 314         if (in_heap) {
 315           new_value_h()->obj_field_put(field_offset, voop);
 316         } else {
 317           new_value_h()->obj_field_put_raw(field_offset, voop);
 318           if (UseG1GC) {
 319             G1SATBCardTableModRefBS::enqueue(voop);
 320           }
 321         }
 322       }
 323     }
 324   } else {
 325     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 326     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 327   }
 328 
 329   // returning result
 330   thread->set_vm_result(new_value_h());
 331   return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize;
 332 IRT_END
 333 
 334 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value))
 335   assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled");
 336   if (value == NULL) {
 337     THROW(vmSymbols::java_lang_NullPointerException());
 338   }
 339 
 340   // Since the verifier is probably disabled, a few extra type check
 341   Klass* target_klass = pool->klass_at(index, CHECK);
 342   if (target_klass->is_value()) {


 383   InstanceKlass* klass = InstanceKlass::cast(field_holder);
 384 
 385   Klass* field_k = klass->get_value_field_klass(index);
 386   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 387   field_vklass->initialize(THREAD);
 388 
 389   instanceOop res;
 390   bool in_heap;
 391   if (klass->is_field_flatten(index)) {
 392     // allocate instance
 393     res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 394     instanceHandle res_h(THREAD, res);
 395     // copy value
 396     field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index),
 397                               field_vklass->data_for_oop(res), in_heap, false);
 398     thread->set_vm_result(res_h());
 399   } else {
 400     oop res = value_h()->obj_field_acquire(klass->field_offset(index));
 401     if (res == NULL) {
 402       res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 403     } else {
 404       assert(res->klass() == field_k, "Sanity check");
 405       assert(!VTBuffer::is_in_vt_buffer(res), "Sanity check");
 406     }
 407     thread->set_vm_result(res);
 408   }
 409   assert(thread->vm_result()->klass() == field_vklass, "sanity check");
 410 IRT_END
 411 
 412 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
 413   instanceHandle mirror_h(THREAD, (instanceOop)mirror);
 414   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
 415   int offset = klass->field_offset(index);
 416   assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
 417 
 418   Klass* field_k = klass->get_value_field_klass_or_null(index);
 419   if (field_k == NULL) {
 420     field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index),
 421                                                 Handle(THREAD, klass->class_loader()),
 422                                                 Handle(THREAD, klass->protection_domain()), true, CHECK);
 423     assert(field_k != NULL, "Sanity check");
 424     assert(field_k->access_flags().is_value_type(), "Value type expected");
 425     klass->set_value_field_klass(index, field_k);
 426   }
 427   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 428   // allocate instance, because it is going to be assigned to a static field
 429   // it must not be a buffered value


 431   instanceHandle res_h(THREAD, res);
 432   mirror_h()->obj_field_put(offset, res_h());
 433   thread->set_vm_result(res_h());
 434 IRT_END
 435 
 436 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, ConstantPoolCache* cp_cache))
 437   Handle value_h(THREAD, value);
 438   Handle obj_h(THREAD, obj);
 439   assert(!obj_h()->klass()->is_value(), "obj must be an object");
 440   assert(value_h()->klass()->is_value(), "value must be an value type");
 441 
 442   int idx = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putfield));
 443   ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(idx);
 444 
 445   int index = cp_entry->field_index();
 446   bool flatten = cp_entry->is_flatten();
 447 
 448   InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
 449   Klass* field_k = klass->get_value_field_klass(index);
 450   ValueKlass* field_vklass = ValueKlass::cast(value->klass());
 451   assert(value_h()->klass() == field_k, "Sanity check");
 452   assert(field_k == field_vklass, "Field descriptor and argument must match");
 453   if (flatten) {
 454     // copy value
 455     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 456                               ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);
 457   } else {
 458     if (!VTBuffer::is_in_vt_buffer(value_h())) {
 459       obj_h()->obj_field_put(klass->field_offset(index), value_h());
 460     } else {
 461       // allocate heap instance
 462       instanceOop val = field_vklass->allocate_instance(CHECK);
 463       instanceHandle res_h(THREAD, val);
 464       // copy value
 465       field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 466                                 field_vklass->data_for_oop(res_h()), true, false);
 467 
 468 
 469       obj_h()->obj_field_put(klass->field_offset(index), res_h());
 470     }
 471   }
 472 IRT_END
 473 
 474 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
 475   instanceHandle value_h(THREAD, (instanceOop)value);
 476   assert(value_h()->is_value(), "qputstatic only deals with value arguments");
 477   if (!VTBuffer::is_in_vt_buffer(value_h())) {
 478       mirror->obj_field_put(offset, value_h());
 479   } else {
 480     // The argument is a buffered value, a copy must be created in the Java heap
 481     // because a static field cannot point to a thread-local buffered value
 482     ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
 483     Handle mirror_h(THREAD, mirror);
 484     // allocate heap instance
 485     instanceOop res = field_vklass->allocate_instance(CHECK);
 486     assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
 487     instanceHandle res_h(THREAD, res);
 488     // copy value
 489     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 490                               field_vklass->data_for_oop(res), true, false);
 491     // writing static field
 492     mirror_h->obj_field_put(offset, res_h());
 493     assert(mirror_h->obj_field(offset) != NULL,"Sanity check");
 494   }
 495 IRT_END
 496 
 497 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
 498   oop obj = oopFactory::new_typeArray(type, size, CHECK);
 499   thread->set_vm_result(obj);
 500 IRT_END
 501 
 502 
 503 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 504   Klass*    klass = pool->klass_at(index, CHECK);
 505   if (klass->is_value()) { // Logically creates elements, ensure klass init
 506     klass->initialize(CHECK);
 507   }
 508   arrayOop obj = oopFactory::new_array(klass, size, CHECK);
 509   thread->set_vm_result(obj);
 510 IRT_END
 511 
 512 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 513   Klass* klass = array->klass();
 514   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
 515 
 516   if (klass->is_objArray_klass()) {
 517     thread->set_vm_result(((objArrayOop) array)->obj_at(index));
 518   } else {

 519     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 520     ValueKlass* vklass = vaklass->element_klass();
 521     arrayHandle ah(THREAD, array);
 522     bool in_heap;
 523     instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 524     void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
 525     vklass->value_store(src, vklass->data_for_oop(value_holder),
 526                           vaklass->element_byte_size(), in_heap, false);
 527     thread->set_vm_result(value_holder);
 528   }
 529 IRT_END
 530 
 531 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))
 532   Klass* klass = array->klass();
 533   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
 534   Handle array_h(THREAD, array);
 535 
 536   if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) {
 537     THROW(vmSymbols::java_lang_ArrayStoreException());
 538   }
 539   if (klass->is_objArray_klass()) {
 540     if(VTBuffer::is_in_vt_buffer(val)) {
 541       // A Java heap allocated copy must be made because an array cannot
 542       // reference a thread-local buffered value
 543       Handle val_h(THREAD, (oop)val);
 544       ObjArrayKlass* aklass = ObjArrayKlass::cast(klass);
 545       Klass* eklass = aklass->element_klass();
 546       assert(eklass->is_value(), "Sanity check");
 547       assert(eklass == ((oop)val)->klass(), "Sanity check");
 548       ValueKlass* vklass = ValueKlass::cast(eklass);
 549       // allocate heap instance
 550       instanceOop res = vklass->allocate_instance(CHECK);
 551       Handle res_h(THREAD, res);
 552       // copy value
 553       vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(),
 554                             ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false);
 555       val = res_h();
 556     }
 557     ((objArrayOop) array_h())->obj_at_put(index, (oop)val);
 558   } else {
 559     valueArrayOop varray = (valueArrayOop)array;
 560     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 561     ValueKlass* vklass = vaklass->element_klass();
 562     const int lh = vaklass->layout_helper();
 563     vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
 564                         vaklass->element_byte_size(), true, false);
 565   }
 566 IRT_END
 567 
 568 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 569   // We may want to pass in more arguments - could make this slightly faster
 570   ConstantPool* constants = method(thread)->constants();
 571   int          i = get_index_u2(thread, Bytecodes::_multianewarray);
 572   Klass* klass = constants->klass_at(i, CHECK);
 573   int   nof_dims = number_of_dimensions(thread);
 574   assert(klass->is_klass(), "not a class");
 575   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 576 
 577   if (klass->is_value()) { // Logically creates elements, ensure klass init
 578     klass->initialize(CHECK);
 579   }
 580 
 581   // We must create an array of jints to pass to multi_allocate.
 582   ResourceMark rm(thread);
 583   const int small_dims = 10;
 584   jint dim_array[small_dims];
 585   jint *dims = &dim_array[0];
 586   if (nof_dims > small_dims) {
 587     dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
 588   }
 589   for (int index = 0; index < nof_dims; index++) {
 590     // offset from first_size_address is addressed as local[index]
 591     int n = Interpreter::local_offset_in_bytes(index)/jintSize;
 592     dims[index] = first_size_address[n];
 593   }
 594   oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
 595   thread->set_vm_result(obj);
 596 IRT_END
 597 
 598 IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr))
 599   JavaThread* thread = (JavaThread*)Thread::current();
 600   VTBuffer::recycle_vtbuffer(thread, alloc_ptr);
 601 IRT_END
 602 
 603 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
 604   frame f = thread->last_frame();
 605   assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
 606   VTBuffer::recycle_vt_in_frame(thread, &f);
 607 IRT_END
 608 
 609 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
 610   frame f = thread->last_frame();
 611   VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
 612 IRT_END
 613 
 614 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
 615   if (!VTBuffer::is_in_vt_buffer(obj)) {
 616     thread->set_vm_result(obj);
 617     return;
 618   }
 619   assert(obj->klass()->is_value(), "Sanity check");
 620   ValueKlass* vk = ValueKlass::cast(obj->klass());
 621   RegisterMap reg_map(thread, false);
 622   frame current_frame = last_frame(thread);
 623   frame caller_frame = current_frame.sender(&reg_map);
 624   if (!caller_frame.is_interpreted_frame()) {
 625     // caller is not an interpreted frame, creating a new value in Java heap
 626     Handle obj_h(THREAD, obj);
 627     instanceOop res = vk->allocate_instance(CHECK);
 628     Handle res_h(THREAD, res);
 629     // copy value
 630     vk->value_store(vk->data_for_oop(obj_h()),
 631                     vk->data_for_oop(res_h()), true, false);
 632     thread->set_vm_result(res_h());
 633     return;
 634   } else {
 635     // A buffered value is being returned to an interpreted frame,
 636     // but the work has to be delayed to remove_activation() because
 637     // the frame cannot be modified now (GC can run at the safepoint
 638     // when exiting runtime, and frame layout must be kept consistent
 639     // with the OopMap).
 640     thread->set_return_buffered_value(obj);
 641     thread->set_vm_result(obj);
 642   }
 643 IRT_END
 644 
 645 IRT_LEAF(void, InterpreterRuntime::return_value_step2(oopDesc* obj, void* alloc_ptr))
 646 
 647   JavaThread* thread = (JavaThread*)Thread::current();
 648   assert(obj == thread->return_buffered_value(), "Consistency check");
 649   assert(!Universe::heap()->is_in_reserved(obj), "Should only apply to buffered values");
 650 
 651   oop dest = VTBuffer::relocate_return_value(thread, alloc_ptr, obj);
 652   thread->set_return_buffered_value(NULL);
 653   thread->set_vm_result(dest);
 654 IRT_END
 655 
 656 IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj))
 657   if (obj != NULL) {
 658     Klass* k = obj->klass();
 659     if (k->is_value()) {
 660       ResourceMark rm(thread);
 661       tty->print_cr("areturn used on a value from %s", k->name()->as_C_string());
 662     }
 663     assert(!k->is_value(), "areturn should never be used on values");
 664   }
 665   thread->set_vm_result(obj);
 666 IRT_END
 667 
 668 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
 669   assert(oopDesc::is_oop(obj), "must be a valid oop");
 670   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
 671   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
 672 IRT_END
 673 


< prev index next >