8256205: Simplify compiler calling convention handling
Reviewed-by: kvn, neliasso
This commit is contained in:
parent
68fd71d2ad
commit
6e35bcbf03
src/hotspot
cpu
aarch64
arm
ppc
s390
x86
c1_CodeStubs_x86.cppc1_FrameMap_x86.cppsharedRuntime_x86_32.cppsharedRuntime_x86_64.cppx86_32.adx86_64.ad
zero
share
@ -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, ®s, 1, true);
|
SharedRuntime::java_calling_convention(&sig_bt, ®s, 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, ®s, 1, true);
|
SharedRuntime::java_calling_convention(&sig_bt, ®s, 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, ®s, 1, is_outgoing);
|
SharedRuntime::java_calling_convention(&sig_bt, ®s, 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, ®s, 1, true);
|
(void) java_calling_convention(&sig_bt, ®s, 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user