< 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(®_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 >