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