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 }
|