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