--- old/src/hotspot/share/interpreter/interpreterRuntime.cpp 2017-12-13 15:36:04.044791853 -0500 +++ new/src/hotspot/share/interpreter/interpreterRuntime.cpp 2017-12-13 15:36:03.780790544 -0500 @@ -590,44 +590,30 @@ 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; - } +IRT_ENTRY(void, InterpreterRuntime::reallocate_value_in_heap(JavaThread* thread, oopDesc* obj)) + assert(VTBuffer::is_in_vt_buffer(obj), "must be called on buffered value"); + assert(!ReturnValuesInThreadLocalBuffer, "Should re-allocate value if ReturnValuesInThreadLocalBuffer is true"); + + Handle obj_h(THREAD, obj); assert(obj->klass()->is_value(), "Sanity check"); ValueKlass* vk = ValueKlass::cast(obj->klass()); - RegisterMap reg_map(thread, false); - frame current_frame = thread->last_frame(); - 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 { - // 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); - } + 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()); IRT_END -IRT_LEAF(void, InterpreterRuntime::return_value_step2(oopDesc* obj, void* alloc_ptr)) - +IRT_LEAF(void, InterpreterRuntime::relocate_return_value(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); + ValueKlass* vklass = ValueKlass::cast(dest->klass()); + void* start = (char*)(oopDesc*)dest + vklass->size_helper() * wordSize; + VTBuffer::recycle_vtbuffer(thread, start); thread->set_return_buffered_value(NULL); thread->set_vm_result(dest); IRT_END