< prev index next > src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
Print this page
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
+ #include "asm/assembler.hpp"
#include "asm/macroAssembler.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/vmIntrinsics.hpp"
#include "compiler/oopMap.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/barrierSetNMethod.hpp"
#include "gc/shared/gc_globals.hpp"
#include "memory/universe.hpp"
+ #include "oops/inlineKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/arguments.hpp"
#include "runtime/continuationEntry.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+ #include "utilities/macros.hpp"
+ #include "vmreg_x86.inline.hpp"
#include "stubGenerator_x86_64.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#include "opto/c2_globals.hpp"
#endif
BLOCK_COMMENT("call_stub_return_address:");
return_address = __ pc();
entries.append(return_address);
// store result depending on type (everything that is not
// T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
! __ movptr(c_rarg0, result);
! Label is_long, is_float, is_double, exit;
! __ movl(c_rarg1, result_type);
! __ cmpl(c_rarg1, T_OBJECT);
! __ jcc(Assembler::equal, is_long);
! __ cmpl(c_rarg1, T_LONG);
__ jcc(Assembler::equal, is_long);
! __ cmpl(c_rarg1, T_FLOAT);
__ jcc(Assembler::equal, is_float);
! __ cmpl(c_rarg1, T_DOUBLE);
__ jcc(Assembler::equal, is_double);
#ifdef ASSERT
// make sure the type is INT
{
Label L;
! __ cmpl(c_rarg1, T_INT);
__ jcc(Assembler::equal, L);
__ stop("StubRoutines::call_stub: unexpected result type");
__ bind(L);
}
#endif
// handle T_INT case
! __ movl(Address(c_rarg0, 0), rax);
__ BIND(exit);
// pop parameters
__ lea(rsp, rsp_after_call);
BLOCK_COMMENT("call_stub_return_address:");
return_address = __ pc();
entries.append(return_address);
+ // All of j_rargN + rax may be used to return inline type fields so be careful
+ // not to clobber those. See SharedRuntime::java_return_convention().
+
// store result depending on type (everything that is not
// T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
! __ movptr(r13, result);
! Label is_long, is_float, is_double, check_prim, exit;
! __ movl(rbx, result_type);
! __ cmpl(rbx, T_OBJECT);
! __ jcc(Assembler::equal, check_prim);
! __ cmpl(rbx, T_LONG);
__ jcc(Assembler::equal, is_long);
! __ cmpl(rbx, T_FLOAT);
__ jcc(Assembler::equal, is_float);
! __ cmpl(rbx, T_DOUBLE);
__ jcc(Assembler::equal, is_double);
#ifdef ASSERT
// make sure the type is INT
{
Label L;
! __ cmpl(rbx, T_INT);
__ jcc(Assembler::equal, L);
__ stop("StubRoutines::call_stub: unexpected result type");
__ bind(L);
}
#endif
// handle T_INT case
! __ movl(Address(r13, 0), rax);
__ BIND(exit);
// pop parameters
__ lea(rsp, rsp_after_call);
__ vzeroupper();
__ pop(rbp);
__ ret(0);
// handle return types different from T_INT
__ BIND(is_long);
! __ movq(Address(c_rarg0, 0), rax);
__ jmp(exit);
__ BIND(is_float);
! __ movflt(Address(c_rarg0, 0), xmm0);
__ jmp(exit);
__ BIND(is_double);
! __ movdbl(Address(c_rarg0, 0), xmm0);
__ jmp(exit);
// record the stub entry and end plus the auxiliary entry
store_archive_data(stub_id, start, __ pc(), &entries);
__ vzeroupper();
__ pop(rbp);
__ ret(0);
// handle return types different from T_INT
+ __ BIND(check_prim);
+ if (InlineTypeReturnedAsFields) {
+ // Check for scalarized return value
+ __ testptr(rax, 1);
+ __ jcc(Assembler::zero, is_long);
+ // Load pack handler address
+ __ andptr(rax, -2);
+ __ movptr(rax, Address(rax, InlineKlass::adr_members_offset()));
+ __ movptr(rbx, Address(rax, InlineKlass::pack_handler_jobject_offset()));
+ // Call pack handler to initialize the buffer
+ __ call(rbx);
+ __ jmp(exit);
+ }
__ BIND(is_long);
! __ movq(Address(r13, 0), rax);
__ jmp(exit);
__ BIND(is_float);
! __ movflt(Address(r13, 0), xmm0);
__ jmp(exit);
__ BIND(is_double);
! __ movdbl(Address(r13, 0), xmm0);
__ jmp(exit);
// record the stub entry and end plus the auxiliary entry
store_archive_data(stub_id, start, __ pc(), &entries);
store_archive_data(stub_id, start, __ pc());
return start;
}
+ static void save_return_registers(MacroAssembler* masm) {
+ masm->push_ppx(rax);
+ if (InlineTypeReturnedAsFields) {
+ masm->push(rdi);
+ masm->push(rsi);
+ masm->push(rdx);
+ masm->push(rcx);
+ masm->push(r8);
+ masm->push(r9);
+ }
+ masm->push_d(xmm0);
+ if (InlineTypeReturnedAsFields) {
+ masm->push_d(xmm1);
+ masm->push_d(xmm2);
+ masm->push_d(xmm3);
+ masm->push_d(xmm4);
+ masm->push_d(xmm5);
+ masm->push_d(xmm6);
+ masm->push_d(xmm7);
+ }
+ #ifdef ASSERT
+ masm->movq(rax, 0xBADC0FFE);
+ masm->movq(rdi, rax);
+ masm->movq(rsi, rax);
+ masm->movq(rdx, rax);
+ masm->movq(rcx, rax);
+ masm->movq(r8, rax);
+ masm->movq(r9, rax);
+ masm->movq(xmm0, rax);
+ masm->movq(xmm1, rax);
+ masm->movq(xmm2, rax);
+ masm->movq(xmm3, rax);
+ masm->movq(xmm4, rax);
+ masm->movq(xmm5, rax);
+ masm->movq(xmm6, rax);
+ masm->movq(xmm7, rax);
+ #endif
+ }
+
+ static void restore_return_registers(MacroAssembler* masm) {
+ if (InlineTypeReturnedAsFields) {
+ masm->pop_d(xmm7);
+ masm->pop_d(xmm6);
+ masm->pop_d(xmm5);
+ masm->pop_d(xmm4);
+ masm->pop_d(xmm3);
+ masm->pop_d(xmm2);
+ masm->pop_d(xmm1);
+ }
+ masm->pop_d(xmm0);
+ if (InlineTypeReturnedAsFields) {
+ masm->pop(r9);
+ masm->pop(r8);
+ masm->pop(rcx);
+ masm->pop(rdx);
+ masm->pop(rsi);
+ masm->pop(rdi);
+ }
+ masm->pop_ppx(rax);
+ }
+
address StubGenerator::generate_cont_thaw(StubId stub_id) {
if (!Continuations::enabled()) return nullptr;
bool return_barrier;
bool return_barrier_exception;
}
#endif // ASSERT
if (return_barrier) {
// Preserve possible return value from a method returning to the return barrier.
! __ push_ppx(rax);
- __ push_d(xmm0);
}
__ movptr(c_rarg0, r15_thread);
__ movptr(c_rarg1, (return_barrier ? 1 : 0));
__ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), 2);
__ movptr(rbx, rax);
if (return_barrier) {
// Restore return value from a method returning to the return barrier.
// No safepoint in the call to thaw, so even an oop return value should be OK.
! __ pop_d(xmm0);
- __ pop_ppx(rax);
}
#ifdef ASSERT
{
Label L_good_sp;
}
#endif // ASSERT
if (return_barrier) {
// Preserve possible return value from a method returning to the return barrier.
! save_return_registers(_masm);
}
__ movptr(c_rarg0, r15_thread);
__ movptr(c_rarg1, (return_barrier ? 1 : 0));
__ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), 2);
__ movptr(rbx, rax);
if (return_barrier) {
// Restore return value from a method returning to the return barrier.
// No safepoint in the call to thaw, so even an oop return value should be OK.
! restore_return_registers(_masm);
}
#ifdef ASSERT
{
Label L_good_sp;
__ subptr(rsp, rbx);
__ andptr(rsp, -StackAlignmentInBytes);
if (return_barrier) {
// Preserve possible return value from a method returning to the return barrier. (Again.)
! __ push_ppx(rax);
- __ push_d(xmm0);
}
// If we want, we can templatize thaw by kind, and have three different entries.
__ movptr(c_rarg0, r15_thread);
__ movptr(c_rarg1, kind);
__ subptr(rsp, rbx);
__ andptr(rsp, -StackAlignmentInBytes);
if (return_barrier) {
// Preserve possible return value from a method returning to the return barrier. (Again.)
! save_return_registers(_masm);
}
// If we want, we can templatize thaw by kind, and have three different entries.
__ movptr(c_rarg0, r15_thread);
__ movptr(c_rarg1, kind);
__ movptr(rbx, rax);
if (return_barrier) {
// Restore return value from a method returning to the return barrier. (Again.)
// No safepoint in the call to thaw, so even an oop return value should be OK.
! __ pop_d(xmm0);
- __ pop_ppx(rax);
} else {
// Return 0 (success) from doYield.
__ xorptr(rax, rax);
}
__ movptr(rbx, rax);
if (return_barrier) {
// Restore return value from a method returning to the return barrier. (Again.)
// No safepoint in the call to thaw, so even an oop return value should be OK.
! restore_return_registers(_masm);
} else {
// Return 0 (success) from doYield.
__ xorptr(rax, rax);
}
< prev index next >