Skip to content

Commit b428cda

Browse files
committed
8349686: [s390x] C1: Improve Class.isInstance intrinsic
Reviewed-by: lucy, aph
1 parent 70e3250 commit b428cda

File tree

4 files changed

+104
-11
lines changed

4 files changed

+104
-11
lines changed

src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
961961

962962
// Intrinsic for Class::isInstance
963963
address LIRGenerator::isInstance_entry() {
964-
return CAST_FROM_FN_PTR(address, Runtime1::is_instance_of);
964+
return Runtime1::entry_for(C1StubId::is_instance_of_id);
965965
}
966966

967967

src/hotspot/cpu/s390/c1_Runtime1_s390.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,67 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
589589
__ z_br(Z_R14);
590590
}
591591
break;
592+
case C1StubId::is_instance_of_id:
593+
{
594+
// Mirror: Z_ARG1(R2)
595+
// Object: Z_ARG2
596+
// Temps: Z_ARG3, Z_ARG4, Z_ARG5, Z_R10, Z_R11
597+
// Result: Z_RET(R2)
598+
599+
// Get the Klass* into Z_ARG3
600+
Register klass = Z_ARG3 , obj = Z_ARG2, result = Z_RET;
601+
Register temp0 = Z_ARG4, temp1 = Z_ARG5, temp2 = Z_R10, temp3 = Z_R11;
602+
603+
__ z_ltg(klass, Address(Z_ARG1, java_lang_Class::klass_offset())); // Klass is null
604+
605+
Label is_secondary;
606+
607+
__ clear_reg(result /* Z_R2 */, true /* whole_reg */, false /* set_cc */); // sets result=0 (failure)
608+
609+
__ z_bcr(Assembler::bcondEqual, Z_R14); // cc set by z_ltg above
610+
611+
__ z_ltgr(obj, obj); // obj is null
612+
__ z_bcr(Assembler::bcondEqual, Z_R14);
613+
614+
__ z_llgf(temp0, Address(klass, in_bytes(Klass::super_check_offset_offset())));
615+
__ compare32_and_branch(temp0, in_bytes(Klass::secondary_super_cache_offset()), Assembler::bcondEqual, is_secondary); // Klass is a secondary superclass
616+
617+
// Klass is a concrete class
618+
__ load_klass(temp1, obj);
619+
__ z_cg(klass, Address(temp1, temp0));
620+
621+
// result is already holding 0, denoting NotEqual case
622+
__ load_on_condition_imm_32(result, 1, Assembler::bcondEqual);
623+
__ z_br(Z_R14);
624+
625+
__ bind(is_secondary);
626+
627+
__ load_klass(obj, obj);
628+
629+
// This is necessary because I am never in my own secondary_super list.
630+
__ z_cgr(obj, klass);
631+
__ load_on_condition_imm_32(result, 1, Assembler::bcondEqual);
632+
__ z_bcr(Assembler::bcondEqual, Z_R14);
633+
634+
// Z_R10 and Z_R11 are callee saved, so we must need to preserve them before any use
635+
__ z_ldgr(Z_F1, Z_R10);
636+
__ z_ldgr(Z_F3, Z_R11);
637+
638+
__ lookup_secondary_supers_table_var(obj, klass,
639+
/*temps*/ temp0, temp1, temp2, temp3,
640+
result);
641+
642+
// lookup_secondary_supers_table_var return 0 on success and 1 on failure.
643+
// but this method returns 0 on failure and 1 on success.
644+
// so we have to invert the result from lookup_secondary_supers_table_var.
645+
__ z_xilf(result, 1); // invert the result
646+
647+
__ z_lgdr(Z_R10, Z_F1);
648+
__ z_lgdr(Z_R11, Z_F3);
649+
650+
__ z_br(Z_R14);
651+
652+
}
592653
case C1StubId::monitorenter_nofpu_id:
593654
case C1StubId::monitorenter_id:
594655
{ // Z_R1_scratch : object

src/hotspot/cpu/s390/macroAssembler_s390.cpp

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,9 +3679,6 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
36793679
r_array_index = r_temp3,
36803680
r_bitmap = noreg; // unused
36813681

3682-
const Register r_one = Z_R0_scratch;
3683-
z_lghi(r_one, 1); // for locgr down there, to a load result for failure
3684-
36853682
BLOCK_COMMENT("verify_secondary_supers_table {");
36863683

36873684
Label L_passed, L_failure;
@@ -3697,21 +3694,28 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
36973694

36983695
const Register r_linear_result = r_array_index; // reuse
36993696
z_chi(r_array_length, 0);
3700-
z_locgr(r_linear_result, r_one, bcondNotHigh); // load failure if array_length <= 0
3697+
load_on_condition_imm_32(r_linear_result, 1, bcondNotHigh); // load failure if array_length <= 0
37013698
z_brc(bcondNotHigh, L_failure);
37023699
repne_scan(r_array_base, r_super_klass, r_array_length, r_linear_result);
37033700
bind(L_failure);
37043701

37053702
z_cr(r_result, r_linear_result);
37063703
z_bre(L_passed);
37073704

3708-
assert_different_registers(Z_ARG1, r_sub_klass, r_linear_result, r_result);
3709-
lgr_if_needed(Z_ARG1, r_super_klass);
3710-
assert_different_registers(Z_ARG2, r_linear_result, r_result);
3711-
lgr_if_needed(Z_ARG2, r_sub_klass);
3712-
assert_different_registers(Z_ARG3, r_result);
3713-
z_lgr(Z_ARG3, r_linear_result);
3705+
// report fatal error and terminate VM
3706+
3707+
// Argument shuffle
3708+
// Z_F1, Z_F3, Z_F5 are volatile regs
3709+
z_ldgr(Z_F1, r_super_klass);
3710+
z_ldgr(Z_F3, r_sub_klass);
3711+
z_ldgr(Z_F5, r_linear_result);
3712+
37143713
z_lgr(Z_ARG4, r_result);
3714+
3715+
z_lgdr(Z_ARG1, Z_F1); // r_super_klass
3716+
z_lgdr(Z_ARG2, Z_F3); // r_sub_klass
3717+
z_lgdr(Z_ARG3, Z_F5); // r_linear_result
3718+
37153719
const char* msg = "mismatch";
37163720
load_const_optimized(Z_ARG5, (address)msg);
37173721

@@ -6944,3 +6948,29 @@ void MacroAssembler::pop_count_int_with_ext3(Register r_dst, Register r_src) {
69446948

69456949
BLOCK_COMMENT("} pop_count_int_with_ext3");
69466950
}
6951+
6952+
// LOAD HALFWORD IMMEDIATE ON CONDITION (32 <- 16)
6953+
void MacroAssembler::load_on_condition_imm_32(Register dst, int64_t i2, branch_condition cc) {
6954+
if (VM_Version::has_LoadStoreConditional2()) { // z_lochi works on z13 or above
6955+
assert(Assembler::is_simm16(i2), "sanity");
6956+
z_lochi(dst, i2, cc);
6957+
} else {
6958+
NearLabel done;
6959+
z_brc(Assembler::inverse_condition(cc), done);
6960+
z_lhi(dst, i2);
6961+
bind(done);
6962+
}
6963+
}
6964+
6965+
// LOAD HALFWORD IMMEDIATE ON CONDITION (64 <- 16)
6966+
void MacroAssembler::load_on_condition_imm_64(Register dst, int64_t i2, branch_condition cc) {
6967+
if (VM_Version::has_LoadStoreConditional2()) { // z_locghi works on z13 or above
6968+
assert(Assembler::is_simm16(i2), "sanity");
6969+
z_locghi(dst, i2, cc);
6970+
} else {
6971+
NearLabel done;
6972+
z_brc(Assembler::inverse_condition(cc), done);
6973+
z_lghi(dst, i2);
6974+
bind(done);
6975+
}
6976+
}

src/hotspot/cpu/s390/macroAssembler_s390.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,8 @@ class MacroAssembler: public Assembler {
11091109
void pop_count_int_with_ext3(Register dst, Register src);
11101110
void pop_count_long_with_ext3(Register dst, Register src);
11111111

1112+
void load_on_condition_imm_32(Register dst, int64_t i2, branch_condition cc);
1113+
void load_on_condition_imm_64(Register dst, int64_t i2, branch_condition cc);
11121114
};
11131115

11141116
#ifdef ASSERT

0 commit comments

Comments
 (0)