< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page




  31 #include "compiler/compileBroker.hpp"
  32 #include "compiler/disassembler.hpp"
  33 #include "gc/shared/barrierSetNMethod.hpp"
  34 #include "gc/shared/collectedHeap.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "interpreter/interpreterRuntime.hpp"
  37 #include "interpreter/linkResolver.hpp"
  38 #include "interpreter/templateTable.hpp"
  39 #include "logging/log.hpp"
  40 #include "memory/oopFactory.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "oops/constantPool.hpp"
  44 #include "oops/cpCache.inline.hpp"
  45 #include "oops/instanceKlass.hpp"
  46 #include "oops/methodData.hpp"
  47 #include "oops/objArrayKlass.hpp"
  48 #include "oops/objArrayOop.inline.hpp"
  49 #include "oops/oop.inline.hpp"
  50 #include "oops/symbol.hpp"
  51 #include "oops/valueKlass.hpp"
  52 #include "oops/valueArrayKlass.hpp"
  53 #include "oops/valueArrayOop.hpp"
  54 #include "oops/valueArrayOop.inline.hpp"

  55 #include "prims/jvmtiExport.hpp"
  56 #include "prims/nativeLookup.hpp"
  57 #include "runtime/atomic.hpp"
  58 #include "runtime/biasedLocking.hpp"
  59 #include "runtime/compilationPolicy.hpp"
  60 #include "runtime/deoptimization.hpp"
  61 #include "runtime/fieldDescriptor.inline.hpp"
  62 #include "runtime/frame.inline.hpp"
  63 #include "runtime/handles.inline.hpp"
  64 #include "runtime/icache.hpp"
  65 #include "runtime/interfaceSupport.inline.hpp"
  66 #include "runtime/java.hpp"
  67 #include "runtime/javaCalls.hpp"
  68 #include "runtime/jfieldIDWorkaround.hpp"
  69 #include "runtime/osThread.hpp"
  70 #include "runtime/sharedRuntime.hpp"
  71 #include "runtime/stubRoutines.hpp"
  72 #include "runtime/synchronizer.hpp"
  73 #include "runtime/threadCritical.hpp"
  74 #include "utilities/align.hpp"


 320   int offset = cp_entry->f2_as_index();
 321   int field_index = cp_entry->field_index();
 322   int field_offset = cp_entry->f2_as_offset();
 323   Symbol* field_signature = vklass->field_signature(field_index);
 324   ResourceMark rm(THREAD);
 325   const char* signature = (const char *) field_signature->as_utf8();
 326   BasicType field_type = char2type(signature[0]);
 327 
 328   // Getting old value
 329   frame& f = last_frame.get_frame();
 330   jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
 331   int vt_offset = type2size[field_type];
 332   oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
 333   assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
 334   Handle old_value_h(THREAD, old_value);
 335 
 336   // Creating new value by copying the one passed in argument
 337   instanceOop new_value = vklass->allocate_instance(
 338       CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 339   Handle new_value_h = Handle(THREAD, new_value);
 340   int first_offset = vklass->first_field_offset();
 341   vklass->value_store(vklass->data_for_oop(old_value_h()),
 342       vklass->data_for_oop(new_value_h()), true, false);
 343 
 344   // Updating the field specified in arguments
 345   if (field_type == T_ARRAY || field_type == T_OBJECT) {
 346     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 347     assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
 348     new_value_h()->obj_field_put(field_offset, aoop);
 349   } else if (field_type == T_VALUETYPE) {
 350     if (cp_entry->is_flattened()) {
 351       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 352       if (vt_oop == NULL) {
 353         THROW_(vmSymbols::java_lang_NullPointerException(),
 354             (type2size[field_type] * AbstractInterpreter::stackElementSize));
 355       }
 356       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 357       Klass* field_k = vklass->get_value_field_klass(field_index);
 358       ValueKlass* field_vk = ValueKlass::cast(field_k);
 359       assert(field_vk == vt_oop->klass(), "Must match");
 360       field_vk->value_store(field_vk->data_for_oop(vt_oop),
 361           ((char*)(oopDesc*)new_value_h()) + field_offset, false, false);
 362     } else { // not flattened
 363       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 364       if (voop == NULL && cp_entry->is_flattenable()) {
 365         THROW_(vmSymbols::java_lang_NullPointerException(),
 366             (type2size[field_type] * AbstractInterpreter::stackElementSize));
 367       }
 368       assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
 369       new_value_h()->obj_field_put(field_offset, voop);
 370     }
 371   } else { // not T_OBJECT nor T_ARRAY nor T_VALUETYPE
 372     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 373     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 374   }
 375 
 376   // returning result
 377   thread->set_vm_result(new_value_h());
 378   return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
 379 JRT_END
 380 
 381 JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))


 428 JRT_END
 429 
 430 JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
 431   instanceHandle obj_h(THREAD, (instanceOop)obj);
 432   InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
 433   Klass* field_k = klass->get_value_field_klass_or_null(index);
 434   assert(field_k != NULL, "Must have been initialized");
 435   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 436   assert(field_vklass->is_initialized(), "Must have been initialized at this point");
 437   instanceOop res = (instanceOop)field_vklass->default_value();
 438   thread->set_vm_result(res);
 439 JRT_END
 440 
 441 JRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
 442   assert(oopDesc::is_oop(value), "Sanity check");
 443   assert(oopDesc::is_oop(rcv), "Sanity check");
 444   assert(value->is_value(), "Sanity check");
 445 
 446   ValueKlass* vklass = ValueKlass::cast(value->klass());
 447   if (!vklass->is_empty_value()) {
 448     vklass->value_store(vklass->data_for_oop(value), ((char*)(oopDesc*)rcv) + offset, true, true);
 449   }
 450 JRT_END
 451 
 452 JRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
 453   Handle obj_h(THREAD, obj);
 454 
 455   assert(oopDesc::is_oop(obj), "Sanity check");
 456 
 457   assert(field_holder->is_instance_klass(), "Sanity check");
 458   InstanceKlass* klass = InstanceKlass::cast(field_holder);
 459 
 460   assert(klass->field_is_flattened(index), "Sanity check");
 461 
 462   ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
 463   assert(field_vklass->is_initialized(), "Must be initialized at this point");
 464 
 465   instanceOop res = NULL;
 466   if (field_vklass->is_empty_value()) {
 467     res = (instanceOop)field_vklass->default_value();
 468   } else {
 469     // allocate instance
 470     res = field_vklass->allocate_instance(CHECK);
 471     // copy value
 472     field_vklass->value_store(((char*)(oopDesc*)obj_h()) + klass->field_offset(index),
 473         field_vklass->data_for_oop(res), true, true);
 474   }
 475   assert(res != NULL, "Must be set in one of two paths above");
 476   thread->set_vm_result(res);
 477 JRT_END
 478 
 479 JRT_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 JRT_END
 483 
 484 
 485 JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 486   Klass*    klass = pool->klass_at(index, CHECK);
 487   bool      is_qtype_desc = pool->tag_at(index).is_Qdescriptor_klass();
 488   arrayOop obj;
 489   if ((!klass->is_array_klass()) && is_qtype_desc) { // Logically creates elements, ensure klass init
 490     klass->initialize(CHECK);
 491     obj = oopFactory::new_valueArray(klass, size, CHECK);
 492   } else {
 493     obj = oopFactory::new_objArray(klass, size, CHECK);
 494   }
 495   thread->set_vm_result(obj);
 496 JRT_END
 497 
 498 JRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 499   Klass* klass = array->klass();
 500   assert(klass->is_valueArray_klass(), "expected value array oop");
 501 
 502   ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 503   ValueKlass* vklass = vaklass->element_klass();
 504   arrayHandle ah(THREAD, array);
 505   instanceOop value_holder = NULL;
 506   if (vklass->is_empty_value()) {
 507     value_holder = (instanceOop)vklass->default_value();
 508   } else {
 509     value_holder = vklass->allocate_instance(CHECK);
 510     void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
 511     vklass->value_store(src, vklass->data_for_oop(value_holder),
 512         vaklass->element_byte_size(), true, false);
 513   }
 514   assert(value_holder != NULL, "Must be set in one of two paths above");
 515   thread->set_vm_result(value_holder);
 516 JRT_END
 517 
 518 JRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
 519   assert(val != NULL, "can't store null into flat array");
 520   Klass* klass = array->klass();
 521   assert(klass->is_valueArray_klass(), "expected value array");
 522   assert(ArrayKlass::cast(klass)->element_klass() == ((oop)val)->klass(), "Store type incorrect");
 523 
 524   valueArrayOop varray = (valueArrayOop)array;
 525   ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
 526   ValueKlass* vklass = vaklass->element_klass();
 527   if (!vklass->is_empty_value()) {
 528     const int lh = vaklass->layout_helper();
 529     vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
 530         vaklass->element_byte_size(), true, false);
 531   }
 532 JRT_END
 533 
 534 JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 535   // We may want to pass in more arguments - could make this slightly faster
 536   LastFrameAccessor last_frame(thread);
 537   ConstantPool* constants = last_frame.method()->constants();
 538   int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
 539   Klass* klass = constants->klass_at(i, CHECK);
 540   bool is_qtype = klass->name()->is_Q_array_signature();
 541   int   nof_dims = last_frame.number_of_dimensions();
 542   assert(klass->is_klass(), "not a class");
 543   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 544 
 545   if (is_qtype) { // Logically creates elements, ensure klass init
 546     klass->initialize(CHECK);
 547   }
 548 
 549   // We must create an array of jints to pass to multi_allocate.
 550   ResourceMark rm(thread);
 551   const int small_dims = 10;




  31 #include "compiler/compileBroker.hpp"
  32 #include "compiler/disassembler.hpp"
  33 #include "gc/shared/barrierSetNMethod.hpp"
  34 #include "gc/shared/collectedHeap.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "interpreter/interpreterRuntime.hpp"
  37 #include "interpreter/linkResolver.hpp"
  38 #include "interpreter/templateTable.hpp"
  39 #include "logging/log.hpp"
  40 #include "memory/oopFactory.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "oops/constantPool.hpp"
  44 #include "oops/cpCache.inline.hpp"
  45 #include "oops/instanceKlass.hpp"
  46 #include "oops/methodData.hpp"
  47 #include "oops/objArrayKlass.hpp"
  48 #include "oops/objArrayOop.inline.hpp"
  49 #include "oops/oop.inline.hpp"
  50 #include "oops/symbol.hpp"

  51 #include "oops/valueArrayKlass.hpp"

  52 #include "oops/valueArrayOop.inline.hpp"
  53 #include "oops/valueKlass.inline.hpp"
  54 #include "prims/jvmtiExport.hpp"
  55 #include "prims/nativeLookup.hpp"
  56 #include "runtime/atomic.hpp"
  57 #include "runtime/biasedLocking.hpp"
  58 #include "runtime/compilationPolicy.hpp"
  59 #include "runtime/deoptimization.hpp"
  60 #include "runtime/fieldDescriptor.inline.hpp"
  61 #include "runtime/frame.inline.hpp"
  62 #include "runtime/handles.inline.hpp"
  63 #include "runtime/icache.hpp"
  64 #include "runtime/interfaceSupport.inline.hpp"
  65 #include "runtime/java.hpp"
  66 #include "runtime/javaCalls.hpp"
  67 #include "runtime/jfieldIDWorkaround.hpp"
  68 #include "runtime/osThread.hpp"
  69 #include "runtime/sharedRuntime.hpp"
  70 #include "runtime/stubRoutines.hpp"
  71 #include "runtime/synchronizer.hpp"
  72 #include "runtime/threadCritical.hpp"
  73 #include "utilities/align.hpp"


 319   int offset = cp_entry->f2_as_index();
 320   int field_index = cp_entry->field_index();
 321   int field_offset = cp_entry->f2_as_offset();
 322   Symbol* field_signature = vklass->field_signature(field_index);
 323   ResourceMark rm(THREAD);
 324   const char* signature = (const char *) field_signature->as_utf8();
 325   BasicType field_type = char2type(signature[0]);
 326 
 327   // Getting old value
 328   frame& f = last_frame.get_frame();
 329   jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
 330   int vt_offset = type2size[field_type];
 331   oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
 332   assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
 333   Handle old_value_h(THREAD, old_value);
 334 
 335   // Creating new value by copying the one passed in argument
 336   instanceOop new_value = vklass->allocate_instance(
 337       CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
 338   Handle new_value_h = Handle(THREAD, new_value);
 339   vklass->value_copy_oop_to_new_oop(old_value_h(), new_value_h());


 340 
 341   // Updating the field specified in arguments
 342   if (field_type == T_ARRAY || field_type == T_OBJECT) {
 343     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 344     assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
 345     new_value_h()->obj_field_put(field_offset, aoop);
 346   } else if (field_type == T_VALUETYPE) {
 347     if (cp_entry->is_flattened()) {
 348       oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 349       if (vt_oop == NULL) {
 350         THROW_(vmSymbols::java_lang_NullPointerException(),
 351             (type2size[field_type] * AbstractInterpreter::stackElementSize));
 352       }
 353       assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 354       Klass* field_k = vklass->get_value_field_klass(field_index);
 355       ValueKlass* field_vk = ValueKlass::cast(field_k);
 356       assert(field_vk == vt_oop->klass(), "Must match");
 357       field_vk->value_copy_oop_to_new_payload(vt_oop, ((char*)(oopDesc*)new_value_h()) + field_offset);

 358     } else { // not flattened
 359       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 360       if (voop == NULL && cp_entry->is_flattenable()) {
 361         THROW_(vmSymbols::java_lang_NullPointerException(),
 362             (type2size[field_type] * AbstractInterpreter::stackElementSize));
 363       }
 364       assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
 365       new_value_h()->obj_field_put(field_offset, voop);
 366     }
 367   } else { // not T_OBJECT nor T_ARRAY nor T_VALUETYPE
 368     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
 369     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
 370   }
 371 
 372   // returning result
 373   thread->set_vm_result(new_value_h());
 374   return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
 375 JRT_END
 376 
 377 JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))


 424 JRT_END
 425 
 426 JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
 427   instanceHandle obj_h(THREAD, (instanceOop)obj);
 428   InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
 429   Klass* field_k = klass->get_value_field_klass_or_null(index);
 430   assert(field_k != NULL, "Must have been initialized");
 431   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 432   assert(field_vklass->is_initialized(), "Must have been initialized at this point");
 433   instanceOop res = (instanceOop)field_vklass->default_value();
 434   thread->set_vm_result(res);
 435 JRT_END
 436 
 437 JRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
 438   assert(oopDesc::is_oop(value), "Sanity check");
 439   assert(oopDesc::is_oop(rcv), "Sanity check");
 440   assert(value->is_value(), "Sanity check");
 441 
 442   ValueKlass* vklass = ValueKlass::cast(value->klass());
 443   if (!vklass->is_empty_value()) {
 444     vklass->value_copy_oop_to_payload(value, ((char*)(oopDesc*)rcv) + offset);
 445   }
 446 JRT_END
 447 
 448 JRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
 449   Handle obj_h(THREAD, obj);
 450 
 451   assert(oopDesc::is_oop(obj), "Sanity check");
 452 
 453   assert(field_holder->is_instance_klass(), "Sanity check");
 454   InstanceKlass* klass = InstanceKlass::cast(field_holder);
 455 
 456   assert(klass->field_is_flattened(index), "Sanity check");
 457 
 458   ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
 459   assert(field_vklass->is_initialized(), "Must be initialized at this point");
 460 
 461   instanceOop res = NULL;
 462   if (field_vklass->is_empty_value()) {
 463     res = (instanceOop)field_vklass->default_value();
 464   } else {

 465     res = field_vklass->allocate_instance(CHECK);
 466     field_vklass->value_copy_payload_to_new_oop(((char*)(oopDesc*)obj_h()) + klass->field_offset(index), res);


 467   }
 468   assert(res != NULL, "Must be set in one of two paths above");
 469   thread->set_vm_result(res);
 470 JRT_END
 471 
 472 JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
 473   oop obj = oopFactory::new_typeArray(type, size, CHECK);
 474   thread->set_vm_result(obj);
 475 JRT_END
 476 
 477 
 478 JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
 479   Klass*    klass = pool->klass_at(index, CHECK);
 480   bool      is_qtype_desc = pool->tag_at(index).is_Qdescriptor_klass();
 481   arrayOop obj;
 482   if ((!klass->is_array_klass()) && is_qtype_desc) { // Logically creates elements, ensure klass init
 483     klass->initialize(CHECK);
 484     obj = oopFactory::new_valueArray(klass, size, CHECK);
 485   } else {
 486     obj = oopFactory::new_objArray(klass, size, CHECK);
 487   }
 488   thread->set_vm_result(obj);
 489 JRT_END
 490 
 491 JRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
 492   valueArrayHandle vah(thread, (valueArrayOop)array);
 493   oop value_holder = valueArrayOopDesc::value_copy_from_index(vah, index, CHECK);














 494   thread->set_vm_result(value_holder);
 495 JRT_END
 496 
 497 JRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
 498   assert(val != NULL, "can't store null into flat array");
 499   ((valueArrayOop)array)->value_copy_to_index((oop)val, index);











 500 JRT_END
 501 
 502 JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
 503   // We may want to pass in more arguments - could make this slightly faster
 504   LastFrameAccessor last_frame(thread);
 505   ConstantPool* constants = last_frame.method()->constants();
 506   int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
 507   Klass* klass = constants->klass_at(i, CHECK);
 508   bool is_qtype = klass->name()->is_Q_array_signature();
 509   int   nof_dims = last_frame.number_of_dimensions();
 510   assert(klass->is_klass(), "not a class");
 511   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 512 
 513   if (is_qtype) { // Logically creates elements, ensure klass init
 514     klass->initialize(CHECK);
 515   }
 516 
 517   // We must create an array of jints to pass to multi_allocate.
 518   ResourceMark rm(thread);
 519   const int small_dims = 10;


< prev index next >