From 70436396ccd8948ad4baab1bb8a77702021c4fd4 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Fri, 1 Dec 2023 11:15:04 +0100 Subject: [PATCH] Just started --- .../cpu/riscv/c1_LIRAssembler_riscv.cpp | 21 +------- .../cpu/riscv/c1_MacroAssembler_riscv.cpp | 9 ---- .../cpu/riscv/macroAssembler_riscv.cpp | 50 ++++++++++++++++++- .../cpu/riscv/macroAssembler_riscv.hpp | 4 ++ src/hotspot/cpu/riscv/riscv.ad | 8 +-- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 22 +++----- src/hotspot/cpu/riscv/vtableStubs_riscv.cpp | 5 +- 7 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index 580901694542a..edee30def7056 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -265,26 +265,7 @@ void LIR_Assembler::osr_entry() { // inline cache check; done before the frame is built. int LIR_Assembler::check_icache() { - Register receiver = FrameMap::receiver_opr->as_register(); - Register ic_klass = IC_Klass; - int start_offset = __ offset(); - Label dont; - __ inline_cache_check(receiver, ic_klass, dont); - - // if icache check fails, then jump to runtime routine - // Note: RECEIVER must still contain the receiver! - __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - - // We align the verified entry point unless the method body - // (including its inline cache check) will fit in a single 64-byte - // icache line. - if (!method()->is_accessor() || __ offset() - start_offset > 4 * 4) { - // force alignment after the cache check. - __ align(CodeEntryAlignment); - } - - __ bind(dont); - return start_offset; + return __ ic_check(CodeEntryAlignment); } void LIR_Assembler::jobject2reg(jobject o, Register reg) { diff --git a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp index 6c1dce0de1598..2961b1a91ceab 100644 --- a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp @@ -314,15 +314,6 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1 verify_oop(obj); } -void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache, Label &L) { - verify_oop(receiver); - // explicit null check not needed since load from [klass_offset] causes a trap - // check against inline cache - assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); - assert_different_registers(receiver, iCache, t0, t2); - cmp_klass(receiver, iCache, t0, t2 /* call-clobbered t2 as a tmp */, L); -} - void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) { assert(bang_size_in_bytes >= framesize, "stack bang size incorrect"); // Make sure there is enough stack space for this method's activation. diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 39281dcc20a3a..6225093857f1d 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -27,6 +27,7 @@ #include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" +#include "code/compiledIC.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -3310,14 +3311,61 @@ address MacroAssembler::trampoline_call(Address entry) { return call_pc; } +uintptr_t MacroAssembler::create_ic_data() { +#ifdef COMPILER2 + if (code_section()->scratch_emit()) { + return (uintptr_t)Universe::non_oop_word(); + } +#endif + return (uintptr_t)new CompiledICData(); +} + address MacroAssembler::ic_call(address entry, jint method_index) { RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index); IncompressibleRegion ir(this); // relocations - movptr(t1, (address)Universe::non_oop_word()); + movptr(t1, create_ic_data()); assert_cond(entry != nullptr); return trampoline_call(Address(entry, rh)); } +int MacroAssembler::ic_check_size() { + return NativeInstruction::instruction_size * 9; +} + +int MacroAssembler::ic_check(int end_alignment) { + IncompressibleRegion ir(this); + Register receiver = j_rarg0; + Register data = t1; + Register tmp = t0; + + int start_offset = offset(); + + align(end_alignment, offset() + ic_check_size()); + + int uep_offset = offset(); + + if (UseCompressedClassPointers) { + lw(tmp, Address(receiver, oopDesc::klass_offset_in_bytes())); + lw(data, Address(data, CompiledICData::speculated_klass_offset())); + } else { + ld(tmp, Address(receiver, oopDesc::klass_offset_in_bytes())); + ld(data, Address(data, CompiledICData::speculated_klass_offset())); + } + + Label dont; + beq(data, tmp, dont); + far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); + bind(dont); + + int beoffs = offset(); + align(end_alignment, 0); + + int offs = offset(); + assert((offs % end_alignment) == 0, "Misaligned verified entry point: %d %d %d %d %d %d", + start_offset, uep_offset, beoffs, offs, ic_check_size(), end_alignment); + return uep_offset; +} + // Emit a trampoline stub for a call to a target which is too far away. // // code sequences: diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 1a8271166a9cc..8c8f6d180906e 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1169,7 +1169,11 @@ class MacroAssembler: public Assembler { // // Return: the call PC or null if CodeCache is full. address trampoline_call(Address entry); + + uintptr_t create_ic_data(); address ic_call(address entry, jint method_index = 0); + static int ic_check_size(); + int ic_check(int end_alignment); // Support for memory inc/dec // n.b. increment/decrement calls with an Address destination will diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 7ce4bf91aa1b0..c1581f27a61d2 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1824,12 +1824,8 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { // This is the unverified entry point. C2_MacroAssembler _masm(&cbuf); - - Label skip; - __ cmp_klass(j_rarg0, t1, t0, t2 /* call-clobbered t2 as a tmp */, skip); - __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - __ bind(skip); - + __ ic_check(CodeEntryAlignment); + // These NOPs are critical so that verified entry point is properly // 4 bytes aligned for patching by NativeJump::patch_verified_entry() __ align(NativeInstruction::instruction_size); diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 7ee16c6480c93..1eb87642075a3 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -638,11 +638,9 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm { __ block_comment("c2i_unverified_entry {"); - __ load_klass(t0, receiver, tmp); - __ ld(tmp, Address(holder, CompiledICHolder::holder_klass_offset())); - __ ld(xmethod, Address(holder, CompiledICHolder::holder_metadata_offset())); - __ beq(t0, tmp, ok); - __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); + + __ ic_check(1 /* end_alignment */); + __ ld(xmethod, Address(holder, CompiledICData::speculated_method_offset())); __ bind(ok); // Method might have been compiled since the call site was patched to @@ -1423,19 +1421,10 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, const Register ic_reg = t1; const Register receiver = j_rarg0; - Label hit; - Label exception_pending; - __ verify_oop(receiver); - assert_different_registers(ic_reg, receiver, t0, t2); - __ cmp_klass(receiver, ic_reg, t0, t2 /* call-clobbered t2 as a tmp */, hit); + assert_different_registers(receiver, t0, t1); - __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - - // Verified entry point must be aligned - __ align(8); - - __ bind(hit); + __ ic_check(8 /* end_alignment */); int vep_offset = ((intptr_t)__ pc()) - start; @@ -1870,6 +1859,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ leave(); // Any exception pending? + Label exception_pending; __ ld(t0, Address(xthread, in_bytes(Thread::pending_exception_offset()))); __ bnez(t0, exception_pending); diff --git a/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp b/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp index 86aa4bdc42b42..7b9f0dbe85325 100644 --- a/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp @@ -27,6 +27,7 @@ #include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" +#include "code/compiledIC.hpp" #include "code/vtableStubs.hpp" #include "interp_masm_riscv.hpp" #include "memory/resourceArea.hpp" @@ -184,8 +185,8 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { Label L_no_such_interface; - __ ld(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset())); - __ ld(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset())); + __ ld(resolved_klass_reg, Address(icholder_reg, CompiledICData::itable_refc_klass_offset())); + __ ld(holder_klass_reg, Address(icholder_reg, CompiledICData::itable_defc_klass_offset())); start_pc = __ pc();