< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page




 305     // 1 - flattened or not flattened
 306     // 2 - if not flattened: argument is buffered (value) or in heap (value and objects)
 307     if (cp_entry->is_flattened()) {
 308       Klass* field_k = vklass->get_value_field_klass(field_index);
 309       ValueKlass* field_vk = ValueKlass::cast(field_k);
 310       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 311       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 312       assert(field_vk == vt_oop->klass(), "Must match");
 313       field_vk->value_store(field_vk->data_for_oop(vt_oop),
 314           ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
 315     } else { // not flattened
 316       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 317       assert(voop != NULL || !cp_entry->is_flattenable(),
 318              "NULL checks for non flattenable fields must have been performed in interpreter assembly template");
 319       assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
 320       if (VTBuffer::is_in_vt_buffer(voop)) {
 321         // new value field is currently allocated in a TLVB, a heap allocated
 322         // copy must be created because a field must never point to a TLVB allocated value
 323         Handle voop_h = Handle(THREAD, voop);
 324         ValueKlass* field_vk = ValueKlass::cast(voop->klass());
 325         assert(field_vk == vklass->get_value_field_klass(field_index), "Sanity check");
 326         instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 327         Handle field_copy_h = Handle(THREAD, field_copy);
 328         field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false);
 329         if (in_heap) {
 330           new_value_h()->obj_field_put(field_offset, field_copy_h());
 331         } else {
 332           new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
 333         }
 334       } else { // not buffered
 335         if (in_heap) {
 336           new_value_h()->obj_field_put(field_offset, voop);
 337         } else {
 338           new_value_h()->obj_field_put_raw(field_offset, voop);
 339         }
 340       }
 341     }
 342   } else { // not T_OBJECT nor T_ARRAY
 343     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 344     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 345   }


 476   }
 477 IRT_END
 478 
 479 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
 480   oop obj = oopFactory::new_typeArray(type, size, CHECK);
 481   thread->set_vm_result(obj);
 482 IRT_END
 483 
 484 
 485 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 486   Klass*    klass = pool->klass_at(index, CHECK);
 487   if (klass->is_value()) { // Logically creates elements, ensure klass init
 488     klass->initialize(CHECK);
 489   }
 490   arrayOop obj = oopFactory::new_array(klass, size, CHECK);
 491   thread->set_vm_result(obj);
 492 IRT_END
 493 
 494 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 495   Klass* klass = array->klass();
 496   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
 497 
 498   if (klass->is_objArray_klass()) {
 499     thread->set_vm_result(((objArrayOop) array)->obj_at(index));
 500   } else {
 501     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 502     ValueKlass* vklass = vaklass->element_klass();
 503     arrayHandle ah(THREAD, array);
 504     bool in_heap;
 505     instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 506     void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
 507     vklass->value_store(src, vklass->data_for_oop(value_holder),
 508                           vaklass->element_byte_size(), in_heap, false);
 509     thread->set_vm_result(value_holder);
 510   }
 511 IRT_END
 512 
 513 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))

 514   Klass* klass = array->klass();
 515   assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
 516   Handle array_h(THREAD, array);
 517 
 518   if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) {
 519     THROW(vmSymbols::java_lang_ArrayStoreException());
 520   }
 521   if (klass->is_objArray_klass()) {
 522     if(VTBuffer::is_in_vt_buffer(val)) {
 523       // A Java heap allocated copy must be made because an array cannot
 524       // reference a thread-local buffered value
 525       Handle val_h(THREAD, (oop)val);
 526       ObjArrayKlass* aklass = ObjArrayKlass::cast(klass);
 527       Klass* eklass = aklass->element_klass();
 528       assert(eklass->is_value(), "Sanity check");
 529       assert(eklass == ((oop)val)->klass(), "Sanity check");
 530       ValueKlass* vklass = ValueKlass::cast(eklass);
 531       // allocate heap instance
 532       instanceOop res = vklass->allocate_instance(CHECK);
 533       Handle res_h(THREAD, res);
 534       // copy value
 535       vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(),
 536                             ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false);
 537       val = res_h();
 538     }
 539     ((objArrayOop) array_h())->obj_at_put(index, (oop)val);
 540   } else {
 541     valueArrayOop varray = (valueArrayOop)array;
 542     ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 543     ValueKlass* vklass = vaklass->element_klass();
 544     const int lh = vaklass->layout_helper();
 545     vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
 546                         vaklass->element_byte_size(), true, false);
 547   }
 548 IRT_END
 549 
 550 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 551   // We may want to pass in more arguments - could make this slightly faster
 552   LastFrameAccessor last_frame(thread);
 553   ConstantPool* constants = last_frame.method()->constants();
 554   int          i = last_frame.get_index_u2(Bytecodes::_multianewarray);
 555   Klass* klass   = constants->klass_at(i, CHECK);
 556   int   nof_dims = last_frame.number_of_dimensions();
 557   assert(klass->is_klass(), "not a class");
 558   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 559 
 560   if (klass->is_value()) { // Logically creates elements, ensure klass init
 561     klass->initialize(CHECK);
 562   }
 563 
 564   // We must create an array of jints to pass to multi_allocate.
 565   ResourceMark rm(thread);
 566   const int small_dims = 10;
 567   jint dim_array[small_dims];
 568   jint *dims = &dim_array[0];
 569   if (nof_dims > small_dims) {
 570     dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
 571   }
 572   for (int index = 0; index < nof_dims; index++) {
 573     // offset from first_size_address is addressed as local[index]
 574     int n = Interpreter::local_offset_in_bytes(index)/jintSize;
 575     dims[index] = first_size_address[n];
 576   }
 577   oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
 578   thread->set_vm_result(obj);










 579 IRT_END
 580 
 581 IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr))
 582   JavaThread* thread = (JavaThread*)Thread::current();
 583   VTBuffer::recycle_vtbuffer(thread, alloc_ptr);
 584 IRT_END
 585 
 586 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
 587   frame f = thread->last_frame();
 588   assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
 589   VTBuffer::recycle_vt_in_frame(thread, &f);
 590 IRT_END
 591 
 592 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
 593   frame f = thread->last_frame();
 594   VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
 595 IRT_END
 596 
 597 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
 598   assert(VTBuffer::is_in_vt_buffer(obj), "Must only be called for buffered values");




 305     // 1 - flattened or not flattened
 306     // 2 - if not flattened: argument is buffered (value) or in heap (value and objects)
 307     if (cp_entry->is_flattened()) {
 308       Klass* field_k = vklass->get_value_field_klass(field_index);
 309       ValueKlass* field_vk = ValueKlass::cast(field_k);
 310       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 311       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 312       assert(field_vk == vt_oop->klass(), "Must match");
 313       field_vk->value_store(field_vk->data_for_oop(vt_oop),
 314           ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
 315     } else { // not flattened
 316       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 317       assert(voop != NULL || !cp_entry->is_flattenable(),
 318              "NULL checks for non flattenable fields must have been performed in interpreter assembly template");
 319       assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
 320       if (VTBuffer::is_in_vt_buffer(voop)) {
 321         // new value field is currently allocated in a TLVB, a heap allocated
 322         // copy must be created because a field must never point to a TLVB allocated value
 323         Handle voop_h = Handle(THREAD, voop);
 324         ValueKlass* field_vk = ValueKlass::cast(voop->klass());
 325         assert(!cp_entry->is_flattenable() || field_vk == vklass->get_value_field_klass(field_index), "Sanity check");
 326         instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 327         Handle field_copy_h = Handle(THREAD, field_copy);
 328         field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false);
 329         if (in_heap) {
 330           new_value_h()->obj_field_put(field_offset, field_copy_h());
 331         } else {
 332           new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
 333         }
 334       } else { // not buffered
 335         if (in_heap) {
 336           new_value_h()->obj_field_put(field_offset, voop);
 337         } else {
 338           new_value_h()->obj_field_put_raw(field_offset, voop);
 339         }
 340       }
 341     }
 342   } else { // not T_OBJECT nor T_ARRAY
 343     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 344     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 345   }


 476   }
 477 IRT_END
 478 
 479 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
 480   oop obj = oopFactory::new_typeArray(type, size, CHECK);
 481   thread->set_vm_result(obj);
 482 IRT_END
 483 
 484 
 485 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 486   Klass*    klass = pool->klass_at(index, CHECK);
 487   if (klass->is_value()) { // Logically creates elements, ensure klass init
 488     klass->initialize(CHECK);
 489   }
 490   arrayOop obj = oopFactory::new_array(klass, size, CHECK);
 491   thread->set_vm_result(obj);
 492 IRT_END
 493 
 494 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 495   Klass* klass = array->klass();
 496   assert(klass->is_valueArray_klass(), "expected value or object array oop");
 497 



 498   ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 499   ValueKlass* vklass = vaklass->element_klass();
 500   arrayHandle ah(THREAD, array);
 501   bool in_heap;
 502   instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
 503   void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
 504   vklass->value_store(src, vklass->data_for_oop(value_holder),
 505                         vaklass->element_byte_size(), in_heap, false);
 506   thread->set_vm_result(value_holder);

 507 IRT_END
 508 
 509 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
 510   assert(val != NULL, "can't store null into flat array");
 511   Klass* klass = array->klass();
 512   assert(klass->is_valueArray_klass(), "expected value array");
 513   assert(ArrayKlass::cast(klass)->element_klass() == ((oop)val)->klass(), "Store type incorrect");
 514 























 515   valueArrayOop varray = (valueArrayOop)array;
 516   ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 517   ValueKlass* vklass = vaklass->element_klass();
 518   const int lh = vaklass->layout_helper();
 519   vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
 520                       vaklass->element_byte_size(), true, false);

 521 IRT_END
 522 
 523 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 524   // We may want to pass in more arguments - could make this slightly faster
 525   LastFrameAccessor last_frame(thread);
 526   ConstantPool* constants = last_frame.method()->constants();
 527   int          i = last_frame.get_index_u2(Bytecodes::_multianewarray);
 528   Klass* klass   = constants->klass_at(i, CHECK);
 529   int   nof_dims = last_frame.number_of_dimensions();
 530   assert(klass->is_klass(), "not a class");
 531   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 532 
 533   if (klass->is_value()) { // Logically creates elements, ensure klass init
 534     klass->initialize(CHECK);
 535   }
 536 
 537   // We must create an array of jints to pass to multi_allocate.
 538   ResourceMark rm(thread);
 539   const int small_dims = 10;
 540   jint dim_array[small_dims];
 541   jint *dims = &dim_array[0];
 542   if (nof_dims > small_dims) {
 543     dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
 544   }
 545   for (int index = 0; index < nof_dims; index++) {
 546     // offset from first_size_address is addressed as local[index]
 547     int n = Interpreter::local_offset_in_bytes(index)/jintSize;
 548     dims[index] = first_size_address[n];
 549   }
 550   oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
 551   thread->set_vm_result(obj);
 552 IRT_END
 553 
 554 IRT_ENTRY(void, InterpreterRuntime::value_heap_copy(JavaThread* thread, oopDesc* value))
 555   assert(VTBuffer::is_in_vt_buffer(value), "Must only be called for buffered values");
 556   ValueKlass* vk = ValueKlass::cast(value->klass());
 557   Handle val_h(THREAD, value);
 558   instanceOop obj = vk->allocate_instance(CHECK);
 559   Handle obj_h(THREAD, obj);
 560   vk->value_store(vk->data_for_oop(val_h()), vk->data_for_oop(obj_h()), true, false);
 561   thread->set_vm_result(obj_h());
 562 IRT_END
 563 
 564 IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr))
 565   JavaThread* thread = (JavaThread*)Thread::current();
 566   VTBuffer::recycle_vtbuffer(thread, alloc_ptr);
 567 IRT_END
 568 
 569 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
 570   frame f = thread->last_frame();
 571   assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
 572   VTBuffer::recycle_vt_in_frame(thread, &f);
 573 IRT_END
 574 
 575 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
 576   frame f = thread->last_frame();
 577   VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
 578 IRT_END
 579 
 580 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
 581   assert(VTBuffer::is_in_vt_buffer(obj), "Must only be called for buffered values");


< prev index next >