8288971: AArch64: Clean up stack and register handling in interpreter
Reviewed-by: adinn, ngasson
This commit is contained in:
parent
d53b02eb9f
commit
b5d965656d
@ -90,7 +90,7 @@ int AbstractInterpreter::size_activation(int max_stack,
|
|||||||
// for the callee's params we only need to account for the extra
|
// for the callee's params we only need to account for the extra
|
||||||
// locals.
|
// locals.
|
||||||
int size = overhead +
|
int size = overhead +
|
||||||
(callee_locals - callee_params) +
|
(callee_locals - callee_params) * Interpreter::stackElementWords +
|
||||||
monitors * frame::interpreter_frame_monitor_size() +
|
monitors * frame::interpreter_frame_monitor_size() +
|
||||||
// On the top frame, at all times SP <= ESP, and SP is
|
// On the top frame, at all times SP <= ESP, and SP is
|
||||||
// 16-aligned. We ensure this by adjusting SP on method
|
// 16-aligned. We ensure this by adjusting SP on method
|
||||||
@ -135,7 +135,7 @@ void AbstractInterpreter::layout_activation(Method* method,
|
|||||||
// NOTE the difference in using sender_sp and
|
// NOTE the difference in using sender_sp and
|
||||||
// interpreter_frame_sender_sp interpreter_frame_sender_sp is
|
// interpreter_frame_sender_sp interpreter_frame_sender_sp is
|
||||||
// the original sp of the caller (the unextended_sp) and
|
// the original sp of the caller (the unextended_sp) and
|
||||||
// sender_sp is fp+8/16 (32bit/64bit) XXX
|
// sender_sp is fp+16
|
||||||
//
|
//
|
||||||
// The interpreted method entry on AArch64 aligns SP to 16 bytes
|
// The interpreted method entry on AArch64 aligns SP to 16 bytes
|
||||||
// before generating the fixed part of the activation frame. So there
|
// before generating the fixed part of the activation frame. So there
|
||||||
@ -165,6 +165,19 @@ void AbstractInterpreter::layout_activation(Method* method,
|
|||||||
popframe_extra_args;
|
popframe_extra_args;
|
||||||
interpreter_frame->interpreter_frame_set_last_sp(esp);
|
interpreter_frame->interpreter_frame_set_last_sp(esp);
|
||||||
|
|
||||||
|
// We have to add extra reserved slots to max_stack. There are 3 users of the extra slots,
|
||||||
|
// none of which are at the same time, so we just need to make sure there is enough room
|
||||||
|
// for the biggest user:
|
||||||
|
// -reserved slot for exception handler
|
||||||
|
// -reserved slots for JSR292. Method::extra_stack_entries() is the size.
|
||||||
|
// -reserved slots for TraceBytecodes
|
||||||
|
int max_stack = method->constMethod()->max_stack() + MAX2(3, Method::extra_stack_entries());
|
||||||
|
intptr_t* extended_sp = (intptr_t*) monbot -
|
||||||
|
(max_stack * Interpreter::stackElementWords) -
|
||||||
|
popframe_extra_args;
|
||||||
|
extended_sp = align_down(extended_sp, StackAlignmentInBytes);
|
||||||
|
interpreter_frame->interpreter_frame_set_extended_sp(extended_sp);
|
||||||
|
|
||||||
// All frames but the initial (oldest) interpreter frame we fill in have
|
// All frames but the initial (oldest) interpreter frame we fill in have
|
||||||
// a value for sender_sp that allows walking the stack but isn't
|
// a value for sender_sp that allows walking the stack but isn't
|
||||||
// truly correct. Correct the value here.
|
// truly correct. Correct the value here.
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
const uintptr_t Assembler::asm_bp = 0x00007fffee09ac88;
|
const uintptr_t Assembler::asm_bp = 0x0000ffffac221240;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static float unpack(unsigned value);
|
static float unpack(unsigned value);
|
||||||
|
@ -142,16 +142,18 @@ REGISTER_DECLARATION(Register, rthread, r28);
|
|||||||
REGISTER_DECLARATION(Register, rheapbase, r27);
|
REGISTER_DECLARATION(Register, rheapbase, r27);
|
||||||
// constant pool cache
|
// constant pool cache
|
||||||
REGISTER_DECLARATION(Register, rcpool, r26);
|
REGISTER_DECLARATION(Register, rcpool, r26);
|
||||||
// monitors allocated on stack
|
// r25 is a callee-saved temp
|
||||||
REGISTER_DECLARATION(Register, rmonitors, r25);
|
// REGISTER_DECLARATION(Register, unused, r25);
|
||||||
// locals on stack
|
// locals on stack
|
||||||
REGISTER_DECLARATION(Register, rlocals, r24);
|
REGISTER_DECLARATION(Register, rlocals, r24);
|
||||||
// bytecode pointer
|
// bytecode pointer
|
||||||
REGISTER_DECLARATION(Register, rbcp, r22);
|
REGISTER_DECLARATION(Register, rbcp, r22);
|
||||||
// Dispatch table base
|
// Dispatch table base
|
||||||
REGISTER_DECLARATION(Register, rdispatch, r21);
|
REGISTER_DECLARATION(Register, rdispatch, r21);
|
||||||
// Java stack pointer
|
// Java expression stack pointer
|
||||||
REGISTER_DECLARATION(Register, esp, r20);
|
REGISTER_DECLARATION(Register, esp, r20);
|
||||||
|
// Sender's SP while in interpreter
|
||||||
|
REGISTER_DECLARATION(Register, r19_sender_sp, r19);
|
||||||
|
|
||||||
// Preserved predicate register with all elements set TRUE.
|
// Preserved predicate register with all elements set TRUE.
|
||||||
REGISTER_DECLARATION(PRegister, ptrue, p7);
|
REGISTER_DECLARATION(PRegister, ptrue, p7);
|
||||||
|
@ -354,6 +354,11 @@ void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
|
|||||||
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
|
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used by template based interpreter deoptimization
|
||||||
|
void frame::interpreter_frame_set_extended_sp(intptr_t* sp) {
|
||||||
|
*((intptr_t**)addr_at(interpreter_frame_extended_sp_offset)) = sp;
|
||||||
|
}
|
||||||
|
|
||||||
frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
||||||
assert(map != NULL, "map must be set");
|
assert(map != NULL, "map must be set");
|
||||||
// Java frame called from C; skip all C frames and return top C
|
// Java frame called from C; skip all C frames and return top C
|
||||||
@ -599,6 +604,7 @@ void frame::describe_pd(FrameValues& values, int frame_no) {
|
|||||||
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
|
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_method);
|
DESCRIBE_FP_OFFSET(interpreter_frame_method);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
|
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
|
||||||
|
DESCRIBE_FP_OFFSET(interpreter_frame_extended_sp);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
|
DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
|
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
|
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
|
||||||
@ -670,6 +676,8 @@ void internal_pf(uintptr_t sp, uintptr_t fp, uintptr_t pc, uintptr_t bcx) {
|
|||||||
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
|
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_method);
|
DESCRIBE_FP_OFFSET(interpreter_frame_method);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
|
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
|
||||||
|
DESCRIBE_FP_OFFSET(interpreter_frame_extended_sp);
|
||||||
|
DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
|
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
|
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
|
||||||
DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
|
DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
|
||||||
@ -772,4 +780,3 @@ void JavaFrameAnchor::make_walkable() {
|
|||||||
_last_Java_pc = (address)_last_Java_sp[-1];
|
_last_Java_pc = (address)_last_Java_sp[-1];
|
||||||
vmassert(walkable(), "something went wrong");
|
vmassert(walkable(), "something went wrong");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,13 +47,13 @@
|
|||||||
// [constant pool cache ] = cache() cache_offset
|
// [constant pool cache ] = cache() cache_offset
|
||||||
|
|
||||||
// [klass of method ] = mirror() mirror_offset
|
// [klass of method ] = mirror() mirror_offset
|
||||||
// [padding ]
|
// [extended SP ] extended_sp offset
|
||||||
|
|
||||||
// [methodData ] = mdp() mdx_offset
|
// [methodData ] = mdp() mdx_offset
|
||||||
// [Method ] = method() method_offset
|
// [Method ] = method() method_offset
|
||||||
|
|
||||||
// [last esp ] = last_sp() last_sp_offset
|
// [last esp ] = last_sp() last_sp_offset
|
||||||
// [old stack pointer ] (sender_sp) sender_sp_offset
|
// [sender's SP ] (sender_sp) sender_sp_offset
|
||||||
|
|
||||||
// [old frame pointer ] <- fp = link()
|
// [old frame pointer ] <- fp = link()
|
||||||
// [return pc ]
|
// [return pc ]
|
||||||
@ -82,8 +82,8 @@
|
|||||||
interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1,
|
interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1,
|
||||||
interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1,
|
interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1,
|
||||||
interpreter_frame_mdp_offset = interpreter_frame_method_offset - 1,
|
interpreter_frame_mdp_offset = interpreter_frame_method_offset - 1,
|
||||||
interpreter_frame_padding_offset = interpreter_frame_mdp_offset - 1,
|
interpreter_frame_extended_sp_offset = interpreter_frame_mdp_offset - 1,
|
||||||
interpreter_frame_mirror_offset = interpreter_frame_padding_offset - 1,
|
interpreter_frame_mirror_offset = interpreter_frame_extended_sp_offset - 1,
|
||||||
interpreter_frame_cache_offset = interpreter_frame_mirror_offset - 1,
|
interpreter_frame_cache_offset = interpreter_frame_mirror_offset - 1,
|
||||||
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
|
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
|
||||||
interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1,
|
interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1,
|
||||||
@ -182,6 +182,8 @@
|
|||||||
// expression stack tos if we are nested in a java call
|
// expression stack tos if we are nested in a java call
|
||||||
intptr_t* interpreter_frame_last_sp() const;
|
intptr_t* interpreter_frame_last_sp() const;
|
||||||
|
|
||||||
|
void interpreter_frame_set_extended_sp(intptr_t* sp);
|
||||||
|
|
||||||
template <typename RegisterMapT>
|
template <typename RegisterMapT>
|
||||||
static void update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr);
|
static void update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr);
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ void InterpreterMacroAssembler::load_double(Address src) {
|
|||||||
|
|
||||||
void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
|
void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
|
||||||
// set sender sp
|
// set sender sp
|
||||||
mov(r13, sp);
|
mov(r19_sender_sp, sp);
|
||||||
// record last_sp
|
// record last_sp
|
||||||
str(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
str(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,31 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||||||
ldr(rcpool, Address(rfp, frame::interpreter_frame_cache_offset * wordSize));
|
ldr(rcpool, Address(rfp, frame::interpreter_frame_cache_offset * wordSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restore_sp_after_call() {
|
||||||
|
Label L;
|
||||||
|
ldr(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
|
||||||
|
#ifdef ASSERT
|
||||||
|
cbnz(rscratch1, L);
|
||||||
|
stop("SP is null");
|
||||||
|
#endif
|
||||||
|
bind(L);
|
||||||
|
mov(sp, rscratch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_extended_sp(const char* msg = "check extended SP") {
|
||||||
|
#ifdef ASSERT
|
||||||
|
Label L;
|
||||||
|
ldr(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
|
||||||
|
cmp(sp, rscratch1);
|
||||||
|
br(EQ, L);
|
||||||
|
stop(msg);
|
||||||
|
bind(L);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define check_extended_sp() \
|
||||||
|
check_extended_sp("SP does not match extended SP in frame at " __FILE__ ":" XSTR(__LINE__))
|
||||||
|
|
||||||
void get_dispatch();
|
void get_dispatch();
|
||||||
|
|
||||||
// Helpers for runtime call arguments/results
|
// Helpers for runtime call arguments/results
|
||||||
|
@ -185,7 +185,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
|
// r19_sender_sp: sender SP (must preserve; see prepare_to_jump_from_interpreted)
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r3: argument locator (parameter slot count, added to rsp)
|
// r3: argument locator (parameter slot count, added to rsp)
|
||||||
// r1: used as temp to hold mh or receiver
|
// r1: used as temp to hold mh or receiver
|
||||||
@ -283,7 +283,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
|||||||
// temps used in this code are not used in *either* compiled or interpreted calling sequences
|
// temps used in this code are not used in *either* compiled or interpreted calling sequences
|
||||||
Register temp1 = r10;
|
Register temp1 = r10;
|
||||||
Register temp2 = r11;
|
Register temp2 = r11;
|
||||||
Register temp3 = r14; // r13 is live by this point: it contains the sender SP
|
Register temp3 = r14;
|
||||||
if (for_compiler_entry) {
|
if (for_compiler_entry) {
|
||||||
assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic || iid == vmIntrinsics::_linkToNative ? noreg : j_rarg0), "only valid assignment");
|
assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic || iid == vmIntrinsics::_linkToNative ? noreg : j_rarg0), "only valid assignment");
|
||||||
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
|
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
|
||||||
@ -356,7 +356,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
|||||||
// Live registers at this point:
|
// Live registers at this point:
|
||||||
// member_reg - MemberName that was the trailing argument
|
// member_reg - MemberName that was the trailing argument
|
||||||
// temp1_recv_klass - klass of stacked receiver, if needed
|
// temp1_recv_klass - klass of stacked receiver, if needed
|
||||||
// r13 - interpreter linkage (if interpreted) ??? FIXME
|
// r19 - interpreter linkage (if interpreted)
|
||||||
// r1 ... r0 - compiler arguments (if compiled)
|
// r1 ... r0 - compiler arguments (if compiled)
|
||||||
|
|
||||||
Label L_incompatible_class_change_error;
|
Label L_incompatible_class_change_error;
|
||||||
@ -443,7 +443,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// live at this point: rmethod, r13 (if interpreted)
|
// live at this point: rmethod, r19_sender_sp (if interpreted)
|
||||||
|
|
||||||
// After figuring out which concrete method to call, jump into it.
|
// After figuring out which concrete method to call, jump into it.
|
||||||
// Note that this works in the interpreter with no data motion.
|
// Note that this works in the interpreter with no data motion.
|
||||||
|
@ -44,11 +44,9 @@ const int ConcreteRegisterImpl::max_pr
|
|||||||
const char* RegisterImpl::name() const {
|
const char* RegisterImpl::name() const {
|
||||||
static const char *const names[number_of_registers] = {
|
static const char *const names[number_of_registers] = {
|
||||||
"c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
|
"c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
|
||||||
"rscratch1", "rscratch2",
|
"rscratch1", "rscratch2", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
"r10", "r11", "r12", "r13", "r14", "r15", "r16",
|
"r16", "r17", "r18_tls", "r19", "resp", "rdispatch", "rbcp", "r23",
|
||||||
"r17", "r18_tls", "r19",
|
"rlocals", "r25", "rcpool", "rheapbase", "rthread", "rfp", "lr", "sp"
|
||||||
"resp", "rdispatch", "rbcp", "r23", "rlocals", "rmonitors", "rcpool", "rheapbase",
|
|
||||||
"rthread", "rfp", "lr", "sp"
|
|
||||||
};
|
};
|
||||||
return is_valid() ? names[encoding()] : "noreg";
|
return is_valid() ? names[encoding()] : "noreg";
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,7 @@ static void gen_c2i_adapter(MacroAssembler *masm,
|
|||||||
|
|
||||||
int extraspace = total_args_passed * Interpreter::stackElementSize;
|
int extraspace = total_args_passed * Interpreter::stackElementSize;
|
||||||
|
|
||||||
__ mov(r13, sp);
|
__ mov(r19_sender_sp, sp);
|
||||||
|
|
||||||
// stack is aligned, keep it that way
|
// stack is aligned, keep it that way
|
||||||
extraspace = align_up(extraspace, 2*wordSize);
|
extraspace = align_up(extraspace, 2*wordSize);
|
||||||
@ -552,12 +552,10 @@ void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
|
|||||||
const BasicType *sig_bt,
|
const BasicType *sig_bt,
|
||||||
const VMRegPair *regs) {
|
const VMRegPair *regs) {
|
||||||
|
|
||||||
// Note: r13 contains the senderSP on entry. We must preserve it since
|
// Note: r19_sender_sp contains the senderSP on entry. We must
|
||||||
// we may do a i2c -> c2i transition if we lose a race where compiled
|
// preserve it since we may do a i2c -> c2i transition if we lose a
|
||||||
// code goes non-entrant while we get args ready.
|
// race where compiled code goes non-entrant while we get args
|
||||||
|
// ready.
|
||||||
// In addition we use r13 to locate all the interpreter args because
|
|
||||||
// we must align the stack to 16 bytes.
|
|
||||||
|
|
||||||
// Adapters are frameless.
|
// Adapters are frameless.
|
||||||
|
|
||||||
|
@ -298,9 +298,9 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
|
|
||||||
// call Java entry -- passing methdoOop, and current sp
|
// call Java entry -- passing methdoOop, and current sp
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r13: sender sp
|
// r19_sender_sp: sender sp
|
||||||
BLOCK_COMMENT("call Java function");
|
BLOCK_COMMENT("call Java function");
|
||||||
__ mov(r13, sp);
|
__ mov(r19_sender_sp, sp);
|
||||||
__ blr(c_rarg4);
|
__ blr(c_rarg4);
|
||||||
|
|
||||||
// we do this here because the notify will already have been done
|
// we do this here because the notify will already have been done
|
||||||
|
@ -146,7 +146,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() {
|
|||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r13: sender sp
|
// r19_sender_sp: sender sp
|
||||||
// esp: args
|
// esp: args
|
||||||
|
|
||||||
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
||||||
@ -174,13 +174,13 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
entry_point = __ pc();
|
entry_point = __ pc();
|
||||||
__ ldrd(v0, Address(esp));
|
__ ldrd(v0, Address(esp));
|
||||||
__ fabsd(v0, v0);
|
__ fabsd(v0, v0);
|
||||||
__ mov(sp, r13); // Restore caller's SP
|
__ mov(sp, r19_sender_sp); // Restore caller's SP
|
||||||
break;
|
break;
|
||||||
case Interpreter::java_lang_math_sqrt:
|
case Interpreter::java_lang_math_sqrt:
|
||||||
entry_point = __ pc();
|
entry_point = __ pc();
|
||||||
__ ldrd(v0, Address(esp));
|
__ ldrd(v0, Address(esp));
|
||||||
__ fsqrtd(v0, v0);
|
__ fsqrtd(v0, v0);
|
||||||
__ mov(sp, r13);
|
__ mov(sp, r19_sender_sp);
|
||||||
break;
|
break;
|
||||||
case Interpreter::java_lang_math_sin :
|
case Interpreter::java_lang_math_sin :
|
||||||
case Interpreter::java_lang_math_cos :
|
case Interpreter::java_lang_math_cos :
|
||||||
@ -190,18 +190,18 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
case Interpreter::java_lang_math_exp :
|
case Interpreter::java_lang_math_exp :
|
||||||
entry_point = __ pc();
|
entry_point = __ pc();
|
||||||
__ ldrd(v0, Address(esp));
|
__ ldrd(v0, Address(esp));
|
||||||
__ mov(sp, r13);
|
__ mov(sp, r19_sender_sp);
|
||||||
__ mov(r19, lr);
|
__ mov(r23, lr);
|
||||||
continuation = r19; // The first callee-saved register
|
continuation = r23; // The first free callee-saved register
|
||||||
generate_transcendental_entry(kind, 1);
|
generate_transcendental_entry(kind, 1);
|
||||||
break;
|
break;
|
||||||
case Interpreter::java_lang_math_pow :
|
case Interpreter::java_lang_math_pow :
|
||||||
entry_point = __ pc();
|
entry_point = __ pc();
|
||||||
__ mov(r19, lr);
|
__ mov(r23, lr);
|
||||||
continuation = r19;
|
continuation = r23;
|
||||||
__ ldrd(v0, Address(esp, 2 * Interpreter::stackElementSize));
|
__ ldrd(v0, Address(esp, 2 * Interpreter::stackElementSize));
|
||||||
__ ldrd(v1, Address(esp));
|
__ ldrd(v1, Address(esp));
|
||||||
__ mov(sp, r13);
|
__ mov(sp, r19_sender_sp);
|
||||||
generate_transcendental_entry(kind, 2);
|
generate_transcendental_entry(kind, 2);
|
||||||
break;
|
break;
|
||||||
case Interpreter::java_lang_math_fmaD :
|
case Interpreter::java_lang_math_fmaD :
|
||||||
@ -211,7 +211,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
__ ldrd(v1, Address(esp, 2 * Interpreter::stackElementSize));
|
__ ldrd(v1, Address(esp, 2 * Interpreter::stackElementSize));
|
||||||
__ ldrd(v2, Address(esp));
|
__ ldrd(v2, Address(esp));
|
||||||
__ fmaddd(v0, v0, v1, v2);
|
__ fmaddd(v0, v0, v1, v2);
|
||||||
__ mov(sp, r13); // Restore caller's SP
|
__ mov(sp, r19_sender_sp); // Restore caller's SP
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Interpreter::java_lang_math_fmaF :
|
case Interpreter::java_lang_math_fmaF :
|
||||||
@ -221,7 +221,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
__ ldrs(v1, Address(esp, Interpreter::stackElementSize));
|
__ ldrs(v1, Address(esp, Interpreter::stackElementSize));
|
||||||
__ ldrs(v2, Address(esp));
|
__ ldrs(v2, Address(esp));
|
||||||
__ fmadds(v0, v0, v1, v2);
|
__ fmadds(v0, v0, v1, v2);
|
||||||
__ mov(sp, r13); // Restore caller's SP
|
__ mov(sp, r19_sender_sp); // Restore caller's SP
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -307,7 +307,7 @@ void TemplateInterpreterGenerator::generate_transcendental_entry(AbstractInterpr
|
|||||||
// Attempt to execute abstract method. Throw exception
|
// Attempt to execute abstract method. Throw exception
|
||||||
address TemplateInterpreterGenerator::generate_abstract_entry(void) {
|
address TemplateInterpreterGenerator::generate_abstract_entry(void) {
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r13: sender SP
|
// r19_sender_sp: sender SP
|
||||||
|
|
||||||
address entry_point = __ pc();
|
address entry_point = __ pc();
|
||||||
|
|
||||||
@ -458,13 +458,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
|||||||
__ add(esp, esp, r1, Assembler::LSL, 3);
|
__ add(esp, esp, r1, Assembler::LSL, 3);
|
||||||
|
|
||||||
// Restore machine SP
|
// Restore machine SP
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
__ restore_sp_after_call();
|
||||||
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
|
||||||
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size() + 2);
|
|
||||||
__ ldr(rscratch2,
|
|
||||||
Address(rfp, frame::interpreter_frame_initial_sp_offset * wordSize));
|
|
||||||
__ sub(rscratch1, rscratch2, rscratch1, ext::uxtw, 3);
|
|
||||||
__ andr(sp, rscratch1, -16);
|
|
||||||
|
|
||||||
__ check_and_handle_popframe(rthread);
|
__ check_and_handle_popframe(rthread);
|
||||||
__ check_and_handle_earlyret(rthread);
|
__ check_and_handle_earlyret(rthread);
|
||||||
@ -485,14 +479,7 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
|
|||||||
__ get_method(rmethod);
|
__ get_method(rmethod);
|
||||||
__ get_dispatch();
|
__ get_dispatch();
|
||||||
|
|
||||||
// Calculate stack limit
|
__ restore_sp_after_call(); // Restore SP to extended SP
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
|
||||||
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
|
||||||
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size() + 2);
|
|
||||||
__ ldr(rscratch2,
|
|
||||||
Address(rfp, frame::interpreter_frame_initial_sp_offset * wordSize));
|
|
||||||
__ sub(rscratch1, rscratch2, rscratch1, ext::uxtx, 3);
|
|
||||||
__ andr(sp, rscratch1, -16);
|
|
||||||
|
|
||||||
// Restore expression stack pointer
|
// Restore expression stack pointer
|
||||||
__ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
__ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||||
@ -715,9 +702,9 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(void) {
|
|||||||
// was in the caller. This is not strictly necessary, but unless we
|
// was in the caller. This is not strictly necessary, but unless we
|
||||||
// do so the stack frame may have a garbage FP; this ensures a
|
// do so the stack frame may have a garbage FP; this ensures a
|
||||||
// correct call stack that we can always unwind. The ANDR should be
|
// correct call stack that we can always unwind. The ANDR should be
|
||||||
// unnecessary because the sender SP in r13 is always aligned, but
|
// unnecessary because the sender SP in r19 is always aligned, but
|
||||||
// it doesn't hurt.
|
// it doesn't hurt.
|
||||||
__ andr(sp, r13, -16);
|
__ andr(sp, r19_sender_sp, -16);
|
||||||
|
|
||||||
// Note: the restored frame is not necessarily interpreted.
|
// Note: the restored frame is not necessarily interpreted.
|
||||||
// Use the shared runtime version of the StackOverflowError.
|
// Use the shared runtime version of the StackOverflowError.
|
||||||
@ -780,10 +767,12 @@ void TemplateInterpreterGenerator::lock_method() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add space for monitor & lock
|
// add space for monitor & lock
|
||||||
|
__ check_extended_sp();
|
||||||
__ sub(sp, sp, entry_size); // add space for a monitor entry
|
__ sub(sp, sp, entry_size); // add space for a monitor entry
|
||||||
__ sub(esp, esp, entry_size);
|
__ sub(esp, esp, entry_size);
|
||||||
__ mov(rscratch1, esp);
|
__ mov(rscratch1, sp);
|
||||||
__ str(rscratch1, monitor_block_top); // set new monitor block top
|
__ str(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
|
||||||
|
__ str(esp, monitor_block_top); // set new monitor block top
|
||||||
// store object
|
// store object
|
||||||
__ str(r0, Address(esp, BasicObjectLock::obj_offset_in_bytes()));
|
__ str(r0, Address(esp, BasicObjectLock::obj_offset_in_bytes()));
|
||||||
__ mov(c_rarg1, esp); // object address
|
__ mov(c_rarg1, esp); // object address
|
||||||
@ -810,7 +799,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
|||||||
__ stp(zr, zr, Address(sp, 12 * wordSize));
|
__ stp(zr, zr, Address(sp, 12 * wordSize));
|
||||||
} else {
|
} else {
|
||||||
__ sub(esp, sp, 12 * wordSize);
|
__ sub(esp, sp, 12 * wordSize);
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod
|
__ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod
|
||||||
__ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
|
__ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
|
||||||
__ stp(esp, rbcp, Address(__ pre(sp, -12 * wordSize)));
|
__ stp(esp, rbcp, Address(__ pre(sp, -12 * wordSize)));
|
||||||
}
|
}
|
||||||
@ -823,13 +812,9 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
|||||||
__ bind(method_data_continue);
|
__ bind(method_data_continue);
|
||||||
__ stp(rscratch1, rmethod, Address(sp, 6 * wordSize)); // save Method* and mdp (method data pointer)
|
__ stp(rscratch1, rmethod, Address(sp, 6 * wordSize)); // save Method* and mdp (method data pointer)
|
||||||
} else {
|
} else {
|
||||||
__ stp(zr, rmethod, Address(sp, 6 * wordSize)); // save Method* (no mdp)
|
__ stp(zr, rmethod, Address(sp, 6 * wordSize)); // save Method* (no mdp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get mirror and store it in the frame as GC root for this Method*
|
|
||||||
__ load_mirror(r10, rmethod);
|
|
||||||
__ stp(r10, zr, Address(sp, 4 * wordSize));
|
|
||||||
|
|
||||||
__ ldr(rcpool, Address(rmethod, Method::const_offset()));
|
__ ldr(rcpool, Address(rmethod, Method::const_offset()));
|
||||||
__ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
|
__ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
|
||||||
__ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset_in_bytes()));
|
__ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset_in_bytes()));
|
||||||
@ -841,15 +826,23 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
|||||||
|
|
||||||
// set sender sp
|
// set sender sp
|
||||||
// leave last_sp as null
|
// leave last_sp as null
|
||||||
__ stp(zr, r13, Address(sp, 8 * wordSize));
|
__ stp(zr, r19_sender_sp, Address(sp, 8 * wordSize));
|
||||||
|
|
||||||
// Move SP out of the way
|
// Get mirror
|
||||||
|
__ load_mirror(r10, rmethod);
|
||||||
if (! native_call) {
|
if (! native_call) {
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
||||||
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
||||||
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size() + 2);
|
__ add(rscratch1, rscratch1, MAX2(3, Method::extra_stack_entries()));
|
||||||
__ sub(rscratch1, sp, rscratch1, ext::uxtw, 3);
|
__ sub(rscratch1, sp, rscratch1, ext::uxtw, 3);
|
||||||
__ andr(sp, rscratch1, -16);
|
__ andr(rscratch1, rscratch1, -16);
|
||||||
|
// Store extended SP and mirror
|
||||||
|
__ stp(r10, rscratch1, Address(sp, 4 * wordSize));
|
||||||
|
// Move SP out of the way
|
||||||
|
__ mov(sp, rscratch1);
|
||||||
|
} else {
|
||||||
|
__ mov(rscratch1, sp);
|
||||||
|
__ stp(zr, rscratch1, Address(sp, 4 * wordSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,7 +893,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
|||||||
// This code is based on generate_accessor_entry.
|
// This code is based on generate_accessor_entry.
|
||||||
//
|
//
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r13: senderSP must preserve for slow path, set SP to it on fast path
|
// r19_sender_sp: senderSP must preserve for slow path, set SP to it on fast path
|
||||||
|
|
||||||
// LR is live. It must be saved around calls.
|
// LR is live. It must be saved around calls.
|
||||||
|
|
||||||
@ -915,15 +908,13 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
|||||||
__ ldr(local_0, Address(esp, 0));
|
__ ldr(local_0, Address(esp, 0));
|
||||||
__ cbz(local_0, slow_path);
|
__ cbz(local_0, slow_path);
|
||||||
|
|
||||||
__ mov(r19, r13); // Move senderSP to a callee-saved register
|
|
||||||
|
|
||||||
// Load the value of the referent field.
|
// Load the value of the referent field.
|
||||||
const Address field_address(local_0, referent_offset);
|
const Address field_address(local_0, referent_offset);
|
||||||
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
bs->load_at(_masm, IN_HEAP | ON_WEAK_OOP_REF, T_OBJECT, local_0, field_address, /*tmp1*/ rscratch2, /*tmp2*/ rscratch1);
|
bs->load_at(_masm, IN_HEAP | ON_WEAK_OOP_REF, T_OBJECT, local_0, field_address, /*tmp1*/ rscratch2, /*tmp2*/ rscratch1);
|
||||||
|
|
||||||
// areturn
|
// areturn
|
||||||
__ andr(sp, r19, -16); // done with stack
|
__ andr(sp, r19_sender_sp, -16); // done with stack
|
||||||
__ ret(lr);
|
__ ret(lr);
|
||||||
|
|
||||||
// generate a vanilla interpreter entry as the slow path
|
// generate a vanilla interpreter entry as the slow path
|
||||||
@ -942,7 +933,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
|||||||
address entry = __ pc();
|
address entry = __ pc();
|
||||||
|
|
||||||
// rmethod: Method*
|
// rmethod: Method*
|
||||||
// r13: senderSP must preserved for slow path
|
// r19_sender_sp: senderSP must preserved for slow path
|
||||||
// esp: args
|
// esp: args
|
||||||
|
|
||||||
Label slow_path;
|
Label slow_path;
|
||||||
@ -971,7 +962,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
|||||||
|
|
||||||
// result in c_rarg0
|
// result in c_rarg0
|
||||||
|
|
||||||
__ andr(sp, r13, -16);
|
__ andr(sp, r19_sender_sp, -16);
|
||||||
__ ret(lr);
|
__ ret(lr);
|
||||||
|
|
||||||
// generate a vanilla native entry as the slow path
|
// generate a vanilla native entry as the slow path
|
||||||
@ -992,7 +983,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
|||||||
address entry = __ pc();
|
address entry = __ pc();
|
||||||
|
|
||||||
// rmethod,: Method*
|
// rmethod,: Method*
|
||||||
// r13: senderSP must preserved for slow path
|
// r19_sender_sp: senderSP must preserved for slow path
|
||||||
|
|
||||||
Label slow_path;
|
Label slow_path;
|
||||||
// If we need a safepoint check, generate full interpreter entry.
|
// If we need a safepoint check, generate full interpreter entry.
|
||||||
@ -1024,7 +1015,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
|||||||
// Can now load 'len' since we're finished with 'off'
|
// Can now load 'len' since we're finished with 'off'
|
||||||
__ ldrw(len, Address(esp, 0x0)); // Length
|
__ ldrw(len, Address(esp, 0x0)); // Length
|
||||||
|
|
||||||
__ andr(sp, r13, -16); // Restore the caller's SP
|
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||||
|
|
||||||
// We are frameless so we can just jump to the stub.
|
// We are frameless so we can just jump to the stub.
|
||||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()));
|
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()));
|
||||||
@ -1068,7 +1059,7 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
|
|||||||
__ ldrw(crc, Address(esp, 3*wordSize)); // long crc
|
__ ldrw(crc, Address(esp, 3*wordSize)); // long crc
|
||||||
}
|
}
|
||||||
|
|
||||||
__ andr(sp, r13, -16); // Restore the caller's SP
|
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||||
|
|
||||||
// Jump to the stub.
|
// Jump to the stub.
|
||||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
|
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
|
||||||
@ -1234,7 +1225,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||||||
__ ldr(rscratch1, monitor_block_top);
|
__ ldr(rscratch1, monitor_block_top);
|
||||||
__ cmp(esp, rscratch1);
|
__ cmp(esp, rscratch1);
|
||||||
__ br(Assembler::EQ, L);
|
__ br(Assembler::EQ, L);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 1");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1532,7 +1523,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||||||
// remove frame anchor
|
// remove frame anchor
|
||||||
__ leave();
|
__ leave();
|
||||||
|
|
||||||
// resture sender sp
|
// restore sender sp
|
||||||
__ mov(sp, esp);
|
__ mov(sp, esp);
|
||||||
|
|
||||||
__ ret(lr);
|
__ ret(lr);
|
||||||
@ -1685,7 +1676,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
|||||||
__ ldr(rscratch1, monitor_block_top);
|
__ ldr(rscratch1, monitor_block_top);
|
||||||
__ cmp(esp, rscratch1);
|
__ cmp(esp, rscratch1);
|
||||||
__ br(Assembler::EQ, L);
|
__ br(Assembler::EQ, L);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 2");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1743,14 +1734,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
|||||||
InterpreterRuntime::exception_handler_for_exception),
|
InterpreterRuntime::exception_handler_for_exception),
|
||||||
c_rarg1);
|
c_rarg1);
|
||||||
|
|
||||||
// Calculate stack limit
|
// Restore machine SP
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
__ restore_sp_after_call();
|
||||||
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
|
||||||
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size() + 4);
|
|
||||||
__ ldr(rscratch2,
|
|
||||||
Address(rfp, frame::interpreter_frame_initial_sp_offset * wordSize));
|
|
||||||
__ sub(rscratch1, rscratch2, rscratch1, ext::uxtx, 3);
|
|
||||||
__ andr(sp, rscratch1, -16);
|
|
||||||
|
|
||||||
// r0: exception handler entry point
|
// r0: exception handler entry point
|
||||||
// r3: preserved exception oop
|
// r3: preserved exception oop
|
||||||
@ -1879,13 +1864,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
|||||||
#endif // INCLUDE_JVMTI
|
#endif // INCLUDE_JVMTI
|
||||||
|
|
||||||
// Restore machine SP
|
// Restore machine SP
|
||||||
__ ldr(rscratch1, Address(rmethod, Method::const_offset()));
|
__ restore_sp_after_call();
|
||||||
__ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset()));
|
|
||||||
__ add(rscratch1, rscratch1, frame::interpreter_frame_monitor_size() + 4);
|
|
||||||
__ ldr(rscratch2,
|
|
||||||
Address(rfp, frame::interpreter_frame_initial_sp_offset * wordSize));
|
|
||||||
__ sub(rscratch1, rscratch2, rscratch1, ext::uxtw, 3);
|
|
||||||
__ andr(sp, rscratch1, -16);
|
|
||||||
|
|
||||||
__ dispatch_next(vtos);
|
__ dispatch_next(vtos);
|
||||||
// end of PopFrame support
|
// end of PopFrame support
|
||||||
|
@ -3827,14 +3827,18 @@ void TemplateTable::monitorenter()
|
|||||||
{
|
{
|
||||||
Label entry, loop;
|
Label entry, loop;
|
||||||
// 1. compute new pointers // rsp: old expression stack top
|
// 1. compute new pointers // rsp: old expression stack top
|
||||||
|
|
||||||
|
__ check_extended_sp();
|
||||||
|
__ sub(sp, sp, entry_size); // make room for the monitor
|
||||||
|
__ mov(rscratch1, sp);
|
||||||
|
__ str(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
|
||||||
|
|
||||||
__ ldr(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom
|
__ ldr(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom
|
||||||
__ sub(esp, esp, entry_size); // move expression stack top
|
__ sub(esp, esp, entry_size); // move expression stack top
|
||||||
__ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom
|
__ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom
|
||||||
__ mov(c_rarg3, esp); // set start value for copy loop
|
__ mov(c_rarg3, esp); // set start value for copy loop
|
||||||
__ str(c_rarg1, monitor_block_bot); // set new monitor block bottom
|
__ str(c_rarg1, monitor_block_bot); // set new monitor block bottom
|
||||||
|
|
||||||
__ sub(sp, sp, entry_size); // make room for the monitor
|
|
||||||
|
|
||||||
__ b(entry);
|
__ b(entry);
|
||||||
// 2. move expression stack contents
|
// 2. move expression stack contents
|
||||||
__ bind(loop);
|
__ bind(loop);
|
||||||
|
@ -893,7 +893,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||||||
__ ldr(Rtemp, Address(FP, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
__ ldr(Rtemp, Address(FP, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
||||||
__ cmp(Rtemp, Rstack_top);
|
__ cmp(Rtemp, Rstack_top);
|
||||||
__ b(L, eq);
|
__ b(L, eq);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 3");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1247,7 +1247,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
|||||||
__ ldr(Rtemp, Address(FP, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
__ ldr(Rtemp, Address(FP, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
||||||
__ cmp(Rtemp, Rstack_top);
|
__ cmp(Rtemp, Rstack_top);
|
||||||
__ b(L, eq);
|
__ b(L, eq);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 4");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -907,7 +907,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||||||
__ movptr(rax, monitor_block_top);
|
__ movptr(rax, monitor_block_top);
|
||||||
__ cmpptr(rax, rsp);
|
__ cmpptr(rax, rsp);
|
||||||
__ jcc(Assembler::equal, L);
|
__ jcc(Assembler::equal, L);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 5");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1461,7 +1461,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
|||||||
__ movptr(rax, monitor_block_top);
|
__ movptr(rax, monitor_block_top);
|
||||||
__ cmpptr(rax, rsp);
|
__ cmpptr(rax, rsp);
|
||||||
__ jcc(Assembler::equal, L);
|
__ jcc(Assembler::equal, L);
|
||||||
__ stop("broken stack frame setup in interpreter");
|
__ stop("broken stack frame setup in interpreter 6");
|
||||||
__ bind(L);
|
__ bind(L);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user