Skip to content

Commit 735805d

Browse files
committed
8349727: [PPC] C1: Improve Class.isInstance intrinsic
Reviewed-by: rrich, varadam
1 parent 1e87ff0 commit 735805d

File tree

4 files changed

+95
-23
lines changed

4 files changed

+95
-23
lines changed

src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,25 +2839,28 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) {
28392839

28402840
void LIR_Assembler::rt_call(LIR_Opr result, address dest,
28412841
const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
2842-
// Stubs: Called via rt_call, but dest is a stub address (no function descriptor).
2842+
// Stubs: Called via rt_call, but dest is a stub address (no FunctionDescriptor).
28432843
if (dest == Runtime1::entry_for(C1StubId::register_finalizer_id) ||
2844-
dest == Runtime1::entry_for(C1StubId::new_multi_array_id )) {
2844+
dest == Runtime1::entry_for(C1StubId::new_multi_array_id ) ||
2845+
dest == Runtime1::entry_for(C1StubId::is_instance_of_id )) {
2846+
assert(CodeCache::contains(dest), "simplified call is only for special C1 stubs");
28452847
//__ load_const_optimized(R0, dest);
28462848
__ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(dest));
28472849
__ mtctr(R0);
28482850
__ bctrl();
2849-
assert(info != nullptr, "sanity");
2850-
add_call_info_here(info);
2851-
__ post_call_nop();
2851+
if (info != nullptr) {
2852+
add_call_info_here(info);
2853+
__ post_call_nop();
2854+
}
28522855
return;
28532856
}
28542857

28552858
__ call_c(dest, relocInfo::runtime_call_type);
2859+
assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc");
28562860
if (info != nullptr) {
28572861
add_call_info_here(info);
2862+
__ post_call_nop();
28582863
}
2859-
assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc");
2860-
__ post_call_nop();
28612864
}
28622865

28632866

src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,10 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
11281128
x->profiled_method(), x->profiled_bci());
11291129
}
11301130

1131+
11311132
// Intrinsic for Class::isInstance
11321133
address LIRGenerator::isInstance_entry() {
1133-
return CAST_FROM_FN_PTR(address, Runtime1::is_instance_of);
1134+
return Runtime1::entry_for(C1StubId::is_instance_of_id);
11341135
}
11351136

11361137

src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,73 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
609609
}
610610
break;
611611

612+
case C1StubId::is_instance_of_id:
613+
{
614+
// Called like a C function, but without FunctionDescriptor (see LIR_Assembler::rt_call).
615+
616+
// Arguments and return value.
617+
Register mirror = R3_ARG1;
618+
Register obj = R4_ARG2;
619+
Register result = R3_RET;
620+
621+
// Other argument registers can be used as temp registers.
622+
Register klass = R5;
623+
Register offset = R6;
624+
Register sub_klass = R7;
625+
626+
Label is_secondary, success;
627+
628+
// Get the Klass*.
629+
__ ld(klass, java_lang_Class::klass_offset(), mirror);
630+
631+
// Return false if obj or klass is null.
632+
mirror = noreg; // killed by next instruction
633+
__ li(result, 0); // assume result is false
634+
__ cmpdi(CR0, obj, 0);
635+
__ cmpdi(CR1, klass, 0);
636+
__ cror(CR0, Assembler::equal, CR1, Assembler::equal);
637+
__ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn);
638+
639+
__ lwz(offset, in_bytes(Klass::super_check_offset_offset()), klass);
640+
__ load_klass(sub_klass, obj);
641+
__ cmpwi(CR0, offset, in_bytes(Klass::secondary_super_cache_offset()));
642+
__ beq(CR0, is_secondary); // Klass is a secondary superclass
643+
644+
// Klass is a concrete class
645+
__ ldx(R0, sub_klass, offset);
646+
__ cmpd(CR0, klass, R0);
647+
if (VM_Version::has_brw()) {
648+
// Power10 can set the result by one instruction. No need for a branch.
649+
__ setbc(result, CR0, Assembler::equal);
650+
} else {
651+
__ beq(CR0, success);
652+
}
653+
__ blr();
654+
655+
__ bind(is_secondary);
656+
657+
// This is necessary because I am never in my own secondary_super list.
658+
__ cmpd(CR0, sub_klass, klass);
659+
__ beq(CR0, success);
660+
661+
__ lookup_secondary_supers_table_var(sub_klass, klass,
662+
/*temps*/R9, R10, R11, R12,
663+
/*result*/R8);
664+
__ cmpdi(CR0, R8, 0); // 0 means is subclass
665+
if (VM_Version::has_brw()) {
666+
// Power10 can set the result by one instruction. No need for a branch.
667+
__ setbc(result, CR0, Assembler::equal);
668+
} else {
669+
__ beq(CR0, success);
670+
}
671+
__ blr();
672+
673+
__ bind(success);
674+
__ li(result, 1);
675+
__ blr();
676+
}
677+
break;
678+
612679
case C1StubId::monitorenter_nofpu_id:
613680
case C1StubId::monitorenter_id:
614681
{

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,27 +2265,28 @@ void MacroAssembler::check_klass_subtype(Register sub_klass,
22652265
// generic (count must be >0)
22662266
// iff found: CR0 eq, scratch == 0
22672267
void MacroAssembler::repne_scan(Register addr, Register value, Register count, Register scratch) {
2268-
Label Lloop, Lexit;
2268+
Label Lloop, Lafter_loop, Lexit;
22692269

2270-
#ifdef ASSERT
2271-
{
2272-
Label ok;
2273-
cmpdi(CR0, count, 0);
2274-
bgt(CR0, ok);
2275-
stop("count must be positive");
2276-
bind(ok);
2277-
}
2278-
#endif
2279-
2280-
mtctr(count);
2270+
srdi_(scratch, count, 1);
2271+
beq(CR0, Lafter_loop);
2272+
mtctr(scratch);
22812273

2282-
bind(Lloop);
2283-
ld(scratch, 0 , addr);
2274+
bind(Lloop); // 2x unrolled
2275+
ld(scratch, 0, addr);
22842276
xor_(scratch, scratch, value);
22852277
beq(CR0, Lexit);
2286-
addi(addr, addr, wordSize);
2278+
ld(scratch, 8, addr);
2279+
xor_(scratch, scratch, value);
2280+
beq(CR0, Lexit);
2281+
addi(addr, addr, 2 * wordSize);
22872282
bdnz(Lloop);
22882283

2284+
bind(Lafter_loop);
2285+
andi_(scratch, count, 1);
2286+
beq(CR0, Lexit); // if taken: CR0 eq and scratch == 0
2287+
ld(scratch, 0, addr);
2288+
xor_(scratch, scratch, value);
2289+
22892290
bind(Lexit);
22902291
}
22912292

0 commit comments

Comments
 (0)