< prev index next >
src/share/vm/interpreter/interpreterRuntime.cpp
Print this page
@@ -264,18 +264,24 @@
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(fd.offset(), aoop);
} else if (field_type == T_VALUETYPE) {
+ if (fd.is_flatten()) {
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 && 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()) + fd.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(fd.offset(), voop);
+ }
+ } else {
intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
copy_primitive_argument(addr, new_value_h, fd.offset(), field_type);
}
// returning result
@@ -328,28 +334,37 @@
InstanceKlass::cast(target_klass),
CHECK);
thread->set_vm_result(value);
IRT_END
-IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* value, int offset))
- Handle value_h(THREAD, value);
- InstanceKlass* klass = InstanceKlass::cast(value->klass());
+IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* obj, int offset))
+ Handle value_h(THREAD, obj);
+ 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(field_k);
field_vklass->initialize(THREAD);
- // allocate instance
+ instanceOop res;
bool in_heap;
- instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
+ if (fd.is_flatten()) {
+ // allocate instance
+ 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());
+ } else {
+ oop res = value_h()->obj_field_acquire(offset);
+ if (res == NULL) {
+ res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
+ }
+ thread->set_vm_result(res);
+ }
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));
@@ -377,13 +392,29 @@
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");
+ if (fd.is_flatten()) {
// copy value
field_vklass->value_store(field_vklass->data_for_oop(value_h()),
((char*)(oopDesc*)obj_h()) + offset, true, false);
+ } else {
+ if (Universe::heap()->is_in_reserved(value_h())) {
+ obj_h()->obj_field_put(offset, value_h());
+ } else {
+ // allocate heap instance
+ instanceOop val = field_vklass->allocate_instance(CHECK);
+ instanceHandle res_h(THREAD, val);
+ // copy value
+ field_vklass->value_store(field_vklass->data_for_oop(value_h()),
+ field_vklass->data_for_oop(res_h()), true, false);
+
+
+ obj_h()->obj_field_put(offset, res_h());
+ }
+ }
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");
@@ -993,10 +1024,11 @@
info.index(),
info.offset(),
state,
info.access_flags().is_final(),
info.access_flags().is_volatile(),
+ info.is_flatten(),
pool->pool_holder()
);
}
< prev index next >