mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8155980: ARM InterpreterMacroAssembler::get_method_counters() should not be saving caller saved registers
Make get_method_counters() only save registers specified by caller, not all of them Reviewed-by: dlong, jiangli
This commit is contained in:
parent
7519b299b3
commit
57f866aaeb
5 changed files with 56 additions and 65 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -234,8 +234,15 @@ void AbstractInterpreter::layout_activation(Method* method,
|
||||||
#ifdef AARCH64
|
#ifdef AARCH64
|
||||||
interpreter_frame->interpreter_frame_set_stack_top(stack_top);
|
interpreter_frame->interpreter_frame_set_stack_top(stack_top);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// -3 reserved slots so get_method_counters() can save some registers before call_VM().
|
||||||
|
int max_stack = method->constMethod()->max_stack() + MAX2(3, Method::extra_stack_entries());
|
||||||
intptr_t* extended_sp = (intptr_t*) monbot -
|
intptr_t* extended_sp = (intptr_t*) monbot -
|
||||||
(method->max_stack() + 1) * Interpreter::stackElementWords - // +1 is reserved slot for exception handler
|
(max_stack * Interpreter::stackElementWords) -
|
||||||
popframe_extra_args;
|
popframe_extra_args;
|
||||||
extended_sp = (intptr_t*)round_down((intptr_t)extended_sp, StackAlignmentInBytes);
|
extended_sp = (intptr_t*)round_down((intptr_t)extended_sp, StackAlignmentInBytes);
|
||||||
interpreter_frame->interpreter_frame_set_extended_sp(extended_sp);
|
interpreter_frame->interpreter_frame_set_extended_sp(extended_sp);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2195,75 +2195,42 @@ void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
|
||||||
|
|
||||||
void InterpreterMacroAssembler::get_method_counters(Register method,
|
void InterpreterMacroAssembler::get_method_counters(Register method,
|
||||||
Register Rcounters,
|
Register Rcounters,
|
||||||
Label& skip) {
|
Label& skip,
|
||||||
|
bool saveRegs,
|
||||||
|
Register reg1,
|
||||||
|
Register reg2,
|
||||||
|
Register reg3) {
|
||||||
const Address method_counters(method, Method::method_counters_offset());
|
const Address method_counters(method, Method::method_counters_offset());
|
||||||
Label has_counters;
|
Label has_counters;
|
||||||
|
|
||||||
ldr(Rcounters, method_counters);
|
ldr(Rcounters, method_counters);
|
||||||
cbnz(Rcounters, has_counters);
|
cbnz(Rcounters, has_counters);
|
||||||
|
|
||||||
|
if (saveRegs) {
|
||||||
|
// Save and restore in use caller-saved registers since they will be trashed by call_VM
|
||||||
|
assert(reg1 != noreg, "must specify reg1");
|
||||||
|
assert(reg2 != noreg, "must specify reg2");
|
||||||
#ifdef AARCH64
|
#ifdef AARCH64
|
||||||
const Register tmp = Rcounters;
|
assert(reg3 != noreg, "must specify reg3");
|
||||||
const int saved_regs_size = 20*wordSize;
|
stp(reg1, reg2, Address(Rstack_top, -2*wordSize, pre_indexed));
|
||||||
|
stp(reg3, ZR, Address(Rstack_top, -2*wordSize, pre_indexed));
|
||||||
// Note: call_VM will cut SP according to Rstack_top value before call, and restore SP to
|
|
||||||
// extended_sp value from frame after the call.
|
|
||||||
// So make sure there is enough stack space to save registers and adjust Rstack_top accordingly.
|
|
||||||
{
|
|
||||||
Label enough_stack_space;
|
|
||||||
check_extended_sp(tmp);
|
|
||||||
sub(Rstack_top, Rstack_top, saved_regs_size);
|
|
||||||
cmp(SP, Rstack_top);
|
|
||||||
b(enough_stack_space, ls);
|
|
||||||
|
|
||||||
align_reg(tmp, Rstack_top, StackAlignmentInBytes);
|
|
||||||
mov(SP, tmp);
|
|
||||||
str(tmp, Address(FP, frame::interpreter_frame_extended_sp_offset * wordSize));
|
|
||||||
|
|
||||||
bind(enough_stack_space);
|
|
||||||
check_stack_top();
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
stp(R0, R1, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R2, R3, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R4, R5, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R6, R7, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R8, R9, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
stp(R18, LR, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
assert (offset == saved_regs_size, "should be");
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
push(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
|
assert(reg3 == noreg, "must not specify reg3");
|
||||||
#endif // AARCH64
|
push(RegisterSet(reg1) | RegisterSet(reg2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
mov(R1, method);
|
mov(R1, method);
|
||||||
call_VM(noreg, CAST_FROM_FN_PTR(address,
|
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), R1);
|
||||||
InterpreterRuntime::build_method_counters), R1);
|
|
||||||
|
|
||||||
|
if (saveRegs) {
|
||||||
#ifdef AARCH64
|
#ifdef AARCH64
|
||||||
{
|
ldp(reg3, ZR, Address(Rstack_top, 2*wordSize, post_indexed));
|
||||||
int offset = 0;
|
ldp(reg1, reg2, Address(Rstack_top, 2*wordSize, post_indexed));
|
||||||
ldp(R0, R1, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R2, R3, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R4, R5, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R6, R7, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R8, R9, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
ldp(R18, LR, Address(Rstack_top, offset)); offset += 2*wordSize;
|
|
||||||
assert (offset == saved_regs_size, "should be");
|
|
||||||
|
|
||||||
add(Rstack_top, Rstack_top, saved_regs_size);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
pop(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
|
pop(RegisterSet(reg1) | RegisterSet(reg2));
|
||||||
#endif // AARCH64
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
ldr(Rcounters, method_counters);
|
ldr(Rcounters, method_counters);
|
||||||
cbz(Rcounters, skip); // No MethodCounters created, OutOfMemory
|
cbz(Rcounters, skip); // No MethodCounters created, OutOfMemory
|
||||||
|
|
|
@ -349,7 +349,13 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||||
|
|
||||||
void trace_state(const char* msg) PRODUCT_RETURN;
|
void trace_state(const char* msg) PRODUCT_RETURN;
|
||||||
|
|
||||||
void get_method_counters(Register method, Register Rcounters, Label& skip);
|
void get_method_counters(Register method,
|
||||||
|
Register Rcounters,
|
||||||
|
Label& skip,
|
||||||
|
bool saveRegs = false,
|
||||||
|
Register reg1 = noreg,
|
||||||
|
Register reg2 = noreg,
|
||||||
|
Register reg3 = noreg);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPU_ARM_VM_INTERP_MASM_ARM_HPP
|
#endif // CPU_ARM_VM_INTERP_MASM_ARM_HPP
|
||||||
|
|
|
@ -1401,7 +1401,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||||
#ifdef AARCH64
|
#ifdef AARCH64
|
||||||
// setup RmaxStack
|
// setup RmaxStack
|
||||||
__ ldrh(RmaxStack, Address(RconstMethod, ConstMethod::max_stack_offset()));
|
__ ldrh(RmaxStack, Address(RconstMethod, ConstMethod::max_stack_offset()));
|
||||||
__ add(RmaxStack, RmaxStack, MAX2(1, Method::extra_stack_entries())); // reserve slots for exception handler and JSR292 appendix argument
|
// 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.
|
||||||
|
// -3 reserved slots so get_method_counters() can save some registers before call_VM().
|
||||||
|
__ add(RmaxStack, RmaxStack, MAX2(3, Method::extra_stack_entries()));
|
||||||
#endif // AARCH64
|
#endif // AARCH64
|
||||||
|
|
||||||
// see if we've got enough room on the stack for locals plus overhead.
|
// see if we've got enough room on the stack for locals plus overhead.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2286,13 +2286,18 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
|
||||||
}
|
}
|
||||||
__ bind(no_mdo);
|
__ bind(no_mdo);
|
||||||
// Increment backedge counter in MethodCounters*
|
// Increment backedge counter in MethodCounters*
|
||||||
__ get_method_counters(Rmethod, Rcounters, dispatch);
|
// Note Rbumped_taken_count is a callee saved registers for ARM32, but caller saved for ARM64
|
||||||
|
__ get_method_counters(Rmethod, Rcounters, dispatch, true /*saveRegs*/,
|
||||||
|
Rdisp, R3_bytecode,
|
||||||
|
AARCH64_ONLY(Rbumped_taken_count) NOT_AARCH64(noreg));
|
||||||
const Address mask(Rcounters, in_bytes(MethodCounters::backedge_mask_offset()));
|
const Address mask(Rcounters, in_bytes(MethodCounters::backedge_mask_offset()));
|
||||||
__ increment_mask_and_jump(Address(Rcounters, be_offset), increment, mask,
|
__ increment_mask_and_jump(Address(Rcounters, be_offset), increment, mask,
|
||||||
Rcnt, R4_tmp, eq, &backedge_counter_overflow);
|
Rcnt, R4_tmp, eq, &backedge_counter_overflow);
|
||||||
} else {
|
} else {
|
||||||
// increment counter
|
// Increment backedge counter in MethodCounters*
|
||||||
__ get_method_counters(Rmethod, Rcounters, dispatch);
|
__ get_method_counters(Rmethod, Rcounters, dispatch, true /*saveRegs*/,
|
||||||
|
Rdisp, R3_bytecode,
|
||||||
|
AARCH64_ONLY(Rbumped_taken_count) NOT_AARCH64(noreg));
|
||||||
__ ldr_u32(Rtemp, Address(Rcounters, be_offset)); // load backedge counter
|
__ ldr_u32(Rtemp, Address(Rcounters, be_offset)); // load backedge counter
|
||||||
__ add(Rtemp, Rtemp, InvocationCounter::count_increment); // increment counter
|
__ add(Rtemp, Rtemp, InvocationCounter::count_increment); // increment counter
|
||||||
__ str_32(Rtemp, Address(Rcounters, be_offset)); // store counter
|
__ str_32(Rtemp, Address(Rcounters, be_offset)); // store counter
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue