< prev index next >
src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
Print this page
*** 34,43 ****
--- 34,44 ----
#include "interpreter/templateTable.hpp"
#include "oops/arrayOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/valueKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
*** 55,65 ****
// fail with a guarantee ("not enough space for interpreter generation");
// if too small.
// Run with +PrintInterpreter to get the VM to print out the size.
// Max size with JVMTI
#ifdef AMD64
! int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
#else
int TemplateInterpreter::InterpreterCodeSize = 224 * 1024;
#endif // AMD64
// Global Register Names
--- 56,66 ----
// fail with a guarantee ("not enough space for interpreter generation");
// if too small.
// Run with +PrintInterpreter to get the VM to print out the size.
// Max size with JVMTI
#ifdef AMD64
! int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(280) NOT_JVMCI(268) * 1024;
#else
int TemplateInterpreter::InterpreterCodeSize = 224 * 1024;
#endif // AMD64
// Global Register Names
*** 203,212 ****
--- 204,263 ----
// Restore stack bottom in case i2c adjusted stack
__ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
// and NULL it as marker that esp is now tos until next java call
__ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
+ if (state == atos && ValueTypeReturnedAsFields) {
+ #ifndef _LP64
+ __ super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
+ #else
+ // A value type might be returned. If fields are in registers we
+ // need to allocate a value type instance and initialize it with
+ // the value of the fields.
+ Label skip, slow_case;
+ // We only need a new buffered value if a new one is not returned
+ __ testptr(rax, 1);
+ __ jcc(Assembler::zero, skip);
+
+ // Try to allocate a new buffered value (from the heap)
+ if (UseTLAB) {
+ __ mov(rbx, rax);
+ __ andptr(rbx, -2);
+
+ __ movl(r14, Address(rbx, Klass::layout_helper_offset()));
+
+ __ movptr(r13, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())));
+ __ lea(r14, Address(r13, r14, Address::times_1));
+ __ cmpptr(r14, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset())));
+ __ jcc(Assembler::above, slow_case);
+ __ movptr(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), r14);
+ __ movptr(Address(r13, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::always_locked_prototype());
+
+ __ xorl(rax, rax); // use zero reg to clear memory (shorter code)
+ __ store_klass_gap(r13, rax); // zero klass gap for compressed oops
+ __ mov(rax, rbx);
+ __ store_klass(r13, rbx); // klass
+
+ // We have our new buffered value, initialize its fields with a
+ // value class specific handler
+ __ movptr(rbx, Address(rax, InstanceKlass::adr_valueklass_fixed_block_offset()));
+ __ movptr(rbx, Address(rbx, ValueKlass::pack_handler_offset()));
+ __ mov(rax, r13);
+ __ call(rbx);
+ __ jmp(skip);
+ }
+
+ __ bind(slow_case);
+ // We failed to allocate a new value, fall back to a runtime
+ // call. Some oop field may be live in some registers but we can't
+ // tell. That runtime call will take care of preserving them
+ // across a GC if there's one.
+ __ super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
+ __ bind(skip);
+ #endif
+ }
+
__ restore_bcp();
__ restore_locals();
if (state == atos) {
Register mdp = rbx;
*** 345,354 ****
--- 396,406 ----
#else
case T_FLOAT : /* nothing to do */ break;
case T_DOUBLE : /* nothing to do */ break;
#endif // _LP64
+ case T_VALUETYPE: // fall through (value types are handled with oops)
case T_OBJECT :
// retrieve result from frame
__ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize));
// and verify it
__ verify_oop(rax);
< prev index next >