< prev index next >

src/share/vm/interpreter/interpreterRuntime.cpp

Print this page




 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     Klass* field_k = vklass->get_value_field_klass(field_index);
 270     ValueKlass* field_vk = ValueKlass::cast(field_k);
 271     oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
 272     assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
 273     assert(field_vk == vt_oop->klass(), "Must match");
 274     field_vk->value_store(field_vk->data_for_oop(vt_oop),
 275         ((char*)(oopDesc*)new_value_h()) + field_offset, true, false);
 276   } else {





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


 313   if (obj == NULL) {
 314     THROW(vmSymbols::java_lang_NullPointerException());
 315   }
 316   Klass* target_klass = pool->klass_at(index, CHECK);
 317   if (!target_klass->is_value()) {
 318     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not value type");
 319   }
 320   Klass* klass = obj->klass();
 321   if ((!klass->is_instance_klass()) || klass->is_value()) {
 322     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance");
 323   }
 324     if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) {
 325     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type");
 326   }
 327   oop value = ValueKlass::cast(target_klass)->unbox(Handle(THREAD, obj),
 328                                                 InstanceKlass::cast(target_klass),
 329                                                 CHECK);
 330   thread->set_vm_result(value);
 331 IRT_END
 332 
 333 IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* value, int index))
 334   Handle value_h(THREAD, value);
 335   InstanceKlass* klass = InstanceKlass::cast(value->klass());
 336 
 337   Klass* field_k = klass->get_value_field_klass(index);
 338   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 339   field_vklass->initialize(THREAD);
 340 
 341   // allocate instance
 342   bool in_heap;
 343   instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);


 344   instanceHandle res_h(THREAD, res);
 345   // copy value
 346   field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index),
 347                             field_vklass->data_for_oop(res), in_heap, false);
 348   thread->set_vm_result(res_h());







 349 IRT_END
 350 
 351 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
 352   instanceHandle mirror_h(THREAD, (instanceOop)mirror);
 353   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
 354   int offset = klass->field_offset(index);
 355   assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
 356 
 357   Klass* field_k = klass->get_value_field_klass(index);
 358   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 359   // allocate instance, because it is going to be assigned to a static field
 360   // it must not be a buffered value
 361   instanceOop res = field_vklass->allocate_instance(CHECK);
 362   instanceHandle res_h(THREAD, res);
 363   mirror_h()->obj_field_put(offset, res_h());
 364   thread->set_vm_result(res_h());
 365 IRT_END
 366 
 367 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int flags))
 368   Handle value_h(THREAD, value);
 369   Handle obj_h(THREAD, obj);
 370   assert(!obj_h()->klass()->is_value(), "obj must be an object");
 371   assert(value_h()->klass()->is_value(), "value must be an value type");
 372   int index = flags & ConstantPoolCacheEntry::field_index_mask;

 373 
 374   InstanceKlass* klass = InstanceKlass::cast(obj->klass());
 375   Klass* field_k = klass->get_value_field_klass(index);
 376   ValueKlass* field_vklass = ValueKlass::cast(value->klass());
 377   assert(field_k == field_vklass, "Field descriptor and argument must match");

 378   // copy value
 379   field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 380                             ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);















 381 IRT_END
 382 
 383 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
 384   instanceHandle value_h(THREAD, (instanceOop)value);
 385   assert(value_h()->is_value(), "qputstatic only deals with value arguments");
 386   if (Universe::heap()->is_in_reserved(value_h())) {
 387       mirror->obj_field_put(offset, value_h());
 388   } else {
 389     // The argument is a buffered value, a copy must be created in the Java heap
 390     // because a static field cannot point to a thread-local buffered value
 391     ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
 392     Handle mirror_h(THREAD, mirror);
 393     // allocate heap instance
 394     instanceOop res = field_vklass->allocate_instance(CHECK);
 395     assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
 396     instanceHandle res_h(THREAD, res);
 397     // copy value
 398     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 399                               field_vklass->data_for_oop(res), true, false);
 400     // writing static field


 959       get_code = Bytecodes::_getstatic;
 960     } else {
 961       get_code = Bytecodes::_getfield;
 962     }
 963     if (is_put && is_value) {
 964         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_vwithfield);
 965     } else if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
 966         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
 967     }
 968   }
 969 
 970   cp_cache_entry->set_field(
 971     get_code,
 972     put_code,
 973     info.field_holder(),
 974     info.index(),
 975     info.offset(),
 976     state,
 977     info.access_flags().is_final(),
 978     info.access_flags().is_volatile(),

 979     pool->pool_holder()
 980   );
 981 }
 982 
 983 
 984 //------------------------------------------------------------------------------------------------------------------------
 985 // Synchronization
 986 //
 987 // The interpreter's synchronization code is factored out so that it can
 988 // be shared by method invocation and synchronized blocks.
 989 //%note synchronization_3
 990 
 991 //%note monitor_1
 992 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
 993 #ifdef ASSERT
 994   thread->last_frame().interpreter_frame_verify_monitor(elem);
 995 #endif
 996   if (PrintBiasedLockingStatistics) {
 997     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
 998   }




 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()) {
 301     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vbox target is value type");
 302   }


 319   if (obj == NULL) {
 320     THROW(vmSymbols::java_lang_NullPointerException());
 321   }
 322   Klass* target_klass = pool->klass_at(index, CHECK);
 323   if (!target_klass->is_value()) {
 324     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not value type");
 325   }
 326   Klass* klass = obj->klass();
 327   if ((!klass->is_instance_klass()) || klass->is_value()) {
 328     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance");
 329   }
 330     if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) {
 331     THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type");
 332   }
 333   oop value = ValueKlass::cast(target_klass)->unbox(Handle(THREAD, obj),
 334                                                 InstanceKlass::cast(target_klass),
 335                                                 CHECK);
 336   thread->set_vm_result(value);
 337 IRT_END
 338 
 339 IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* obj, int index))
 340   Handle value_h(THREAD, obj);
 341   InstanceKlass* klass = InstanceKlass::cast(obj->klass());
 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(index);
 373   ValueKlass* field_vklass = ValueKlass::cast(field_k);
 374   // allocate instance, because it is going to be assigned to a static field
 375   // it must not be a buffered value
 376   instanceOop res = field_vklass->allocate_instance(CHECK);
 377   instanceHandle res_h(THREAD, res);
 378   mirror_h()->obj_field_put(offset, res_h());
 379   thread->set_vm_result(res_h());
 380 IRT_END
 381 
 382 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int flags))
 383   Handle value_h(THREAD, value);
 384   Handle obj_h(THREAD, obj);
 385   assert(!obj_h()->klass()->is_value(), "obj must be an object");
 386   assert(value_h()->klass()->is_value(), "value must be an value type");
 387   int index = flags & ConstantPoolCacheEntry::field_index_mask;
 388   bool flatten = (flags & (1 << ConstantPoolCacheEntry::is_flatten_field)) != 0;
 389 
 390   InstanceKlass* klass = InstanceKlass::cast(obj->klass());
 391   Klass* field_k = klass->get_value_field_klass(index);
 392   ValueKlass* field_vklass = ValueKlass::cast(value->klass());
 393   assert(field_k == field_vklass, "Field descriptor and argument must match");
 394   if (flatten) {
 395     // copy value
 396     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 397                               ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);
 398   } else {
 399     if (Universe::heap()->is_in_reserved(value_h())) {
 400       obj_h()->obj_field_put(klass->field_offset(index), value_h());
 401     } else {
 402       // allocate heap instance
 403       instanceOop val = field_vklass->allocate_instance(CHECK);
 404       instanceHandle res_h(THREAD, val);
 405       // copy value
 406       field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 407                                 field_vklass->data_for_oop(res_h()), true, false);
 408 
 409 
 410       obj_h()->obj_field_put(klass->field_offset(index), res_h());
 411     }
 412   }
 413 IRT_END
 414 
 415 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
 416   instanceHandle value_h(THREAD, (instanceOop)value);
 417   assert(value_h()->is_value(), "qputstatic only deals with value arguments");
 418   if (Universe::heap()->is_in_reserved(value_h())) {
 419       mirror->obj_field_put(offset, value_h());
 420   } else {
 421     // The argument is a buffered value, a copy must be created in the Java heap
 422     // because a static field cannot point to a thread-local buffered value
 423     ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
 424     Handle mirror_h(THREAD, mirror);
 425     // allocate heap instance
 426     instanceOop res = field_vklass->allocate_instance(CHECK);
 427     assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
 428     instanceHandle res_h(THREAD, res);
 429     // copy value
 430     field_vklass->value_store(field_vklass->data_for_oop(value_h()),
 431                               field_vklass->data_for_oop(res), true, false);
 432     // writing static field


 991       get_code = Bytecodes::_getstatic;
 992     } else {
 993       get_code = Bytecodes::_getfield;
 994     }
 995     if (is_put && is_value) {
 996         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_vwithfield);
 997     } else if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
 998         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
 999     }
1000   }
1001 
1002   cp_cache_entry->set_field(
1003     get_code,
1004     put_code,
1005     info.field_holder(),
1006     info.index(),
1007     info.offset(),
1008     state,
1009     info.access_flags().is_final(),
1010     info.access_flags().is_volatile(),
1011     info.is_flatten(),
1012     pool->pool_holder()
1013   );
1014 }
1015 
1016 
1017 //------------------------------------------------------------------------------------------------------------------------
1018 // Synchronization
1019 //
1020 // The interpreter's synchronization code is factored out so that it can
1021 // be shared by method invocation and synchronized blocks.
1022 //%note synchronization_3
1023 
1024 //%note monitor_1
1025 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
1026 #ifdef ASSERT
1027   thread->last_frame().interpreter_frame_verify_monitor(elem);
1028 #endif
1029   if (PrintBiasedLockingStatistics) {
1030     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
1031   }


< prev index next >