8256205: Simplify compiler calling convention handling

Reviewed-by: kvn, neliasso
This commit is contained in:
Claes Redestad 2020-11-16 19:39:36 +00:00
parent 68fd71d2ad
commit 6e35bcbf03
31 changed files with 104 additions and 305 deletions

@ -4099,13 +4099,6 @@ frame %{
// Stack alignment requirement // Stack alignment requirement
stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. aarch64 needs two slots for
// return address and fp.
// TODO think this is correct but check
in_preserve_stack_slots(4);
// Number of outgoing stack slots killed above the out_preserve_stack_slots // Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms. // for calls to C. Supports the var-args backing area for register parms.
varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
@ -4124,25 +4117,6 @@ frame %{
Compile::current()->fixed_slots()), Compile::current()->fixed_slots()),
stack_alignment_in_slots())); stack_alignment_in_slots()));
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
calling_convention
%{
// No difference between ingoing/outgoing just pass false
SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
%}
c_calling_convention
%{
// This is obviously always outgoing
(void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length);
%}
// Location of compiled Java return values. Same as C for now. // Location of compiled Java return values. Same as C for now.
return_value return_value
%{ %{

@ -323,7 +323,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
// //
VMRegPair args[5]; VMRegPair args[5];
BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT}; BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT};
SharedRuntime::java_calling_convention(signature, args, 5, true); SharedRuntime::java_calling_convention(signature, args, 5);
// push parameters // push parameters
// (src, src_pos, dest, destPos, length) // (src, src_pos, dest, destPos, length)

@ -290,7 +290,7 @@ void FrameMap::initialize() {
VMRegPair regs; VMRegPair regs;
BasicType sig_bt = T_OBJECT; BasicType sig_bt = T_OBJECT;
SharedRuntime::java_calling_convention(&sig_bt, &regs, 1, true); SharedRuntime::java_calling_convention(&sig_bt, &regs, 1);
receiver_opr = as_oop_opr(regs.first()->as_Register()); receiver_opr = as_oop_opr(regs.first()->as_Register());
for (int i = 0; i < nof_caller_save_fpu_regs; i++) { for (int i = 0; i < nof_caller_save_fpu_regs; i++) {

@ -276,8 +276,7 @@ static int reg2offset_out(VMReg r) {
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
// Create the mapping between argument positions and // Create the mapping between argument positions and
// registers. // registers.
@ -2522,6 +2521,15 @@ void SharedRuntime::generate_deopt_blob() {
#endif #endif
} }
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. aarch64 needs two slots for
// return address and fp.
// TODO think this is correct but check
uint SharedRuntime::in_preserve_stack_slots() {
return 4;
}
uint SharedRuntime::out_preserve_stack_slots() { uint SharedRuntime::out_preserve_stack_slots() {
return 0; return 0;
} }

@ -1673,12 +1673,6 @@ frame %{
// LP64: Alignment size in bytes (128-bit -> 16 bytes) // LP64: Alignment size in bytes (128-bit -> 16 bytes)
// !LP64: Alignment size in bytes (64-bit -> 8 bytes) // !LP64: Alignment size in bytes (64-bit -> 8 bytes)
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots.
// FP + LR
in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
// Number of outgoing stack slots killed above the out_preserve_stack_slots // Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms. // for calls to C. Supports the var-args backing area for register parms.
// ADLC doesn't support parsing expressions, so I folded the math by hand. // ADLC doesn't support parsing expressions, so I folded the math by hand.
@ -1695,22 +1689,6 @@ frame %{
Compile::current()->fixed_slots()), Compile::current()->fixed_slots()),
stack_alignment_in_slots())); stack_alignment_in_slots()));
// Body of function which returns an OptoRegs array locating
// arguments either in registers or in stack slots for calling
// java
calling_convention %{
(void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
%}
// Body of function which returns an OptoRegs array locating
// arguments either in registers or in stack slots for callin
// C.
c_calling_convention %{
// This is obviously always outgoing
(void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
%}
// Location of compiled Java return values. Same as C // Location of compiled Java return values. Same as C
return_value %{ return_value %{
return c2::return_value(ideal_reg); return c2::return_value(ideal_reg);

@ -421,7 +421,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
VMRegPair args[5]; VMRegPair args[5];
BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT }; BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT };
SharedRuntime::java_calling_convention(signature, args, 5, true); SharedRuntime::java_calling_convention(signature, args, 5);
Register r[5]; Register r[5];
r[0] = src()->as_pointer_register(); r[0] = src()->as_pointer_register();

@ -364,13 +364,11 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
#ifdef __SOFTFP__ #ifdef __SOFTFP__
// soft float is the same as the C calling convention. // soft float is the same as the C calling convention.
return c_calling_convention(sig_bt, regs, NULL, total_args_passed); return c_calling_convention(sig_bt, regs, NULL, total_args_passed);
#endif // __SOFTFP__ #endif // __SOFTFP__
(void) is_outgoing;
int slot = 0; int slot = 0;
int ireg = 0; int ireg = 0;
int freg = 0; int freg = 0;
@ -1371,11 +1369,18 @@ int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals)
} }
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots.
// FP + LR
uint SharedRuntime::in_preserve_stack_slots() {
return 2 * VMRegImpl::slots_per_word;
}
uint SharedRuntime::out_preserve_stack_slots() { uint SharedRuntime::out_preserve_stack_slots() {
return 0; return 0;
} }
//------------------------------generate_deopt_blob---------------------------- //------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() { void SharedRuntime::generate_deopt_blob() {
ResourceMark rm; ResourceMark rm;

@ -3848,8 +3848,6 @@ frame %{
stack_alignment(frame::alignment_in_bytes); stack_alignment(frame::alignment_in_bytes);
in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size));
// Number of outgoing stack slots killed above the // Number of outgoing stack slots killed above the
// out_preserve_stack_slots for calls to C. Supports the var-args // out_preserve_stack_slots for calls to C. Supports the var-args
// backing area for register parms. // backing area for register parms.
@ -3874,40 +3872,6 @@ frame %{
// 4 what apparently works and saves us some spills. // 4 what apparently works and saves us some spills.
return_addr(STACK 4); return_addr(STACK 4);
// This is the body of the function
//
// void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs
// uint length, // length of array
// bool is_outgoing)
//
// The `sig' array is to be updated. sig[j] represents the location
// of the j-th argument, either a register or a stack slot.
// Comment taken from x86_32.ad:
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
calling_convention %{
// No difference between ingoing/outgoing. Just pass false.
SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
%}
// Comment taken from x86_32.ad:
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
c_calling_convention %{
// This is obviously always outgoing.
// C argument in register AND stack slot.
(void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
%}
// Location of native (C/C++) and interpreter return values. This // Location of native (C/C++) and interpreter return values. This
// is specified to be the same as Java. In the 32-bit VM, long // is specified to be the same as Java. In the 32-bit VM, long
// values are actually returned from native calls in O0:O1 and // values are actually returned from native calls in O0:O1 and

@ -633,8 +633,7 @@ const int num_java_farg_registers = sizeof(java_farg_reg) / sizeof(java_farg_reg
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
// C2c calling conventions for compiled-compiled calls. // C2c calling conventions for compiled-compiled calls.
// Put 8 ints/longs into registers _AND_ 13 float/doubles into // Put 8 ints/longs into registers _AND_ 13 float/doubles into
// registers _AND_ put the rest on the stack. // registers _AND_ put the rest on the stack.
@ -2511,6 +2510,10 @@ int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals)
return align_up((callee_locals - callee_parameters) * Interpreter::stackElementWords, frame::alignment_in_bytes); return align_up((callee_locals - callee_parameters) * Interpreter::stackElementWords, frame::alignment_in_bytes);
} }
uint SharedRuntime::in_preserve_stack_slots() {
return frame::jit_in_preserve_size / VMRegImpl::stack_slot_size;
}
uint SharedRuntime::out_preserve_stack_slots() { uint SharedRuntime::out_preserve_stack_slots() {
#if defined(COMPILER1) || defined(COMPILER2) #if defined(COMPILER1) || defined(COMPILER2)
return frame::jit_out_preserve_size / VMRegImpl::stack_slot_size; return frame::jit_out_preserve_size / VMRegImpl::stack_slot_size;

@ -2449,8 +2449,6 @@ frame %{
// Use alignment_in_bytes instead of log_2_of_alignment_in_bits. // Use alignment_in_bytes instead of log_2_of_alignment_in_bits.
stack_alignment(frame::alignment_in_bytes); stack_alignment(frame::alignment_in_bytes);
in_preserve_stack_slots(frame::jit_in_preserve_size_in_4_byte_units);
// A `slot' is assumed 4 bytes here! // A `slot' is assumed 4 bytes here!
// out_preserve_stack_slots(frame::jit_out_preserve_size_in_4_byte_units); // out_preserve_stack_slots(frame::jit_out_preserve_size_in_4_byte_units);
@ -2465,38 +2463,6 @@ frame %{
// stack slot. // stack slot.
return_addr(REG Z_R14); return_addr(REG Z_R14);
// This is the body of the function
//
// void Matcher::calling_convention(OptoRegPair* sig /* array of ideal regs */,
// uint length /* length of array */,
// bool is_outgoing)
//
// The `sig' array is to be updated. Sig[j] represents the location
// of the j-th argument, either a register or a stack slot.
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
calling_convention %{
// No difference between ingoing/outgoing just pass false.
SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
%}
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
c_calling_convention %{
// This is obviously always outgoing.
// C argument must be in register AND stack slot.
(void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
%}
// Location of native (C/C++) and interpreter return values. This // Location of native (C/C++) and interpreter return values. This
// is specified to be the same as Java. In the 32-bit VM, long // is specified to be the same as Java. In the 32-bit VM, long
// values are actually returned from native calls in O0:O1 and // values are actually returned from native calls in O0:O1 and

@ -649,8 +649,7 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm,
// advantage out of it. // advantage out of it.
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
// c2c calling conventions for compiled-compiled calls. // c2c calling conventions for compiled-compiled calls.
// An int/float occupies 1 slot here. // An int/float occupies 1 slot here.
@ -2579,6 +2578,10 @@ int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals)
frame::z_parent_ijava_frame_abi_size / BytesPerWord; frame::z_parent_ijava_frame_abi_size / BytesPerWord;
} }
uint SharedRuntime::in_preserve_stack_slots() {
return frame::jit_in_preserve_size_in_4_byte_units;
}
uint SharedRuntime::out_preserve_stack_slots() { uint SharedRuntime::out_preserve_stack_slots() {
return frame::z_jit_out_preserve_size/VMRegImpl::stack_slot_size; return frame::z_jit_out_preserve_size/VMRegImpl::stack_slot_size;
} }

@ -509,7 +509,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
// //
VMRegPair args[5]; VMRegPair args[5];
BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT}; BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT};
SharedRuntime::java_calling_convention(signature, args, 5, true); SharedRuntime::java_calling_convention(signature, args, 5);
// push parameters // push parameters
// (src, src_pos, dest, destPos, length) // (src, src_pos, dest, destPos, length)

@ -299,7 +299,7 @@ void FrameMap::initialize() {
VMRegPair regs; VMRegPair regs;
BasicType sig_bt = T_OBJECT; BasicType sig_bt = T_OBJECT;
SharedRuntime::java_calling_convention(&sig_bt, &regs, 1, true); SharedRuntime::java_calling_convention(&sig_bt, &regs, 1);
receiver_opr = as_oop_opr(regs.first()->as_Register()); receiver_opr = as_oop_opr(regs.first()->as_Register());
} }

@ -418,8 +418,7 @@ static int reg2offset_out(VMReg r) {
// the doubles will grab the registers before the floats will. // the doubles will grab the registers before the floats will.
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
uint stack = 0; // Starting stack position for args on stack uint stack = 0; // Starting stack position for args on stack
@ -2199,6 +2198,14 @@ int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals )
} }
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. Intel needs one slot for
// return address and one for rbp, (must save rbp)
uint SharedRuntime::in_preserve_stack_slots() {
return 2+VerifyStackAtCalls;
}
uint SharedRuntime::out_preserve_stack_slots() { uint SharedRuntime::out_preserve_stack_slots() {
return 0; return 0;
} }

@ -451,8 +451,7 @@ static int reg2offset_out(VMReg r) {
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
// Create the mapping between argument positions and // Create the mapping between argument positions and
// registers. // registers.
@ -2592,6 +2591,15 @@ uint SharedRuntime::out_preserve_stack_slots() {
return 0; return 0;
} }
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. amd64 needs two slots for
// return address.
uint SharedRuntime::in_preserve_stack_slots() {
return 4 + 2 * VerifyStackAtCalls;
}
//------------------------------generate_deopt_blob---------------------------- //------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() { void SharedRuntime::generate_deopt_blob() {
// Allocate space for the code // Allocate space for the code

@ -3159,12 +3159,6 @@ frame %{
// Alignment size in bytes (128-bit -> 16 bytes) // Alignment size in bytes (128-bit -> 16 bytes)
stack_alignment(StackAlignmentInBytes); stack_alignment(StackAlignmentInBytes);
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. Intel needs one slot for
// return address and one for rbp, (must save rbp)
in_preserve_stack_slots(2+VerifyStackAtCalls);
// Number of outgoing stack slots killed above the out_preserve_stack_slots // Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms. // for calls to C. Supports the var-args backing area for register parms.
varargs_C_out_slots_killed(0); varargs_C_out_slots_killed(0);
@ -3180,29 +3174,6 @@ frame %{
Compile::current()->fixed_slots()), Compile::current()->fixed_slots()),
stack_alignment_in_slots())); stack_alignment_in_slots()));
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
calling_convention %{
// No difference between ingoing/outgoing just pass false
SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
%}
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
c_calling_convention %{
// This is obviously always outgoing
(void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
%}
// Location of C & interpreter return values // Location of C & interpreter return values
c_return_value %{ c_return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );

@ -2756,12 +2756,6 @@ frame
// Stack alignment requirement // Stack alignment requirement
stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
// Number of stack slots between incoming argument block and the start of
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. amd64 needs two slots for
// return address.
in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
// Number of outgoing stack slots killed above the out_preserve_stack_slots // Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms. // for calls to C. Supports the var-args backing area for register parms.
varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
@ -2777,25 +2771,6 @@ frame
Compile::current()->fixed_slots()), Compile::current()->fixed_slots()),
stack_alignment_in_slots())); stack_alignment_in_slots()));
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
// of ideal registers called "sig" and a "length" count. Stack-slot
// offsets are based on outgoing arguments, i.e. a CALLER setting up
// arguments for a CALLEE. Incoming stack arguments are
// automatically biased by the preserve_stack_slots field above.
calling_convention
%{
// No difference between ingoing/outgoing just pass false
SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
%}
c_calling_convention
%{
// This is obviously always outgoing
(void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
%}
// Location of compiled Java return values. Same as C for now. // Location of compiled Java return values. Same as C for now.
return_value return_value
%{ %{

@ -51,8 +51,7 @@ static address zero_null_code_stub() {
int SharedRuntime::java_calling_convention(const BasicType *sig_bt, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
int total_args_passed, int total_args_passed) {
int is_outgoing) {
return 0; return 0;
} }

@ -1019,7 +1019,8 @@ void ADLParser::frame_parse(void) {
return_addr_parse(frame, false); return_addr_parse(frame, false);
} }
if (strcmp(token,"in_preserve_stack_slots")==0) { if (strcmp(token,"in_preserve_stack_slots")==0) {
preserve_stack_parse(frame); parse_err(WARN, "Using obsolete token, in_preserve_stack_slots");
skipws();
} }
if (strcmp(token,"out_preserve_stack_slots")==0) { if (strcmp(token,"out_preserve_stack_slots")==0) {
parse_err(WARN, "Using obsolete token, out_preserve_stack_slots"); parse_err(WARN, "Using obsolete token, out_preserve_stack_slots");
@ -1029,7 +1030,8 @@ void ADLParser::frame_parse(void) {
frame->_varargs_C_out_slots_killed = parse_one_arg("varargs C out slots killed"); frame->_varargs_C_out_slots_killed = parse_one_arg("varargs C out slots killed");
} }
if (strcmp(token,"calling_convention")==0) { if (strcmp(token,"calling_convention")==0) {
frame->_calling_convention = calling_convention_parse(); parse_err(WARN, "Using obsolete token, calling_convention");
skipws();
} }
if (strcmp(token,"return_value")==0) { if (strcmp(token,"return_value")==0) {
frame->_return_value = return_value_parse(); frame->_return_value = return_value_parse();
@ -1041,7 +1043,8 @@ void ADLParser::frame_parse(void) {
return_addr_parse(frame, true); return_addr_parse(frame, true);
} }
if (strcmp(token,"c_calling_convention")==0) { if (strcmp(token,"c_calling_convention")==0) {
frame->_c_calling_convention = calling_convention_parse(); parse_err(WARN, "Using obsolete token, c_calling_convention");
skipws();
} }
if (strcmp(token,"c_return_value")==0) { if (strcmp(token,"c_return_value")==0) {
frame->_c_return_value = return_value_parse(); frame->_c_return_value = return_value_parse();
@ -1072,18 +1075,10 @@ void ADLParser::frame_parse(void) {
parse_err(SYNERR, "missing return address location in frame section.\n"); parse_err(SYNERR, "missing return address location in frame section.\n");
return; return;
} }
if(frame->_in_preserve_slots == NULL) {
parse_err(SYNERR, "missing stack slot preservation definition in frame section.\n");
return;
}
if(frame->_varargs_C_out_slots_killed == NULL) { if(frame->_varargs_C_out_slots_killed == NULL) {
parse_err(SYNERR, "missing varargs C out slots killed definition in frame section.\n"); parse_err(SYNERR, "missing varargs C out slots killed definition in frame section.\n");
return; return;
} }
if(frame->_calling_convention == NULL) {
parse_err(SYNERR, "missing calling convention definition in frame section.\n");
return;
}
if(frame->_return_value == NULL) { if(frame->_return_value == NULL) {
parse_err(SYNERR, "missing return value definition in frame section.\n"); parse_err(SYNERR, "missing return value definition in frame section.\n");
return; return;
@ -1096,9 +1091,6 @@ void ADLParser::frame_parse(void) {
frame->_c_return_addr = frame->_return_addr; frame->_c_return_addr = frame->_return_addr;
frame->_c_return_addr_loc = frame->_return_addr_loc; frame->_c_return_addr_loc = frame->_return_addr_loc;
} }
if(frame->_c_calling_convention == NULL) {
frame->_c_calling_convention = frame->_calling_convention;
}
if(frame->_c_return_value == NULL) { if(frame->_c_return_value == NULL) {
frame->_c_return_value = frame->_return_value; frame->_c_return_value = frame->_return_value;
} }
@ -1221,37 +1213,9 @@ void ADLParser::return_addr_parse(FrameForm *frame, bool native) {
} }
} }
//------------------------------preserve_stack_parse---------------------------
void ADLParser::preserve_stack_parse(FrameForm *frame) {
if(_curchar == '(') {
char *token = get_paren_expr("preserve_stack_slots");
frame->_in_preserve_slots = token;
if(_curchar != ';') { // check for semi-colon
parse_err(SYNERR, "missing %c in preserve stack slot entry.\n", ';');
return;
}
next_char(); // skip the semi-colon
}
else {
parse_err(SYNERR, "Missing %c in preserve stack slot entry.\n", '(');
}
}
//------------------------------calling_convention_parse-----------------------
char *ADLParser::calling_convention_parse() {
char *desc = NULL; // String representation of calling_convention
skipws(); // Skip leading whitespace
if ( (desc = find_cpp_block("calling convention block")) == NULL ) {
parse_err(SYNERR, "incorrect or missing block for 'calling_convention'.\n");
}
return desc;
}
//------------------------------return_value_parse----------------------------- //------------------------------return_value_parse-----------------------------
char *ADLParser::return_value_parse() { char *ADLParser::return_value_parse() {
char *desc = NULL; // String representation of calling_convention char *desc = NULL; // String representation of return_value
skipws(); // Skip leading whitespace skipws(); // Skip leading whitespace
if ( (desc = find_cpp_block("return value block")) == NULL ) { if ( (desc = find_cpp_block("return value block")) == NULL ) {

@ -119,8 +119,6 @@ protected:
void cisc_spilling_operand_name_parse(FrameForm *frame, bool native); void cisc_spilling_operand_name_parse(FrameForm *frame, bool native);
void stack_alignment_parse(FrameForm *frame); void stack_alignment_parse(FrameForm *frame);
void return_addr_parse(FrameForm *frame, bool native); void return_addr_parse(FrameForm *frame, bool native);
void preserve_stack_parse(FrameForm *frame);
char *calling_convention_parse();
char *return_value_parse(); char *return_value_parse();
// Parse components of the register section // Parse components of the register section

@ -441,10 +441,7 @@ FrameForm::FrameForm() {
_alignment = NULL; _alignment = NULL;
_return_addr = NULL; _return_addr = NULL;
_c_return_addr = NULL; _c_return_addr = NULL;
_in_preserve_slots = NULL;
_varargs_C_out_slots_killed = NULL; _varargs_C_out_slots_killed = NULL;
_calling_convention = NULL;
_c_calling_convention = NULL;
_return_value = NULL; _return_value = NULL;
_c_return_value = NULL; _c_return_value = NULL;
_interpreter_frame_pointer_reg = NULL; _interpreter_frame_pointer_reg = NULL;

@ -345,10 +345,7 @@ public:
bool _c_return_addr_loc; bool _c_return_addr_loc;
char *_return_addr; char *_return_addr;
char *_c_return_addr; char *_c_return_addr;
char *_in_preserve_slots;
char *_varargs_C_out_slots_killed; char *_varargs_C_out_slots_killed;
char *_calling_convention;
char *_c_calling_convention;
char *_return_value; char *_return_value;
char *_c_return_value; char *_c_return_value;

@ -4158,29 +4158,15 @@ void ArchDesc::buildFrameMethods(FILE *fp_cpp) {
fprintf(fp_cpp," return OptoReg::stack2reg(%s); }\n\n", fprintf(fp_cpp," return OptoReg::stack2reg(%s); }\n\n",
_frame->_return_addr); _frame->_return_addr);
} }
// Java Stack Slot Preservation
fprintf(fp_cpp,"uint Compile::in_preserve_stack_slots() ");
fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_in_preserve_slots);
// Top Of Stack Slot Preservation, for both Java and C
fprintf(fp_cpp,"uint Compile::out_preserve_stack_slots() ");
fprintf(fp_cpp,"{ return SharedRuntime::out_preserve_stack_slots(); }\n\n");
// varargs C out slots killed // varargs C out slots killed
fprintf(fp_cpp,"uint Compile::varargs_C_out_slots_killed() const "); fprintf(fp_cpp,"uint Compile::varargs_C_out_slots_killed() const ");
fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_varargs_C_out_slots_killed); fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_varargs_C_out_slots_killed);
// Java Argument Position
fprintf(fp_cpp,"void Matcher::calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length, bool is_outgoing) {\n");
fprintf(fp_cpp,"%s\n", _frame->_calling_convention);
fprintf(fp_cpp,"}\n\n");
// Native Argument Position
fprintf(fp_cpp,"void Matcher::c_calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length) {\n");
fprintf(fp_cpp,"%s\n", _frame->_c_calling_convention);
fprintf(fp_cpp,"}\n\n");
// Java Return Value Location // Java Return Value Location
fprintf(fp_cpp,"OptoRegPair Matcher::return_value(uint ideal_reg, bool is_outgoing) {\n"); fprintf(fp_cpp,"OptoRegPair Matcher::return_value(uint ideal_reg) {\n");
fprintf(fp_cpp,"%s\n", _frame->_return_value); fprintf(fp_cpp,"%s\n", _frame->_return_value);
fprintf(fp_cpp,"}\n\n"); fprintf(fp_cpp,"}\n\n");
// Native Return Value Location // Native Return Value Location
fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(uint ideal_reg, bool is_outgoing) {\n"); fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(uint ideal_reg) {\n");
fprintf(fp_cpp,"%s\n", _frame->_c_return_value); fprintf(fp_cpp,"%s\n", _frame->_c_return_value);
fprintf(fp_cpp,"}\n\n"); fprintf(fp_cpp,"}\n\n");

@ -72,7 +72,7 @@ CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signa
} }
} }
intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing); intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
LIR_OprList* args = new LIR_OprList(signature->length()); LIR_OprList* args = new LIR_OprList(signature->length());
for (i = 0; i < sizeargs;) { for (i = 0; i < sizeargs;) {
BasicType t = sig_bt[i]; BasicType t = sig_bt[i];

@ -3110,7 +3110,7 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo
assert(sig_index == sizeargs, ""); assert(sig_index == sizeargs, "");
} }
const char* spname = "sp"; // make arch-specific? const char* spname = "sp"; // make arch-specific?
intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false); intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
int stack_slot_offset = this->frame_size() * wordSize; int stack_slot_offset = this->frame_size() * wordSize;
int tab1 = 14, tab2 = 24; int tab1 = 14, tab2 = 24;
int sig_index = 0; int sig_index = 0;

@ -42,6 +42,7 @@
#include "opto/regmask.hpp" #include "opto/regmask.hpp"
#include "opto/rootnode.hpp" #include "opto/rootnode.hpp"
#include "opto/runtime.hpp" #include "opto/runtime.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/powerOfTwo.hpp" #include "utilities/powerOfTwo.hpp"
// Portions of code courtesy of Clifford Click // Portions of code courtesy of Clifford Click
@ -65,8 +66,8 @@ Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){
} }
//------------------------------calling_convention----------------------------- //------------------------------calling_convention-----------------------------
void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { void StartNode::calling_convention(BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt) const {
Matcher::calling_convention( sig_bt, parm_regs, argcnt, false ); SharedRuntime::java_calling_convention(sig_bt, parm_regs, argcnt);
} }
//------------------------------Registers-------------------------------------- //------------------------------Registers--------------------------------------
@ -696,9 +697,9 @@ const Type* CallNode::Value(PhaseGVN* phase) const {
} }
//------------------------------calling_convention----------------------------- //------------------------------calling_convention-----------------------------
void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { void CallNode::calling_convention(BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt) const {
// Use the standard compiler calling convention // Use the standard compiler calling convention
Matcher::calling_convention( sig_bt, parm_regs, argcnt, true ); SharedRuntime::java_calling_convention(sig_bt, parm_regs, argcnt);
} }
@ -720,8 +721,8 @@ Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
case TypeFunc::Parms: { // Normal returns case TypeFunc::Parms: { // Normal returns
uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg(); uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg();
OptoRegPair regs = is_CallRuntime() OptoRegPair regs = is_CallRuntime()
? match->c_return_value(ideal_reg,true) // Calls into C runtime ? match->c_return_value(ideal_reg) // Calls into C runtime
: match-> return_value(ideal_reg,true); // Calls into compiled Java code : match-> return_value(ideal_reg); // Calls into compiled Java code
RegMask rm = RegMask(regs.first()); RegMask rm = RegMask(regs.first());
if( OptoReg::is_valid(regs.second()) ) if( OptoReg::is_valid(regs.second()) )
rm.Insert( regs.second() ); rm.Insert( regs.second() );
@ -1122,8 +1123,8 @@ void CallRuntimeNode::dump_spec(outputStream *st) const {
#endif #endif
//------------------------------calling_convention----------------------------- //------------------------------calling_convention-----------------------------
void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { void CallRuntimeNode::calling_convention(BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt) const {
Matcher::c_calling_convention( sig_bt, parm_regs, argcnt ); SharedRuntime::c_calling_convention(sig_bt, parm_regs, /*regs2=*/nullptr, argcnt);
} }
//============================================================================= //=============================================================================

@ -40,6 +40,7 @@
#include "opto/phase.hpp" #include "opto/phase.hpp"
#include "opto/regmask.hpp" #include "opto/regmask.hpp"
#include "runtime/deoptimization.hpp" #include "runtime/deoptimization.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/timerTrace.hpp" #include "runtime/timerTrace.hpp"
#include "runtime/vmThread.hpp" #include "runtime/vmThread.hpp"
#include "utilities/ticks.hpp" #include "utilities/ticks.hpp"
@ -1033,14 +1034,16 @@ class Compile : public Phase {
// Stack slots that may be unused by the calling convention but must // Stack slots that may be unused by the calling convention but must
// otherwise be preserved. On Intel this includes the return address. // otherwise be preserved. On Intel this includes the return address.
// On PowerPC it includes the 4 words holding the old TOC & LR glue. // On PowerPC it includes the 4 words holding the old TOC & LR glue.
uint in_preserve_stack_slots(); uint in_preserve_stack_slots() {
return SharedRuntime::in_preserve_stack_slots();
}
// "Top of Stack" slots that may be unused by the calling convention but must // "Top of Stack" slots that may be unused by the calling convention but must
// otherwise be preserved. // otherwise be preserved.
// On Intel these are not necessary and the value can be zero. // On Intel these are not necessary and the value can be zero.
// On Sparc this describes the words reserved for storing a register window static uint out_preserve_stack_slots() {
// when an interrupt occurs. return SharedRuntime::out_preserve_stack_slots();
static uint out_preserve_stack_slots(); }
// Number of outgoing stack slots killed above the out_preserve_stack_slots // Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms. // for calls to C. Supports the var-args backing area for register parms.

@ -202,7 +202,7 @@ void Matcher::match( ) {
uint ireg = range->field_at(TypeFunc::Parms)->ideal_reg(); uint ireg = range->field_at(TypeFunc::Parms)->ideal_reg();
// Get machine return register // Get machine return register
uint sop = C->start()->Opcode(); uint sop = C->start()->Opcode();
OptoRegPair regs = return_value(ireg, false); OptoRegPair regs = return_value(ireg);
// And mask for same // And mask for same
_return_value_mask = RegMask(regs.first()); _return_value_mask = RegMask(regs.first());
@ -748,7 +748,7 @@ void Matcher::Fixup_Save_On_Entry( ) {
uint reth_edge_cnt = TypeFunc::Parms+1; uint reth_edge_cnt = TypeFunc::Parms+1;
RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
// Rethrow takes exception oop only, but in the argument 0 slot. // Rethrow takes exception oop only, but in the argument 0 slot.
OptoReg::Name reg = find_receiver(false); OptoReg::Name reg = find_receiver();
if (reg >= 0) { if (reg >= 0) {
reth_rms[TypeFunc::Parms] = mreg2regmask[reg]; reth_rms[TypeFunc::Parms] = mreg2regmask[reg];
#ifdef _LP64 #ifdef _LP64
@ -1994,10 +1994,10 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
//------------------------------find_receiver---------------------------------- //------------------------------find_receiver----------------------------------
// For a given signature, return the OptoReg for parameter 0. // For a given signature, return the OptoReg for parameter 0.
OptoReg::Name Matcher::find_receiver( bool is_outgoing ) { OptoReg::Name Matcher::find_receiver() {
VMRegPair regs; VMRegPair regs;
BasicType sig_bt = T_OBJECT; BasicType sig_bt = T_OBJECT;
calling_convention(&sig_bt, &regs, 1, is_outgoing); SharedRuntime::java_calling_convention(&sig_bt, &regs, 1);
// Return argument 0 register. In the LP64 build pointers // Return argument 0 register. In the LP64 build pointers
// take 2 registers, but the VM wants only the 'main' name. // take 2 registers, but the VM wants only the 'main' name.
return OptoReg::as_OptoReg(regs.first()); return OptoReg::as_OptoReg(regs.first());

@ -370,20 +370,16 @@ public:
return stack_alignment_in_bytes() / (VMRegImpl::stack_slot_size); return stack_alignment_in_bytes() / (VMRegImpl::stack_slot_size);
} }
// Array mapping arguments to registers. Argument 0 is usually the 'this'
// pointer. Registers can include stack-slots and regular registers.
static void calling_convention( BasicType *, VMRegPair *, uint len, bool is_outgoing );
// Convert a sig into a calling convention register layout // Convert a sig into a calling convention register layout
// and find interesting things about it. // and find interesting things about it.
static OptoReg::Name find_receiver( bool is_outgoing ); static OptoReg::Name find_receiver();
// Return address register. On Intel it is a stack-slot. On PowerPC // Return address register. On Intel it is a stack-slot. On PowerPC
// it is the Link register. On Sparc it is r31? // it is the Link register. On Sparc it is r31?
virtual OptoReg::Name return_addr() const; virtual OptoReg::Name return_addr() const;
RegMask _return_addr_mask; RegMask _return_addr_mask;
// Return value register. On Intel it is EAX. On Sparc i0/o0. // Return value register. On Intel it is EAX.
static OptoRegPair return_value(uint ideal_reg, bool is_outgoing); static OptoRegPair return_value(uint ideal_reg);
static OptoRegPair c_return_value(uint ideal_reg, bool is_outgoing); static OptoRegPair c_return_value(uint ideal_reg);
RegMask _return_value_mask; RegMask _return_value_mask;
// Inline Cache Register // Inline Cache Register
static OptoReg::Name inline_cache_reg(); static OptoReg::Name inline_cache_reg();
@ -421,9 +417,6 @@ public:
// Java-Native calling convention // Java-Native calling convention
// (what you use when intercalling between Java and C++ code) // (what you use when intercalling between Java and C++ code)
// Array mapping arguments to registers. Argument 0 is usually the 'this'
// pointer. Registers can include stack-slots and regular registers.
static void c_calling_convention( BasicType*, VMRegPair *, uint );
// Frame pointer. The frame pointer is kept at the base of the stack // Frame pointer. The frame pointer is kept at the base of the stack
// and so is probably the stack pointer for most machines. On Intel // and so is probably the stack pointer for most machines. On Intel
// it is ESP. On the PowerPC it is R1. On Sparc it is SP. // it is ESP. On the PowerPC it is R1. On Sparc it is SP.

@ -1871,8 +1871,7 @@ void SharedRuntime::check_member_name_argument_is_last_argument(const methodHand
assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
const bool is_outgoing = method->is_method_handle_intrinsic(); int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1);
int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1, is_outgoing);
for (int i = 0; i < member_arg_pos; i++) { for (int i = 0; i < member_arg_pos; i++) {
VMReg a = regs_with_member_name[i].first(); VMReg a = regs_with_member_name[i].first();
@ -2688,7 +2687,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& met
} }
// Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
// Make a C heap allocated version of the fingerprint to store in the adapter // Make a C heap allocated version of the fingerprint to store in the adapter
fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
@ -2896,11 +2895,8 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
assert(i == total_args_passed, ""); assert(i == total_args_passed, "");
BasicType ret_type = ss.type(); BasicType ret_type = ss.type();
// Now get the compiled-Java layout as input (or output) arguments. // Now get the compiled-Java arguments layout.
// NOTE: Stubs for compiled entry points of method handle intrinsics int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
// are just trampolines so the argument registers must be outgoing ones.
const bool is_outgoing = method->is_method_handle_intrinsic();
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
// Generate the compiled-to-native wrapper code // Generate the compiled-to-native wrapper code
nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type, critical_entry); nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type, critical_entry);
@ -2944,7 +2940,7 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
VMReg SharedRuntime::name_for_receiver() { VMReg SharedRuntime::name_for_receiver() {
VMRegPair regs; VMRegPair regs;
BasicType sig_bt = T_OBJECT; BasicType sig_bt = T_OBJECT;
(void) java_calling_convention(&sig_bt, &regs, 1, true); (void) java_calling_convention(&sig_bt, &regs, 1);
// Return argument 0 register. In the LP64 build pointers // Return argument 0 register. In the LP64 build pointers
// take 2 registers, but the VM wants only the 'main' name. // take 2 registers, but the VM wants only the 'main' name.
return regs.first(); return regs.first();
@ -2975,7 +2971,7 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver,
assert(cnt < 256, "grow table size"); assert(cnt < 256, "grow table size");
int comp_args_on_stack; int comp_args_on_stack;
comp_args_on_stack = java_calling_convention(sig_bt, regs, cnt, true); comp_args_on_stack = java_calling_convention(sig_bt, regs, cnt);
// the calling convention doesn't count out_preserve_stack_slots so // the calling convention doesn't count out_preserve_stack_slots so
// we must add that in to get "true" stack offsets. // we must add that in to get "true" stack offsets.

@ -368,11 +368,9 @@ class SharedRuntime: AllStatic {
// registers, those above refer to 4-byte stack slots. All stack slots are // registers, those above refer to 4-byte stack slots. All stack slots are
// based off of the window top. SharedInfo::stack0 refers to the first usable // based off of the window top. SharedInfo::stack0 refers to the first usable
// slot in the bottom of the frame. SharedInfo::stack0+1 refers to the memory word // slot in the bottom of the frame. SharedInfo::stack0+1 refers to the memory word
// 4-bytes higher. So for sparc because the register window save area is at // 4-bytes higher.
// the bottom of the frame the first 16 words will be skipped and SharedInfo::stack0
// will be just above it. (
// return value is the maximum number of VMReg stack slots the convention will use. // return value is the maximum number of VMReg stack slots the convention will use.
static int java_calling_convention(const BasicType* sig_bt, VMRegPair* regs, int total_args_passed, int is_outgoing); static int java_calling_convention(const BasicType* sig_bt, VMRegPair* regs, int total_args_passed);
static void check_member_name_argument_is_last_argument(const methodHandle& method, static void check_member_name_argument_is_last_argument(const methodHandle& method,
const BasicType* sig_bt, const BasicType* sig_bt,
@ -461,6 +459,11 @@ class SharedRuntime: AllStatic {
// when an interrupt occurs. // when an interrupt occurs.
static uint out_preserve_stack_slots(); static uint out_preserve_stack_slots();
// Stack slots that may be unused by the calling convention but must
// otherwise be preserved. On Intel this includes the return address.
// On PowerPC it includes the 4 words holding the old TOC & LR glue.
static uint in_preserve_stack_slots();
// Is vector's size (in bytes) bigger than a size saved by default? // Is vector's size (in bytes) bigger than a size saved by default?
// For example, on x86 16 bytes XMM registers are saved by default. // For example, on x86 16 bytes XMM registers are saved by default.
static bool is_wide_vector(int size); static bool is_wide_vector(int size);