< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page

        

*** 70,79 **** --- 70,82 ---- #include "utilities/events.hpp" #include "utilities/globalDefinitions.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif + #if INCLUDE_ALL_GCS + #include "gc/g1/g1SATBCardTableModRefBS.hpp" + #endif // INCLUDE_ALL_GCS class UnlockFlagSaver { private: JavaThread* _thread; bool _do_not_unlock;
*** 262,285 **** // Updating the field specified in arguments if (field_type == T_OBJECT || field_type == T_ARRAY) { oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type"); new_value_h()->obj_field_put(field_offset, aoop); } else if (field_type == T_VALUETYPE) { if (cp_entry->is_flatten()) { Klass* field_k = vklass->get_value_field_klass(field_index); ValueKlass* field_vk = ValueKlass::cast(field_k); oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); assert(field_vk == vt_oop->klass(), "Must match"); field_vk->value_store(field_vk->data_for_oop(vt_oop), ! ((char*)(oopDesc*)new_value_h()) + field_offset, true, false); } else { oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type"); new_value_h()->obj_field_put(field_offset, voop); } } else { intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); copy_primitive_argument(addr, new_value_h, field_offset, field_type); } --- 265,327 ---- // Updating the field specified in arguments if (field_type == T_OBJECT || field_type == T_ARRAY) { oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type"); + if (in_heap) { new_value_h()->obj_field_put(field_offset, aoop); + } else { + if (UseG1GC) { + if (aoop != NULL) { + G1SATBCardTableModRefBS::enqueue(aoop); + } + oop old = new_value_h()->obj_field_acquire(field_offset); + if (old != NULL) { + G1SATBCardTableModRefBS::enqueue(old); + } + } + new_value_h()->obj_field_put_raw(field_offset, aoop); + } } else if (field_type == T_VALUETYPE) { if (cp_entry->is_flatten()) { Klass* field_k = vklass->get_value_field_klass(field_index); ValueKlass* field_vk = ValueKlass::cast(field_k); oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); assert(field_vk == vt_oop->klass(), "Must match"); field_vk->value_store(field_vk->data_for_oop(vt_oop), ! ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false); } else { oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type"); + if (VTBuffer::is_in_vt_buffer(voop)) { + // new value field is currently allocated in a TLVB, a heap allocated + // copy must be created because a field must never point to a TLVB allocated value + Handle voop_h = Handle(THREAD, voop); + ValueKlass* field_vk = ValueKlass::cast(voop->klass()); + assert(field_vk == vklass->get_value_field_klass(field_index), "Sanity check"); + instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); + Handle field_copy_h = Handle(THREAD, field_copy); + field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false); + if (in_heap) { + new_value_h()->obj_field_put(field_offset, field_copy_h()); + } else { + new_value_h()->obj_field_put_raw(field_offset, field_copy_h()); + if (UseG1GC) { + G1SATBCardTableModRefBS::enqueue(field_copy_h()); + } + } + } else { + if (in_heap) { new_value_h()->obj_field_put(field_offset, voop); + } else { + new_value_h()->obj_field_put_raw(field_offset, voop); + if (UseG1GC) { + G1SATBCardTableModRefBS::enqueue(voop); + } + } + } } } else { intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); copy_primitive_argument(addr, new_value_h, field_offset, field_type); }
*** 356,368 **** --- 398,414 ---- thread->set_vm_result(res_h()); } else { oop res = value_h()->obj_field_acquire(klass->field_offset(index)); if (res == NULL) { res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); + } else { + assert(res->klass() == field_k, "Sanity check"); + assert(!VTBuffer::is_in_vt_buffer(res), "Sanity check"); } thread->set_vm_result(res); } + assert(thread->vm_result()->klass() == field_vklass, "sanity check"); IRT_END IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index)) instanceHandle mirror_h(THREAD, (instanceOop)mirror); InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
*** 400,416 **** bool flatten = cp_entry->is_flatten(); InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass()); Klass* field_k = klass->get_value_field_klass(index); ValueKlass* field_vklass = ValueKlass::cast(value->klass()); assert(field_k == field_vklass, "Field descriptor and argument must match"); if (flatten) { // copy value field_vklass->value_store(field_vklass->data_for_oop(value_h()), ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false); } else { ! if (Universe::heap()->is_in_reserved(value_h())) { obj_h()->obj_field_put(klass->field_offset(index), value_h()); } else { // allocate heap instance instanceOop val = field_vklass->allocate_instance(CHECK); instanceHandle res_h(THREAD, val); --- 446,463 ---- bool flatten = cp_entry->is_flatten(); InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass()); Klass* field_k = klass->get_value_field_klass(index); ValueKlass* field_vklass = ValueKlass::cast(value->klass()); + assert(value_h()->klass() == field_k, "Sanity check"); assert(field_k == field_vklass, "Field descriptor and argument must match"); if (flatten) { // copy value field_vklass->value_store(field_vklass->data_for_oop(value_h()), ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false); } else { ! if (!VTBuffer::is_in_vt_buffer(value_h())) { obj_h()->obj_field_put(klass->field_offset(index), value_h()); } else { // allocate heap instance instanceOop val = field_vklass->allocate_instance(CHECK); instanceHandle res_h(THREAD, val);
*** 425,435 **** IRT_END IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror)) instanceHandle value_h(THREAD, (instanceOop)value); assert(value_h()->is_value(), "qputstatic only deals with value arguments"); ! if (Universe::heap()->is_in_reserved(value_h())) { mirror->obj_field_put(offset, value_h()); } else { // The argument is a buffered value, a copy must be created in the Java heap // because a static field cannot point to a thread-local buffered value ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass()); --- 472,482 ---- IRT_END IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror)) instanceHandle value_h(THREAD, (instanceOop)value); assert(value_h()->is_value(), "qputstatic only deals with value arguments"); ! if (!VTBuffer::is_in_vt_buffer(value_h())) { mirror->obj_field_put(offset, value_h()); } else { // The argument is a buffered value, a copy must be created in the Java heap // because a static field cannot point to a thread-local buffered value ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
*** 466,477 **** Klass* klass = array->klass(); assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop"); if (klass->is_objArray_klass()) { thread->set_vm_result(((objArrayOop) array)->obj_at(index)); ! } ! else { ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); ValueKlass* vklass = vaklass->element_klass(); arrayHandle ah(THREAD, array); bool in_heap; instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); --- 513,523 ---- Klass* klass = array->klass(); assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop"); if (klass->is_objArray_klass()) { thread->set_vm_result(((objArrayOop) array)->obj_at(index)); ! } else { ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); ValueKlass* vklass = vaklass->element_klass(); arrayHandle ah(THREAD, array); bool in_heap; instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
*** 483,498 **** IRT_END IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val)) Klass* klass = array->klass(); assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop"); if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) { THROW(vmSymbols::java_lang_ArrayStoreException()); } if (klass->is_objArray_klass()) { ! if(!Universe::heap()->is_in_reserved(val)) { // A Java heap allocated copy must be made because an array cannot // reference a thread-local buffered value Handle val_h(THREAD, (oop)val); ObjArrayKlass* aklass = ObjArrayKlass::cast(klass); Klass* eklass = aklass->element_klass(); --- 529,545 ---- IRT_END IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val)) Klass* klass = array->klass(); assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop"); + Handle array_h(THREAD, array); if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) { THROW(vmSymbols::java_lang_ArrayStoreException()); } if (klass->is_objArray_klass()) { ! if(VTBuffer::is_in_vt_buffer(val)) { // A Java heap allocated copy must be made because an array cannot // reference a thread-local buffered value Handle val_h(THREAD, (oop)val); ObjArrayKlass* aklass = ObjArrayKlass::cast(klass); Klass* eklass = aklass->element_klass();
*** 505,515 **** // copy value vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(), ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false); val = res_h(); } ! ((objArrayOop) array)->obj_at_put(index, (oop)val); } else { valueArrayOop varray = (valueArrayOop)array; ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); ValueKlass* vklass = vaklass->element_klass(); const int lh = vaklass->layout_helper(); --- 552,562 ---- // copy value vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(), ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false); val = res_h(); } ! ((objArrayOop) array_h())->obj_at_put(index, (oop)val); } else { valueArrayOop varray = (valueArrayOop)array; ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); ValueKlass* vklass = vaklass->element_klass(); const int lh = vaklass->layout_helper();
*** 546,557 **** } oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK); thread->set_vm_result(obj); IRT_END ! IRT_ENTRY(void, InterpreterRuntime::recycle_vtbuffer(JavaThread* thread)) ! VTBuffer::recycle_vtbuffer(thread, last_frame(thread)); IRT_END IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread)) frame f = thread->last_frame(); assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames"); --- 593,605 ---- } oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK); thread->set_vm_result(obj); IRT_END ! IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr)) ! JavaThread* thread = (JavaThread*)Thread::current(); ! VTBuffer::recycle_vtbuffer(thread, alloc_ptr); IRT_END IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread)) frame f = thread->last_frame(); assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
*** 562,572 **** frame f = thread->last_frame(); VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr())); IRT_END IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj)) ! if (Universe::heap()->is_in_reserved(obj)) { thread->set_vm_result(obj); return; } assert(obj->klass()->is_value(), "Sanity check"); ValueKlass* vk = ValueKlass::cast(obj->klass()); --- 610,620 ---- frame f = thread->last_frame(); VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr())); IRT_END IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj)) ! if (!VTBuffer::is_in_vt_buffer(obj)) { thread->set_vm_result(obj); return; } assert(obj->klass()->is_value(), "Sanity check"); ValueKlass* vk = ValueKlass::cast(obj->klass());
*** 582,596 **** vk->value_store(vk->data_for_oop(obj_h()), vk->data_for_oop(res_h()), true, false); thread->set_vm_result(res_h()); return; } else { ! oop dest = VTBuffer::relocate_return_value(thread, current_frame, obj); ! thread->set_vm_result(dest); } IRT_END IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj)) if (obj != NULL) { Klass* k = obj->klass(); if (k->is_value()) { ResourceMark rm(thread); --- 630,660 ---- vk->value_store(vk->data_for_oop(obj_h()), vk->data_for_oop(res_h()), true, false); thread->set_vm_result(res_h()); return; } else { ! // A buffered value is being returned to an interpreted frame, ! // but the work has to be delayed to remove_activation() because ! // the frame cannot be modified now (GC can run at the safepoint ! // when exiting runtime, and frame layout must be kept consistent ! // with the OopMap). ! thread->set_return_buffered_value(obj); ! thread->set_vm_result(obj); } IRT_END + IRT_LEAF(void, InterpreterRuntime::return_value_step2(oopDesc* obj, void* alloc_ptr)) + + JavaThread* thread = (JavaThread*)Thread::current(); + assert(obj == thread->return_buffered_value(), "Consistency check"); + assert(!Universe::heap()->is_in_reserved(obj), "Should only apply to buffered values"); + + oop dest = VTBuffer::relocate_return_value(thread, alloc_ptr, obj); + thread->set_return_buffered_value(NULL); + thread->set_vm_result(dest); + IRT_END + IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj)) if (obj != NULL) { Klass* k = obj->klass(); if (k->is_value()) { ResourceMark rm(thread);
< prev index next >