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(fd.offset(), aoop);
268 } else if (field_type == T_VALUETYPE) {
269 Klass* field_k = vklass->get_value_field_klass(fd.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()) + fd.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, fd.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 offset))
334 Handle value_h(THREAD, value);
335 InstanceKlass* klass = InstanceKlass::cast(value->klass());
336
337 fieldDescriptor fd;
338 klass->find_field_from_offset(offset, false, &fd);
339 Klass* field_k = klass->get_value_field_klass(fd.index());
340 ValueKlass* field_vklass = ValueKlass::cast(field_k);
341 field_vklass->initialize(THREAD);
342
343 // allocate instance
344 bool in_heap;
345 instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
346 instanceHandle res_h(THREAD, res);
347 // copy value
348 field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset,
349 field_vklass->data_for_oop(res), in_heap, false);
350 thread->set_vm_result(res_h());
351 IRT_END
352
353 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int offset))
354 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
355 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
356 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
357
358 fieldDescriptor fd;
359 klass->find_field_from_offset(offset, true, &fd);
360 Klass* field_k = klass->get_value_field_klass(fd.index());
361 ValueKlass* field_vklass = ValueKlass::cast(field_k);
362 // allocate instance, because it is going to be assigned to a static field
363 // it must not be a buffered value
364 instanceOop res = field_vklass->allocate_instance(CHECK);
365 instanceHandle res_h(THREAD, res);
366 mirror_h()->obj_field_put(offset, res_h());
367 thread->set_vm_result(res_h());
368 IRT_END
369
370 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int offset))
371 Handle value_h(THREAD, value);
372 Handle obj_h(THREAD, obj);
373 assert(!obj_h()->klass()->is_value(), "obj must be an object");
374 assert(value_h()->klass()->is_value(), "value must be an value type");
375
376 InstanceKlass* klass = InstanceKlass::cast(obj->klass());
377 fieldDescriptor fd;
378 klass->find_field_from_offset(offset, false, &fd);
379 Klass* field_k = klass->get_value_field_klass(fd.index());
380 ValueKlass* field_vklass = ValueKlass::cast(value->klass());
381 assert(field_k == field_vklass, "Field descriptor and argument must match");
382 // copy value
383 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
384 ((char*)(oopDesc*)obj_h()) + offset, true, false);
385 IRT_END
386
387 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value))
388 instanceHandle value_h(THREAD, (instanceOop)value);
389 assert(value_h()->is_value(), "qputstatic only deals with value arguments");
390 Method* m = last_frame(thread).interpreter_frame_method();
391 jint bci = last_frame(thread).interpreter_frame_bci();
392 assert(m->code_at(bci) == Bytecodes::_putstatic, "qputstatic is a particular case of putstatic");
393 ConstantPoolCache* cp_cache = last_frame(thread).interpreter_frame_method()->constants()->cache();
394 int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putstatic));
395 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index);
396 assert(cp_entry->is_field_entry(), "Sanity check");
397
398 InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
399 int offset = cp_entry->f2_as_index();
400 oop mirror = klass->java_mirror();
401
402 if (Universe::heap()->is_in_reserved(value_h())) {
403 mirror->obj_field_put(offset, value_h());
404 } else {
978 get_code = Bytecodes::_getstatic;
979 } else {
980 get_code = Bytecodes::_getfield;
981 }
982 if (is_put && is_value) {
983 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_vwithfield);
984 } else if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
985 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
986 }
987 }
988
989 cp_cache_entry->set_field(
990 get_code,
991 put_code,
992 info.field_holder(),
993 info.index(),
994 info.offset(),
995 state,
996 info.access_flags().is_final(),
997 info.access_flags().is_volatile(),
998 pool->pool_holder()
999 );
1000 }
1001
1002
1003 //------------------------------------------------------------------------------------------------------------------------
1004 // Synchronization
1005 //
1006 // The interpreter's synchronization code is factored out so that it can
1007 // be shared by method invocation and synchronized blocks.
1008 //%note synchronization_3
1009
1010 //%note monitor_1
1011 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
1012 #ifdef ASSERT
1013 thread->last_frame().interpreter_frame_verify_monitor(elem);
1014 #endif
1015 if (PrintBiasedLockingStatistics) {
1016 Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
1017 }
|
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(fd.offset(), aoop);
268 } else if (field_type == T_VALUETYPE) {
269 if (fd.is_flatten()) {
270 Klass* field_k = vklass->get_value_field_klass(fd.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()) + fd.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(fd.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, fd.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 offset))
340 Handle value_h(THREAD, obj);
341 InstanceKlass* klass = InstanceKlass::cast(obj->klass());
342
343 fieldDescriptor fd;
344 klass->find_field_from_offset(offset, false, &fd);
345 Klass* field_k = klass->get_value_field_klass(fd.index());
346 ValueKlass* field_vklass = ValueKlass::cast(field_k);
347 field_vklass->initialize(THREAD);
348
349 instanceOop res;
350 bool in_heap;
351 if (fd.is_flatten()) {
352 // allocate instance
353 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
354 instanceHandle res_h(THREAD, res);
355 // copy value
356 field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset,
357 field_vklass->data_for_oop(res), in_heap, false);
358 thread->set_vm_result(res_h());
359 } else {
360 oop res = value_h()->obj_field_acquire(offset);
361 if (res == NULL) {
362 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
363 }
364 thread->set_vm_result(res);
365 }
366 IRT_END
367
368 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int offset))
369 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
370 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
371 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
372
373 fieldDescriptor fd;
374 klass->find_field_from_offset(offset, true, &fd);
375 Klass* field_k = klass->get_value_field_klass(fd.index());
376 ValueKlass* field_vklass = ValueKlass::cast(field_k);
377 // allocate instance, because it is going to be assigned to a static field
378 // it must not be a buffered value
379 instanceOop res = field_vklass->allocate_instance(CHECK);
380 instanceHandle res_h(THREAD, res);
381 mirror_h()->obj_field_put(offset, res_h());
382 thread->set_vm_result(res_h());
383 IRT_END
384
385 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int offset))
386 Handle value_h(THREAD, value);
387 Handle obj_h(THREAD, obj);
388 assert(!obj_h()->klass()->is_value(), "obj must be an object");
389 assert(value_h()->klass()->is_value(), "value must be an value type");
390
391 InstanceKlass* klass = InstanceKlass::cast(obj->klass());
392 fieldDescriptor fd;
393 klass->find_field_from_offset(offset, false, &fd);
394 Klass* field_k = klass->get_value_field_klass(fd.index());
395 ValueKlass* field_vklass = ValueKlass::cast(value->klass());
396 assert(field_k == field_vklass, "Field descriptor and argument must match");
397 if (fd.is_flatten()) {
398 // copy value
399 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
400 ((char*)(oopDesc*)obj_h()) + offset, true, false);
401 } else {
402 if (Universe::heap()->is_in_reserved(value_h())) {
403 obj_h()->obj_field_put(offset, value_h());
404 } else {
405 // allocate heap instance
406 instanceOop val = field_vklass->allocate_instance(CHECK);
407 instanceHandle res_h(THREAD, val);
408 // copy value
409 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
410 field_vklass->data_for_oop(res_h()), true, false);
411
412
413 obj_h()->obj_field_put(offset, res_h());
414 }
415 }
416 IRT_END
417
418 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value))
419 instanceHandle value_h(THREAD, (instanceOop)value);
420 assert(value_h()->is_value(), "qputstatic only deals with value arguments");
421 Method* m = last_frame(thread).interpreter_frame_method();
422 jint bci = last_frame(thread).interpreter_frame_bci();
423 assert(m->code_at(bci) == Bytecodes::_putstatic, "qputstatic is a particular case of putstatic");
424 ConstantPoolCache* cp_cache = last_frame(thread).interpreter_frame_method()->constants()->cache();
425 int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putstatic));
426 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index);
427 assert(cp_entry->is_field_entry(), "Sanity check");
428
429 InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
430 int offset = cp_entry->f2_as_index();
431 oop mirror = klass->java_mirror();
432
433 if (Universe::heap()->is_in_reserved(value_h())) {
434 mirror->obj_field_put(offset, value_h());
435 } else {
1009 get_code = Bytecodes::_getstatic;
1010 } else {
1011 get_code = Bytecodes::_getfield;
1012 }
1013 if (is_put && is_value) {
1014 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_vwithfield);
1015 } else if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
1016 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
1017 }
1018 }
1019
1020 cp_cache_entry->set_field(
1021 get_code,
1022 put_code,
1023 info.field_holder(),
1024 info.index(),
1025 info.offset(),
1026 state,
1027 info.access_flags().is_final(),
1028 info.access_flags().is_volatile(),
1029 info.is_flatten(),
1030 pool->pool_holder()
1031 );
1032 }
1033
1034
1035 //------------------------------------------------------------------------------------------------------------------------
1036 // Synchronization
1037 //
1038 // The interpreter's synchronization code is factored out so that it can
1039 // be shared by method invocation and synchronized blocks.
1040 //%note synchronization_3
1041
1042 //%note monitor_1
1043 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
1044 #ifdef ASSERT
1045 thread->last_frame().interpreter_frame_verify_monitor(elem);
1046 #endif
1047 if (PrintBiasedLockingStatistics) {
1048 Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
1049 }
|