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

View File

@ -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
%{ %{
@ -12401,7 +12375,7 @@ instruct SubL_reg_LShift_reg(iRegLNoSp dst,
ins_pipe(ialu_reg_reg_shift); ins_pipe(ialu_reg_reg_shift);
%} %}
// This pattern is automatically generated from aarch64_ad.m4 // This pattern is automatically generated from aarch64_ad.m4
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
@ -12708,7 +12682,7 @@ instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
%} %}
// Rotations // Rotations
// This pattern is automatically generated from aarch64_ad.m4 // This pattern is automatically generated from aarch64_ad.m4
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)

View File

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

View File

@ -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++) {

View File

@ -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;
} }

View File

@ -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);

View File

@ -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();

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
} }

View File

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

View File

@ -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());
} }

View File

@ -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;
} }

View File

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

View File

@ -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" );

View File

@ -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
%{ %{

View File

@ -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;
} }

View File

@ -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 ) {

View File

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

View File

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

View File

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

View File

@ -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");

View File

@ -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];

View File

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

View File

@ -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);
} }
//============================================================================= //=============================================================================

View File

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

View File

@ -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());

View File

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

View File

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

View File

@ -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);