mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 10:23:28 +00:00
8349686: [s390x] C1: Improve Class.isInstance intrinsic
Reviewed-by: lucy, aph
This commit is contained in:
parent
70e3250045
commit
b428cda3c6
@ -961,7 +961,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
|
||||
|
||||
// Intrinsic for Class::isInstance
|
||||
address LIRGenerator::isInstance_entry() {
|
||||
return CAST_FROM_FN_PTR(address, Runtime1::is_instance_of);
|
||||
return Runtime1::entry_for(C1StubId::is_instance_of_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -589,6 +589,67 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
|
||||
__ z_br(Z_R14);
|
||||
}
|
||||
break;
|
||||
case C1StubId::is_instance_of_id:
|
||||
{
|
||||
// Mirror: Z_ARG1(R2)
|
||||
// Object: Z_ARG2
|
||||
// Temps: Z_ARG3, Z_ARG4, Z_ARG5, Z_R10, Z_R11
|
||||
// Result: Z_RET(R2)
|
||||
|
||||
// Get the Klass* into Z_ARG3
|
||||
Register klass = Z_ARG3 , obj = Z_ARG2, result = Z_RET;
|
||||
Register temp0 = Z_ARG4, temp1 = Z_ARG5, temp2 = Z_R10, temp3 = Z_R11;
|
||||
|
||||
__ z_ltg(klass, Address(Z_ARG1, java_lang_Class::klass_offset())); // Klass is null
|
||||
|
||||
Label is_secondary;
|
||||
|
||||
__ clear_reg(result /* Z_R2 */, true /* whole_reg */, false /* set_cc */); // sets result=0 (failure)
|
||||
|
||||
__ z_bcr(Assembler::bcondEqual, Z_R14); // cc set by z_ltg above
|
||||
|
||||
__ z_ltgr(obj, obj); // obj is null
|
||||
__ z_bcr(Assembler::bcondEqual, Z_R14);
|
||||
|
||||
__ z_llgf(temp0, Address(klass, in_bytes(Klass::super_check_offset_offset())));
|
||||
__ compare32_and_branch(temp0, in_bytes(Klass::secondary_super_cache_offset()), Assembler::bcondEqual, is_secondary); // Klass is a secondary superclass
|
||||
|
||||
// Klass is a concrete class
|
||||
__ load_klass(temp1, obj);
|
||||
__ z_cg(klass, Address(temp1, temp0));
|
||||
|
||||
// result is already holding 0, denoting NotEqual case
|
||||
__ load_on_condition_imm_32(result, 1, Assembler::bcondEqual);
|
||||
__ z_br(Z_R14);
|
||||
|
||||
__ bind(is_secondary);
|
||||
|
||||
__ load_klass(obj, obj);
|
||||
|
||||
// This is necessary because I am never in my own secondary_super list.
|
||||
__ z_cgr(obj, klass);
|
||||
__ load_on_condition_imm_32(result, 1, Assembler::bcondEqual);
|
||||
__ z_bcr(Assembler::bcondEqual, Z_R14);
|
||||
|
||||
// Z_R10 and Z_R11 are callee saved, so we must need to preserve them before any use
|
||||
__ z_ldgr(Z_F1, Z_R10);
|
||||
__ z_ldgr(Z_F3, Z_R11);
|
||||
|
||||
__ lookup_secondary_supers_table_var(obj, klass,
|
||||
/*temps*/ temp0, temp1, temp2, temp3,
|
||||
result);
|
||||
|
||||
// lookup_secondary_supers_table_var return 0 on success and 1 on failure.
|
||||
// but this method returns 0 on failure and 1 on success.
|
||||
// so we have to invert the result from lookup_secondary_supers_table_var.
|
||||
__ z_xilf(result, 1); // invert the result
|
||||
|
||||
__ z_lgdr(Z_R10, Z_F1);
|
||||
__ z_lgdr(Z_R11, Z_F3);
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
}
|
||||
case C1StubId::monitorenter_nofpu_id:
|
||||
case C1StubId::monitorenter_id:
|
||||
{ // Z_R1_scratch : object
|
||||
|
||||
@ -3679,9 +3679,6 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
|
||||
r_array_index = r_temp3,
|
||||
r_bitmap = noreg; // unused
|
||||
|
||||
const Register r_one = Z_R0_scratch;
|
||||
z_lghi(r_one, 1); // for locgr down there, to a load result for failure
|
||||
|
||||
BLOCK_COMMENT("verify_secondary_supers_table {");
|
||||
|
||||
Label L_passed, L_failure;
|
||||
@ -3697,7 +3694,7 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
|
||||
|
||||
const Register r_linear_result = r_array_index; // reuse
|
||||
z_chi(r_array_length, 0);
|
||||
z_locgr(r_linear_result, r_one, bcondNotHigh); // load failure if array_length <= 0
|
||||
load_on_condition_imm_32(r_linear_result, 1, bcondNotHigh); // load failure if array_length <= 0
|
||||
z_brc(bcondNotHigh, L_failure);
|
||||
repne_scan(r_array_base, r_super_klass, r_array_length, r_linear_result);
|
||||
bind(L_failure);
|
||||
@ -3705,13 +3702,20 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
|
||||
z_cr(r_result, r_linear_result);
|
||||
z_bre(L_passed);
|
||||
|
||||
assert_different_registers(Z_ARG1, r_sub_klass, r_linear_result, r_result);
|
||||
lgr_if_needed(Z_ARG1, r_super_klass);
|
||||
assert_different_registers(Z_ARG2, r_linear_result, r_result);
|
||||
lgr_if_needed(Z_ARG2, r_sub_klass);
|
||||
assert_different_registers(Z_ARG3, r_result);
|
||||
z_lgr(Z_ARG3, r_linear_result);
|
||||
// report fatal error and terminate VM
|
||||
|
||||
// Argument shuffle
|
||||
// Z_F1, Z_F3, Z_F5 are volatile regs
|
||||
z_ldgr(Z_F1, r_super_klass);
|
||||
z_ldgr(Z_F3, r_sub_klass);
|
||||
z_ldgr(Z_F5, r_linear_result);
|
||||
|
||||
z_lgr(Z_ARG4, r_result);
|
||||
|
||||
z_lgdr(Z_ARG1, Z_F1); // r_super_klass
|
||||
z_lgdr(Z_ARG2, Z_F3); // r_sub_klass
|
||||
z_lgdr(Z_ARG3, Z_F5); // r_linear_result
|
||||
|
||||
const char* msg = "mismatch";
|
||||
load_const_optimized(Z_ARG5, (address)msg);
|
||||
|
||||
@ -6944,3 +6948,29 @@ void MacroAssembler::pop_count_int_with_ext3(Register r_dst, Register r_src) {
|
||||
|
||||
BLOCK_COMMENT("} pop_count_int_with_ext3");
|
||||
}
|
||||
|
||||
// LOAD HALFWORD IMMEDIATE ON CONDITION (32 <- 16)
|
||||
void MacroAssembler::load_on_condition_imm_32(Register dst, int64_t i2, branch_condition cc) {
|
||||
if (VM_Version::has_LoadStoreConditional2()) { // z_lochi works on z13 or above
|
||||
assert(Assembler::is_simm16(i2), "sanity");
|
||||
z_lochi(dst, i2, cc);
|
||||
} else {
|
||||
NearLabel done;
|
||||
z_brc(Assembler::inverse_condition(cc), done);
|
||||
z_lhi(dst, i2);
|
||||
bind(done);
|
||||
}
|
||||
}
|
||||
|
||||
// LOAD HALFWORD IMMEDIATE ON CONDITION (64 <- 16)
|
||||
void MacroAssembler::load_on_condition_imm_64(Register dst, int64_t i2, branch_condition cc) {
|
||||
if (VM_Version::has_LoadStoreConditional2()) { // z_locghi works on z13 or above
|
||||
assert(Assembler::is_simm16(i2), "sanity");
|
||||
z_locghi(dst, i2, cc);
|
||||
} else {
|
||||
NearLabel done;
|
||||
z_brc(Assembler::inverse_condition(cc), done);
|
||||
z_lghi(dst, i2);
|
||||
bind(done);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,6 +1109,8 @@ class MacroAssembler: public Assembler {
|
||||
void pop_count_int_with_ext3(Register dst, Register src);
|
||||
void pop_count_long_with_ext3(Register dst, Register src);
|
||||
|
||||
void load_on_condition_imm_32(Register dst, int64_t i2, branch_condition cc);
|
||||
void load_on_condition_imm_64(Register dst, int64_t i2, branch_condition cc);
|
||||
};
|
||||
|
||||
#ifdef ASSERT
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user