< prev index next >

src/share/vm/interpreter/interpreterRuntime.cpp

Print this page

        

*** 36,45 **** --- 36,46 ---- #include "interpreter/templateTable.hpp" #include "logging/log.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" + #include "memory/vtBuffer.hpp" #include "oops/constantPool.hpp" #include "oops/instanceKlass.hpp" #include "oops/methodData.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp"
*** 191,201 **** break; case T_INT: instance()->int_field_put(offset, (jint)*((int*)addr)); break; case T_LONG: ! instance()->long_field_put(offset, (jlong)*((long*)addr)); // Is it correct on 32 and 64 bits? break; case T_OBJECT: case T_ARRAY: case T_VALUETYPE: fatal("Should not be handled with this method"); --- 192,202 ---- break; case T_INT: instance()->int_field_put(offset, (jint)*((int*)addr)); break; case T_LONG: ! instance()->long_field_put(offset, (jlong)*((long long*)addr)); break; case T_OBJECT: case T_ARRAY: case T_VALUETYPE: fatal("Should not be handled with this method");
*** 212,229 **** ValueKlass* vklass = ValueKlass::cast(k); vklass->initialize(THREAD); // Creating value ! instanceOop value = vklass->allocate_instance(CHECK); Handle value_h = Handle(THREAD, value); - // Zeroing, already performed by allocate_instance() when allocating in the Java Heap - // Might need to be performed manually for off-heap allocations - // memset(((char*)(oopDesc*)value) + vklass_h->first_field_offset(), 0, - // vklass_h->size_helper() * wordSize - vklass_h->first_field_offset()); - thread->set_vm_result(value_h()); IRT_END IRT_ENTRY(int, InterpreterRuntime::vwithfield(JavaThread* thread, ConstantPoolCache* cp_cache)) // Getting the ValueKlass --- 213,226 ---- ValueKlass* vklass = ValueKlass::cast(k); vklass->initialize(THREAD); // Creating value ! bool in_heap; ! instanceOop value = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); Handle value_h = Handle(THREAD, value); thread->set_vm_result(value_h()); IRT_END IRT_ENTRY(int, InterpreterRuntime::vwithfield(JavaThread* thread, ConstantPoolCache* cp_cache)) // Getting the ValueKlass
*** 250,264 **** oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset); assert(old_value != NULL && old_value->is_oop() && old_value->is_value(),"Verifying receiver"); Handle old_value_h(THREAD, old_value); // Creating new value by copying the one passed in argument ! instanceOop new_value = vklass->allocate_instance(CHECK_0); Handle new_value_h = Handle(THREAD, new_value); int first_offset = vklass->first_field_offset(); ! vklass->value_store(((char*)(oopDesc*)old_value_h()) + first_offset, ! ((char*)(oopDesc*)new_value_h()) + first_offset, true, false); // 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 || (aoop->is_oop() && (!aoop->is_value())),"argument must be a reference type"); --- 247,263 ---- oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset); assert(old_value != NULL && old_value->is_oop() && old_value->is_value(),"Verifying receiver"); Handle old_value_h(THREAD, old_value); // Creating new value by copying the one passed in argument ! bool in_heap; ! instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap, ! CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); Handle new_value_h = Handle(THREAD, new_value); int first_offset = vklass->first_field_offset(); ! vklass->value_store(vklass->data_for_oop(old_value_h()), ! vklass->data_for_oop(new_value_h()), in_heap, false); // 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 || (aoop->is_oop() && (!aoop->is_value())),"argument must be a reference type");
*** 267,277 **** Klass* field_k = vklass->get_value_field_klass(fd.index()); ValueKlass* field_vk = ValueKlass::cast(field_k); oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(vt_oop != NULL && vt_oop->is_oop() && vt_oop->is_value(),"argument must be a value type"); assert(field_vk == vt_oop->klass(), "Must match"); ! field_vk->value_store(((char*)(oopDesc*)vt_oop + field_vk->first_field_offset()), ((char*)(oopDesc*)new_value_h()) + fd.offset(), true, false); } else { intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); copy_primitive_argument(addr, new_value_h, fd.offset(), field_type); } --- 266,276 ---- Klass* field_k = vklass->get_value_field_klass(fd.index()); ValueKlass* field_vk = ValueKlass::cast(field_k); oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); assert(vt_oop != NULL && vt_oop->is_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()) + fd.offset(), true, false); } else { intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); copy_primitive_argument(addr, new_value_h, fd.offset(), field_type); }
*** 298,312 **** } ValueKlass* vtklass = ValueKlass::cast(klass); if (vtklass->get_vcc_klass() != target_klass) { THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vbox target is not derive value type box"); } ! ! oop boxed = vtklass->derive_value_type_copy(Handle(THREAD, value), InstanceKlass::cast(target_klass), CHECK); ! thread->set_vm_result(boxed); IRT_END IRT_ENTRY(void, InterpreterRuntime::vunbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* obj)) assert(EnableMVT, "vunbox is supported only when the MVT programming model is enabled"); if (obj == NULL) { --- 297,310 ---- } ValueKlass* vtklass = ValueKlass::cast(klass); if (vtklass->get_vcc_klass() != target_klass) { THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vbox target is not derive value type box"); } ! oop box = vtklass->box(Handle(THREAD, value), InstanceKlass::cast(target_klass), CHECK); ! thread->set_vm_result(box); IRT_END IRT_ENTRY(void, InterpreterRuntime::vunbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* obj)) assert(EnableMVT, "vunbox is supported only when the MVT programming model is enabled"); if (obj == NULL) {
*** 321,331 **** THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance"); } if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) { THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type"); } ! oop value = ValueKlass::cast(target_klass)->derive_value_type_copy(Handle(THREAD, obj), InstanceKlass::cast(target_klass), CHECK); thread->set_vm_result(value); IRT_END --- 319,329 ---- THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance"); } if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) { THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type"); } ! oop value = ValueKlass::cast(target_klass)->unbox(Handle(THREAD, obj), InstanceKlass::cast(target_klass), CHECK); thread->set_vm_result(value); IRT_END
*** 335,366 **** fieldDescriptor fd; klass->find_field_from_offset(offset, false, &fd); Klass* field_k = klass->get_value_field_klass(fd.index()); ValueKlass* field_vklass = ValueKlass::cast(field_k); // allocate instance ! instanceOop res = field_vklass->allocate_instance(CHECK); // copy value - int size = field_vklass->layout_helper_size_in_bytes(field_vklass->layout_helper()); field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset, ! ((char*)(oopDesc*)res) + field_vklass->first_field_offset(),true, false); ! thread->set_vm_result(res); IRT_END IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int offset)) Handle value_h(THREAD, value); Handle obj_h(THREAD, obj); ! InstanceKlass* klass_h = InstanceKlass::cast(obj->klass()); ValueKlass* field_vklass = ValueKlass::cast(value->klass()); ! // copy value ! int size = field_vklass->layout_helper_size_in_bytes(field_vklass->layout_helper()); ! field_vklass->value_store(((char*)(oopDesc*)value_h()) + field_vklass->first_field_offset(), ((char*)(oopDesc*)obj_h()) + offset, true, false); IRT_END IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) oop obj = oopFactory::new_typeArray(type, size, CHECK); thread->set_vm_result(obj); IRT_END --- 333,426 ---- fieldDescriptor fd; klass->find_field_from_offset(offset, false, &fd); Klass* field_k = klass->get_value_field_klass(fd.index()); ValueKlass* field_vklass = ValueKlass::cast(field_k); + field_vklass->initialize(THREAD); + // allocate instance ! bool in_heap; ! instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); ! instanceHandle res_h(THREAD, res); // copy value field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset, ! field_vklass->data_for_oop(res), in_heap, false); ! thread->set_vm_result(res_h()); ! IRT_END ! ! IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int offset)) ! instanceHandle mirror_h(THREAD, (instanceOop)mirror); ! InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); ! assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice"); ! ! fieldDescriptor fd; ! klass->find_field_from_offset(offset, true, &fd); ! Klass* field_k = klass->get_value_field_klass(fd.index()); ! ValueKlass* field_vklass = ValueKlass::cast(field_k); ! // allocate instance, because it is going to be assigned to a static field ! // it must not be a buffered value ! instanceOop res = field_vklass->allocate_instance(CHECK); ! instanceHandle res_h(THREAD, res); ! mirror_h()->obj_field_put(offset, res_h()); ! thread->set_vm_result(res_h()); IRT_END IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int offset)) Handle value_h(THREAD, value); Handle obj_h(THREAD, obj); + assert(!obj_h()->klass()->is_value(), "obj must be an object"); + assert(value_h()->klass()->is_value(), "value must be an value type"); ! InstanceKlass* klass = InstanceKlass::cast(obj->klass()); ! fieldDescriptor fd; ! klass->find_field_from_offset(offset, false, &fd); ! Klass* field_k = klass->get_value_field_klass(fd.index()); ValueKlass* field_vklass = ValueKlass::cast(value->klass()); ! assert(field_k == field_vklass, "Field descriptor and argument must match"); // copy value ! field_vklass->value_store(field_vklass->data_for_oop(value_h()), ((char*)(oopDesc*)obj_h()) + offset, true, false); IRT_END + IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value)) + instanceHandle value_h(THREAD, (instanceOop)value); + assert(value_h()->is_value(), "qputstatic only deals with value arguments"); + Method* m = last_frame(thread).interpreter_frame_method(); + jint bci = last_frame(thread).interpreter_frame_bci(); + assert(m->code_at(bci) == Bytecodes::_putstatic, "qputstatic is a particular case of putstatic"); + ConstantPoolCache* cp_cache = last_frame(thread).interpreter_frame_method()->constants()->cache(); + int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putstatic)); + ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index); + assert(cp_entry->is_field_entry(), "Sanity check"); + + InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass()); + int offset = cp_entry->f2_as_index(); + oop mirror = klass->java_mirror(); + + 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 + fieldDescriptor fd; + klass->find_field_from_offset(offset, false, &fd); + Klass* field_k = klass->get_value_field_klass(fd.index()); + ValueKlass* field_vklass = ValueKlass::cast(field_k); + assert(field_vklass == value->klass(), "Field descriptor and argument must match"); + // allocate heap instance + instanceOop res = field_vklass->allocate_instance(CHECK); + assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap"); + instanceHandle res_h(THREAD, res); + // copy value + field_vklass->value_store(field_vklass->data_for_oop(value_h()), + field_vklass->data_for_oop(res), true, false); + // writing static field + mirror->obj_field_put(offset, res_h()); + assert(mirror->obj_field(offset) != NULL,"Sanity check"); + } + IRT_END + IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) oop obj = oopFactory::new_typeArray(type, size, CHECK); thread->set_vm_result(obj); IRT_END
*** 380,397 **** if (klass->is_objArray_klass()) { thread->set_vm_result(((objArrayOop) array)->obj_at(index)); } else { - // Early prototype: we don't have valorind support...just allocate aref and copy ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); ValueKlass* vklass = vaklass->element_klass(); arrayHandle ah(THREAD, array); ! instanceOop value_holder = vklass->allocate_instance(CHECK); void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper()); vklass->value_store(src, vklass->data_for_oop(value_holder), ! vaklass->element_byte_size(), true, true); thread->set_vm_result(value_holder); } IRT_END IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val)) --- 440,457 ---- 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); void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper()); vklass->value_store(src, vklass->data_for_oop(value_holder), ! vaklass->element_byte_size(), in_heap, false); thread->set_vm_result(value_holder); } IRT_END IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))
*** 400,412 **** if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) { THROW(vmSymbols::java_lang_ArrayStoreException()); } if (klass->is_objArray_klass()) { ! ((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(); vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh), --- 460,488 ---- 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(); ! assert(eklass->is_value(), "Sanity check"); ! assert(eklass == ((oop)val)->klass(), "Sanity check"); ! ValueKlass* vklass = ValueKlass::cast(eklass); ! // allocate heap instance ! instanceOop res = vklass->allocate_instance(CHECK); ! Handle res_h(THREAD, res); ! // 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(); vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
*** 442,451 **** --- 518,579 ---- } 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"); + VTBuffer::recycle_vt_in_frame(thread, &f); + IRT_END + + IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread)) + 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()); + RegisterMap reg_map(thread, false); + frame current_frame = last_frame(thread); + frame caller_frame = current_frame.sender(&reg_map); + if (!caller_frame.is_interpreted_frame()) { + // caller is not an interpreted frame, creating a new value in Java heap + Handle obj_h(THREAD, obj); + instanceOop res = vk->allocate_instance(CHECK); + Handle res_h(THREAD, res); + // copy value + 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); + tty->print_cr("areturn used on a value from %s", k->name()->as_C_string()); + } + assert(!k->is_value(), "areturn should never be used on values"); + } + thread->set_vm_result(obj); + IRT_END IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) assert(obj->is_oop(), "must be a valid oop"); assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
*** 972,982 **** methodHandle m (thread, method(thread)); Bytecode_invoke call(m, bci(thread)); Symbol* signature = call.signature(); receiver = Handle(thread, thread->last_frame().interpreter_callee_receiver(signature)); ! assert(Universe::heap()->is_in_reserved_or_null(receiver()), "sanity check"); assert(receiver.is_null() || !Universe::heap()->is_in_reserved(receiver->klass()), "sanity check"); } --- 1100,1111 ---- methodHandle m (thread, method(thread)); Bytecode_invoke call(m, bci(thread)); Symbol* signature = call.signature(); receiver = Handle(thread, thread->last_frame().interpreter_callee_receiver(signature)); ! assert(Universe::heap()->is_in_reserved_or_null(receiver()) ! || VTBuffer::is_in_vt_buffer(receiver()), "sanity check"); assert(receiver.is_null() || !Universe::heap()->is_in_reserved(receiver->klass()), "sanity check"); }
< prev index next >