--- old/src/share/vm/interpreter/interpreterRuntime.cpp 2017-09-13 15:36:02.000000000 -0400 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp 2017-09-13 15:36:02.000000000 -0400 @@ -266,13 +266,19 @@ 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) { - 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); + 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); @@ -330,9 +336,9 @@ 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); @@ -340,14 +346,23 @@ 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); - 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()); + 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)) @@ -379,9 +394,25 @@ 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); + 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)) @@ -995,6 +1026,7 @@ state, info.access_flags().is_final(), info.access_flags().is_volatile(), + info.is_flatten(), pool->pool_holder() ); }