mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8050022: linux-sparcv9: assert(SharedSkipVerify || obj->is_oop()) failed: sanity check
Provide promoted stack slots for floating-point registers in the SPARC c_calling_convention. Reviewed-by: kvn, jrose, drchase
This commit is contained in:
parent
e39f822e38
commit
c468032582
2 changed files with 66 additions and 36 deletions
|
@ -1128,14 +1128,17 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||||
// Hoist any int/ptr/long's in the first 6 to int regs.
|
// Hoist any int/ptr/long's in the first 6 to int regs.
|
||||||
// Hoist any flt/dbl's in the first 16 dbl regs.
|
// Hoist any flt/dbl's in the first 16 dbl regs.
|
||||||
int j = 0; // Count of actual args, not HALVES
|
int j = 0; // Count of actual args, not HALVES
|
||||||
|
VMRegPair param_array_reg; // location of the argument in the parameter array
|
||||||
for (int i = 0; i < total_args_passed; i++, j++) {
|
for (int i = 0; i < total_args_passed; i++, j++) {
|
||||||
|
param_array_reg.set_bad();
|
||||||
switch (sig_bt[i]) {
|
switch (sig_bt[i]) {
|
||||||
case T_BOOLEAN:
|
case T_BOOLEAN:
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_INT:
|
case T_INT:
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
regs[i].set1( int_stk_helper( j ) ); break;
|
regs[i].set1(int_stk_helper(j));
|
||||||
|
break;
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
assert(sig_bt[i+1] == T_VOID, "expecting half");
|
||||||
case T_ADDRESS: // raw pointers, like current thread, for VM calls
|
case T_ADDRESS: // raw pointers, like current thread, for VM calls
|
||||||
|
@ -1145,34 +1148,62 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||||
regs[i].set2(int_stk_helper(j));
|
regs[i].set2(int_stk_helper(j));
|
||||||
break;
|
break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
|
// Per SPARC Compliance Definition 2.4.1, page 3P-12 available here
|
||||||
|
// http://www.sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz
|
||||||
|
//
|
||||||
|
// "When a callee prototype exists, and does not indicate variable arguments,
|
||||||
|
// floating-point values assigned to locations %sp+BIAS+128 through %sp+BIAS+248
|
||||||
|
// will be promoted to floating-point registers"
|
||||||
|
//
|
||||||
|
// By "promoted" it means that the argument is located in two places, an unused
|
||||||
|
// spill slot in the "parameter array" (starts at %sp+BIAS+128), and a live
|
||||||
|
// float register. In most cases, there are 6 or fewer arguments of any type,
|
||||||
|
// and the standard parameter array slots (%sp+BIAS+128 to %sp+BIAS+176 exclusive)
|
||||||
|
// serve as shadow slots. Per the spec floating point registers %d6 to %d16
|
||||||
|
// require slots beyond that (up to %sp+BIAS+248).
|
||||||
|
//
|
||||||
|
{
|
||||||
|
// V9ism: floats go in ODD registers and stack slots
|
||||||
|
int float_index = 1 + (j << 1);
|
||||||
|
param_array_reg.set1(VMRegImpl::stack2reg(float_index));
|
||||||
if (j < 16) {
|
if (j < 16) {
|
||||||
// V9ism: floats go in ODD registers
|
regs[i].set1(as_FloatRegister(float_index)->as_VMReg());
|
||||||
regs[i].set1(as_FloatRegister(1 + (j<<1))->as_VMReg());
|
|
||||||
} else {
|
} else {
|
||||||
// V9ism: floats go in ODD stack slot
|
regs[i] = param_array_reg;
|
||||||
regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1)));
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
|
{
|
||||||
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
assert(sig_bt[i + 1] == T_VOID, "expecting half");
|
||||||
|
// V9ism: doubles go in EVEN/ODD regs and stack slots
|
||||||
|
int double_index = (j << 1);
|
||||||
|
param_array_reg.set2(VMRegImpl::stack2reg(double_index));
|
||||||
if (j < 16) {
|
if (j < 16) {
|
||||||
// V9ism: doubles go in EVEN/ODD regs
|
regs[i].set2(as_FloatRegister(double_index)->as_VMReg());
|
||||||
regs[i].set2(as_FloatRegister(j<<1)->as_VMReg());
|
|
||||||
} else {
|
} else {
|
||||||
// V9ism: doubles go in EVEN/ODD stack slots
|
// V9ism: doubles go in EVEN/ODD stack slots
|
||||||
regs[i].set2(VMRegImpl::stack2reg(j<<1));
|
regs[i] = param_array_reg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_VOID: regs[i].set_bad(); j--; break; // Do not count HALVES
|
case T_VOID:
|
||||||
|
regs[i].set_bad();
|
||||||
|
j--;
|
||||||
|
break; // Do not count HALVES
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
if (regs[i].first()->is_stack()) {
|
// Keep track of the deepest parameter array slot.
|
||||||
int off = regs[i].first()->reg2stack();
|
if (!param_array_reg.first()->is_valid()) {
|
||||||
|
param_array_reg = regs[i];
|
||||||
|
}
|
||||||
|
if (param_array_reg.first()->is_stack()) {
|
||||||
|
int off = param_array_reg.first()->reg2stack();
|
||||||
if (off > max_stack_slots) max_stack_slots = off;
|
if (off > max_stack_slots) max_stack_slots = off;
|
||||||
}
|
}
|
||||||
if (regs[i].second()->is_stack()) {
|
if (param_array_reg.second()->is_stack()) {
|
||||||
int off = regs[i].second()->reg2stack();
|
int off = param_array_reg.second()->reg2stack();
|
||||||
if (off > max_stack_slots) max_stack_slots = off;
|
if (off > max_stack_slots) max_stack_slots = off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1358,10 +1389,9 @@ static void object_move(MacroAssembler* masm,
|
||||||
const Register rHandle = L5;
|
const Register rHandle = L5;
|
||||||
int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset;
|
int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset;
|
||||||
int offset = oop_slot * VMRegImpl::stack_slot_size;
|
int offset = oop_slot * VMRegImpl::stack_slot_size;
|
||||||
Label skip;
|
|
||||||
__ st_ptr(rOop, SP, offset + STACK_BIAS);
|
__ st_ptr(rOop, SP, offset + STACK_BIAS);
|
||||||
if (is_receiver) {
|
if (is_receiver) {
|
||||||
*receiver_offset = oop_slot * VMRegImpl::stack_slot_size;
|
*receiver_offset = offset;
|
||||||
}
|
}
|
||||||
map->set_oop(VMRegImpl::stack2reg(oop_slot));
|
map->set_oop(VMRegImpl::stack2reg(oop_slot));
|
||||||
__ add(SP, offset + STACK_BIAS, rHandle);
|
__ add(SP, offset + STACK_BIAS, rHandle);
|
||||||
|
|
|
@ -1989,7 +1989,7 @@ void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
|
||||||
// to implement the UseStrictFP mode.
|
// to implement the UseStrictFP mode.
|
||||||
const bool Matcher::strict_fp_requires_explicit_rounding = false;
|
const bool Matcher::strict_fp_requires_explicit_rounding = false;
|
||||||
|
|
||||||
// Are floats conerted to double when stored to stack during deoptimization?
|
// Are floats converted to double when stored to stack during deoptimization?
|
||||||
// Sparc does not handle callee-save floats.
|
// Sparc does not handle callee-save floats.
|
||||||
bool Matcher::float_in_double() { return false; }
|
bool Matcher::float_in_double() { return false; }
|
||||||
|
|
||||||
|
@ -3218,7 +3218,7 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r
|
||||||
// are owned by the CALLEE. Holes should not be nessecary in the
|
// are owned by the CALLEE. Holes should not be nessecary in the
|
||||||
// incoming area, as the Java calling convention is completely under
|
// incoming area, as the Java calling convention is completely under
|
||||||
// the control of the AD file. Doubles can be sorted and packed to
|
// the control of the AD file. Doubles can be sorted and packed to
|
||||||
// avoid holes. Holes in the outgoing arguments may be nessecary for
|
// avoid holes. Holes in the outgoing arguments may be necessary for
|
||||||
// varargs C calling conventions.
|
// varargs C calling conventions.
|
||||||
// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
|
// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
|
||||||
// even aligned with pad0 as needed.
|
// even aligned with pad0 as needed.
|
||||||
|
@ -3284,7 +3284,7 @@ frame %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Body of function which returns an OptoRegs array locating
|
// Body of function which returns an OptoRegs array locating
|
||||||
// arguments either in registers or in stack slots for callin
|
// arguments either in registers or in stack slots for calling
|
||||||
// C.
|
// C.
|
||||||
c_calling_convention %{
|
c_calling_convention %{
|
||||||
// This is obviously always outgoing
|
// This is obviously always outgoing
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue