From f3a88ad261fd45159b1161e78431862e8062c11a Mon Sep 17 00:00:00 2001 From: jiangfeilong Date: Thu, 23 Nov 2023 22:02:21 +0800 Subject: [PATCH] RISC-V: Small refactoring for external and runtime calls --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 2 +- src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp | 13 +-- .../cpu/riscv/c1_LIRAssembler_riscv.cpp | 6 +- src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp | 16 +-- src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp | 11 +- .../gc/g1/g1BarrierSetAssembler_riscv.cpp | 5 +- .../gc/shared/barrierSetAssembler_riscv.cpp | 7 +- .../riscv/gc/x/xBarrierSetAssembler_riscv.cpp | 4 +- src/hotspot/cpu/riscv/icBuffer_riscv.cpp | 5 +- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 4 +- .../cpu/riscv/jniFastGetField_riscv.cpp | 8 +- .../cpu/riscv/macroAssembler_riscv.cpp | 103 ++++++++---------- .../cpu/riscv/macroAssembler_riscv.hpp | 32 ++---- src/hotspot/cpu/riscv/riscv.ad | 6 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 75 ++----------- src/hotspot/cpu/riscv/templateTable_riscv.cpp | 10 +- 16 files changed, 101 insertions(+), 206 deletions(-) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 3ee03b4b39022..2a0c30ca40fd6 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -908,7 +908,7 @@ enum operand_size { int8, int16, int32, uint32, int64 }; } INSN(_lui, 0b0110111); - INSN(auipc, 0b0010111); + INSN(_auipc, 0b0010111); #undef INSN diff --git a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp index 530b99dd06b7f..4aa210d75b440 100644 --- a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ void C1SafepointPollStub::emit_code(LIR_Assembler* ce) { InternalAddress safepoint_pc(__ pc() - __ offset() + safepoint_offset()); __ relocate(safepoint_pc.rspec(), [&] { int32_t offset; - __ la_patchable(t0, safepoint_pc.target(), offset); + __ auipc(t0, safepoint_pc.target(), offset); __ addi(t0, t0, offset); }); __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); @@ -92,12 +92,9 @@ void RangeCheckStub::emit_code(LIR_Assembler* ce) { __ mv(t1, _array->as_pointer_register()); stub_id = Runtime1::throw_range_check_failed_id; } - RuntimeAddress target(Runtime1::entry_for(stub_id)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(ra, target, offset); - __ jalr(ra, ra, offset); - }); + // t0 and t1 are used as args in generate_exception_throw, + // so use ra as the tmp register for rt_call. + __ rt_call(Runtime1::entry_for(stub_id), ra); ce->add_call_info_here(_info); ce->verify_oop_map(_info); debug_only(__ should_not_reach_here()); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index 953478d05ae7e..9e27dd3598271 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -402,7 +402,7 @@ int LIR_Assembler::emit_deopt_handler() { int offset = code_offset(); - __ auipc(ra, 0); + __ _auipc(ra, 0); __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); guarantee(code_offset() - offset <= deopt_handler_size(), "overflow"); __ end_a_stub(); @@ -1426,7 +1426,7 @@ void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmit InternalAddress pc_for_athrow(__ pc()); __ relocate(pc_for_athrow.rspec(), [&] { int32_t offset; - __ la_patchable(exceptionPC->as_register(), pc_for_athrow, offset); + __ auipc(exceptionPC->as_register(), pc_for_athrow, offset); __ addi(exceptionPC->as_register(), exceptionPC->as_register(), offset); }); add_call_info(pc_for_athrow_offset, info); // for exception handler @@ -1860,7 +1860,7 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg RuntimeAddress target(dest); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ movptr(t0, target.target(), offset); __ jalr(x1, t0, offset); }); } diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index ea086d46bdac2..b76163a30841d 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,12 +67,7 @@ int StubAssembler::call_RT(Register oop_result, Register metadata_result, addres set_last_Java_frame(sp, fp, retaddr, t0); // do the call - RuntimeAddress target(entry); - relocate(target.rspec(), [&] { - int32_t offset; - la_patchable(t0, target, offset); - jalr(x1, t0, offset); - }); + rt_call(entry); bind(retaddr); int call_offset = offset(); // verify callee-saved register @@ -578,12 +573,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { Label retaddr; __ set_last_Java_frame(sp, fp, retaddr, t0); // do the call - RuntimeAddress addr(target); - __ relocate(addr.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, addr, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(target); __ bind(retaddr); OopMapSet* oop_maps = new OopMapSet(); assert_cond(oop_maps != nullptr); diff --git a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp index d1c66ce1da76a..b10868de35736 100644 --- a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ void C2SafepointPollStub::emit(C2_MacroAssembler& masm) { InternalAddress safepoint_pc(__ pc() - __ offset() + _safepoint_offset); __ relocate(safepoint_pc.rspec(), [&] { int32_t offset; - __ la_patchable(t0, safepoint_pc.target(), offset); + __ auipc(t0, safepoint_pc.target(), offset); __ addi(t0, t0, offset); }); __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); @@ -60,12 +60,7 @@ int C2EntryBarrierStub::max_size() const { void C2EntryBarrierStub::emit(C2_MacroAssembler& masm) { __ bind(entry()); - RuntimeAddress target(StubRoutines::method_entry_barrier()); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(ra, t0, offset); - }); + __ rt_call(StubRoutines::method_entry_barrier()); __ j(continuation()); diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 27130dbc3d968..5d0b0fb472934 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -187,7 +187,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, BarrierSet* bs = BarrierSet::barrier_set(); CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); Label done; Label runtime; @@ -204,7 +203,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, // storing region crossing non-null, is card already dirty? - ExternalAddress cardtable((address) ct->byte_map_base()); const Register card_addr = tmp1; __ srli(card_addr, store_addr, CardTable::card_shift()); @@ -410,7 +408,6 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* BarrierSet* bs = BarrierSet::barrier_set(); CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); Label done; Label runtime; diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp index a4440890b0961..1ac1fc18f1ee0 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp @@ -308,12 +308,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slo Label skip_barrier; __ beq(t0, t1, skip_barrier); - RuntimeAddress target(StubRoutines::method_entry_barrier()); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(ra, t0, offset); - }); + __ rt_call(StubRoutines::method_entry_barrier()); __ j(skip_barrier); diff --git a/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp index c48eac944c129..a5e1d7a4a134a 100644 --- a/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -342,7 +342,7 @@ void XBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, X Address target(stub->slow_path()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ movptr(t0, target.target(), offset); __ jalr(x1, t0, offset); }); } diff --git a/src/hotspot/cpu/riscv/icBuffer_riscv.cpp b/src/hotspot/cpu/riscv/icBuffer_riscv.cpp index 997611df4a3ab..ab904817816fc 100644 --- a/src/hotspot/cpu/riscv/icBuffer_riscv.cpp +++ b/src/hotspot/cpu/riscv/icBuffer_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,7 @@ int InlineCacheBuffer::ic_stub_code_size() { // 6: auipc + ld + auipc + jalr + address(2 * instruction_size) - // 5: auipc + ld + j + address(2 * instruction_size) - return (MacroAssembler::far_branches() ? 6 : 5) * NativeInstruction::instruction_size; + return 6 * NativeInstruction::instruction_size; } #define __ masm-> diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 1240566e26cc4..827dd1178d504 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,7 +194,7 @@ void InterpreterMacroAssembler::get_dispatch() { ExternalAddress target((address)Interpreter::dispatch_table()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(xdispatch, target, offset); + auipc(xdispatch, target, offset); addi(xdispatch, xdispatch, offset); }); } diff --git a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp index 87890d359ee91..195b1c5ef6697 100644 --- a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { Address target(SafepointSynchronize::safepoint_counter_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(rcounter_addr, target, offset); + __ auipc(rcounter_addr, target, offset); __ addi(rcounter_addr, rcounter_addr, offset); }); @@ -96,7 +96,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(result, target, offset); + __ auipc(result, target, offset); __ lwu(result, Address(result, offset)); }); __ bnez(result, slow); @@ -176,7 +176,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress target(slow_case_addr); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ jalr(x1, t0, offset); }); __ leave(); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 8f516f38e7d9a..1ebb2d3011b80 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -340,7 +340,7 @@ void MacroAssembler::call_VM_base(Register oop_result, RuntimeAddress target(StubRoutines::forward_exception_entry()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t0, target, offset); + auipc(t0, target, offset); jalr(x0, t0, offset); }); bind(ok); @@ -421,7 +421,7 @@ void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file, ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t1, target, offset); + auipc(t1, target, offset); ld(t1, Address(t1, offset)); }); jalr(t1); @@ -466,7 +466,7 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* f ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t1, target, offset); + auipc(t1, target, offset); ld(t1, Address(t1, offset)); }); jalr(t1); @@ -720,7 +720,7 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg void MacroAssembler::la(Register Rd, const address dest) { int64_t offset = dest - pc(); if (is_simm32(offset)) { - auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit + _auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit addi(Rd, Rd, ((int64_t)offset << 52) >> 52); } else { movptr(Rd, dest); @@ -1564,7 +1564,7 @@ void MacroAssembler::reinit_heapbase() { ExternalAddress target(CompressedOops::ptrs_base_addr()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(xheapbase, target, offset); + auipc(xheapbase, target, offset); ld(xheapbase, Address(xheapbase, offset)); }); } @@ -2119,7 +2119,7 @@ SkipIfEqual::SkipIfEqual(MacroAssembler* masm, const bool* flag_addr, bool value ExternalAddress target((address)flag_addr); _masm->relocate(target.rspec(), [&] { int32_t offset; - _masm->la_patchable(t0, target, offset); + _masm->auipc(t0, target, offset); _masm->lbu(t0, Address(t0, offset)); }); if (value) { @@ -2893,46 +2893,36 @@ ATOMIC_XCHGU(xchgalwu, xchgalw) #undef ATOMIC_XCHGU -void MacroAssembler::far_jump(Address entry, Register tmp) { +void MacroAssembler::far_jump(const Address &entry, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type || entry.rspec().type() == relocInfo::runtime_call_type || entry.rspec().type() == relocInfo::none, "wrong entry relocInfo type"); - IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() - if (far_branches()) { - // We can use auipc + jalr here because we know that the total size of - // the code cache cannot exceed 2Gb. - relocate(entry.rspec(), [&] { - int32_t offset; - la_patchable(tmp, entry, offset); - jalr(x0, tmp, offset); - }); - } else { - j(entry); - } + // Fixed length: see MacroAssembler::far_branch_size() + relocate(entry.rspec(), [&] { + int32_t offset; + auipc(tmp, entry, offset); + jalr(x0, tmp, offset); + }); } -void MacroAssembler::far_call(Address entry, Register tmp) { +void MacroAssembler::far_call(const Address &entry, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type || entry.rspec().type() == relocInfo::runtime_call_type || entry.rspec().type() == relocInfo::none, "wrong entry relocInfo type"); - IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() - if (far_branches()) { - // We can use auipc + jalr here because we know that the total size of - // the code cache cannot exceed 2Gb. - relocate(entry.rspec(), [&] { - int32_t offset; - la_patchable(tmp, entry, offset); - jalr(x1, tmp, offset); // link - }); - } else { - jal(entry); // link - } + // Fixed length: see MacroAssembler::far_branch_size() + // We can use auipc + jalr here because we know that the total size of + // the code cache cannot exceed 2Gb. + relocate(entry.rspec(), [&] { + int32_t offset; + auipc(tmp, entry, offset); + jalr(x1, tmp, offset); // link + }); } void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, @@ -3155,14 +3145,14 @@ void MacroAssembler::load_byte_map_base(Register reg) { mv(reg, (uint64_t)byte_map_base); } -void MacroAssembler::la_patchable(Register reg1, const Address &dest, int32_t &offset) { +void MacroAssembler::auipc(Register reg, const Address &dest, int32_t &offset) { unsigned long low_address = (uintptr_t)CodeCache::low_bound(); unsigned long high_address = (uintptr_t)CodeCache::high_bound(); unsigned long dest_address = (uintptr_t)dest.target(); long offset_low = dest_address - low_address; long offset_high = dest_address - high_address; - assert(dest.getMode() == Address::literal, "la_patchable must be applied to a literal address"); + assert(dest.getMode() == Address::literal, "auipc must be applied to a literal address"); assert((uintptr_t)dest.target() < (1ull << 48), "bad address"); // RISC-V doesn't compute a page-aligned address, in order to partially @@ -3171,10 +3161,10 @@ void MacroAssembler::la_patchable(Register reg1, const Address &dest, int32_t &o // [-(2G + 2K), 2G - 2K). if (offset_high >= -((1L << 31) + (1L << 11)) && offset_low < (1L << 31) - (1L << 11)) { int64_t distance = dest.target() - pc(); - auipc(reg1, (int32_t)distance + 0x800); + _auipc(reg, (int32_t)distance + 0x800); offset = ((int32_t)distance << 20) >> 20; } else { - movptr(reg1, dest.target(), offset); + movptr(reg, dest.target(), offset); } } @@ -3204,21 +3194,16 @@ void MacroAssembler::reserved_stack_check() { enter(); // RA and FP are live. mv(c_rarg0, xthread); - RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)); - relocate(target.rspec(), [&] { - int32_t offset; - la_patchable(t0, target, offset); - jalr(x1, t0, offset); - }); + rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)); leave(); // We have already removed our own frame. // throw_delayed_StackOverflowError will think that it's been // called by our caller. - target = RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()); + RuntimeAddress target(StubRoutines::throw_delayed_StackOverflowError_entry()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t0, target, offset); + movptr(t0, target.target(), offset); jalr(x0, t0, offset); }); should_not_reach_here(); @@ -3280,21 +3265,19 @@ address MacroAssembler::trampoline_call(Address entry) { address target = entry.target(); // We need a trampoline if branches are far. - if (far_branches()) { - if (!in_scratch_emit_size()) { - if (entry.rspec().type() == relocInfo::runtime_call_type) { - assert(CodeBuffer::supports_shared_stubs(), "must support shared stubs"); - code()->share_trampoline_for(entry.target(), offset()); - } else { - address stub = emit_trampoline_stub(offset(), target); - if (stub == nullptr) { - postcond(pc() == badAddress); - return nullptr; // CodeCache is full - } + if (!in_scratch_emit_size()) { + if (entry.rspec().type() == relocInfo::runtime_call_type) { + assert(CodeBuffer::supports_shared_stubs(), "must support shared stubs"); + code()->share_trampoline_for(entry.target(), offset()); + } else { + address stub = emit_trampoline_stub(offset(), target); + if (stub == nullptr) { + postcond(pc() == badAddress); + return nullptr; // CodeCache is full } } - target = pc(); } + target = pc(); address call_pc = pc(); #ifdef ASSERT @@ -3442,7 +3425,7 @@ void MacroAssembler::cmpptr(Register src1, Address src2, Label& equal) { assert_different_registers(src1, t0); relocate(src2.rspec(), [&] { int32_t offset; - la_patchable(t0, src2, offset); + auipc(t0, src2, offset); ld(t0, Address(t0, offset)); }); beq(src1, t0, equal); @@ -4090,7 +4073,7 @@ address MacroAssembler::zero_words(Register ptr, Register cnt) { Label around, done, done16; bltu(cnt, t0, around); { - RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::riscv::zero_blocks()); + RuntimeAddress zero_blocks(StubRoutines::riscv::zero_blocks()); assert(zero_blocks.target() != nullptr, "zero_blocks stub has not been generated"); if (StubRoutines::riscv::complete()) { address tpc = trampoline_call(zero_blocks); @@ -4685,11 +4668,11 @@ void MacroAssembler::rt_call(address dest, Register tmp) { CodeBlob *cb = CodeCache::find_blob(dest); RuntimeAddress target(dest); if (cb) { - far_call(target); + far_call(target, tmp); } else { relocate(target.rspec(), [&] { int32_t offset; - la_patchable(tmp, target, offset); + movptr(tmp, target.target(), offset); jalr(x1, tmp, offset); }); } diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 1a8271166a9cc..26c6f93d5d3d1 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -811,7 +811,7 @@ class MacroAssembler: public Assembler { assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ if (is_simm32(distance)) { \ - auipc(Rd, (int32_t)distance + 0x800); \ + _auipc(Rd, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, Rd, ((int32_t)distance << 20) >> 20); \ } else { \ int32_t offset = 0; \ @@ -868,7 +868,7 @@ class MacroAssembler: public Assembler { assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ if (is_simm32(distance)) { \ - auipc(temp, (int32_t)distance + 0x800); \ + _auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, temp, ((int32_t)distance << 20) >> 20); \ } else { \ int32_t offset = 0; \ @@ -929,7 +929,7 @@ class MacroAssembler: public Assembler { assert_different_registers(Rs, temp); \ int64_t distance = dest - pc(); \ if (is_simm32(distance)) { \ - auipc(temp, (int32_t)distance + 0x800); \ + _auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ int32_t offset = 0; \ @@ -974,7 +974,7 @@ class MacroAssembler: public Assembler { assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ if (is_simm32(distance)) { \ - auipc(temp, (int32_t)distance + 0x800); \ + _auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ int32_t offset = 0; \ @@ -1053,28 +1053,18 @@ class MacroAssembler: public Assembler { void atomic_xchgwu(Register prev, Register newv, Register addr); void atomic_xchgalwu(Register prev, Register newv, Register addr); - static bool far_branches() { - return ReservedCodeCacheSize > branch_range; - } - - // Emit a direct call/jump if the entry address will always be in range, - // otherwise a far call/jump. + // Emit a far call/jump. Only invalidates the tmp register which + // is used to keep the entry address for jalr. // The address must be inside the code cache. // Supported entry.rspec(): // - relocInfo::external_word_type // - relocInfo::runtime_call_type // - relocInfo::none - // In the case of a far call/jump, the entry address is put in the tmp register. - // The tmp register is invalidated. - void far_call(Address entry, Register tmp = t0); - void far_jump(Address entry, Register tmp = t0); + void far_call(const Address &entry, Register tmp = t0); + void far_jump(const Address &entry, Register tmp = t0); static int far_branch_size() { - if (far_branches()) { return 2 * 4; // auipc + jalr, see far_call() & far_jump() - } else { - return 4; - } } void load_byte_map_base(Register reg); @@ -1086,7 +1076,7 @@ class MacroAssembler: public Assembler { sd(zr, Address(t0)); } - void la_patchable(Register reg1, const Address &dest, int32_t &offset); + void auipc(Register reg, const Address &dest, int32_t &offset); virtual void _call_Unimplemented(address call_site) { mv(t1, call_site); @@ -1421,6 +1411,8 @@ class MacroAssembler: public Assembler { VMRegPair dst, bool is_receiver, int* receiver_offset); + // Emit a runtime call. Only invalidates the tmp register which + // is used to keep the entry address for jalr/movptr. void rt_call(address dest, Register tmp = t0); void call(const address dest, Register temp = t0) { @@ -1460,7 +1452,7 @@ class MacroAssembler: public Assembler { InternalAddress target(const_addr.target()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(dest, target, offset); + auipc(dest, target, offset); ld(dest, Address(dest, offset)); }); } diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 87f240873a85b..2848a1df6fdff 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1848,10 +1848,8 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const // Emit exception handler code. int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) { - // la_patchable t0, #exception_blob_entry_point + // auipc t0, #exception_blob_entry_point // jr (offset)t0 - // or - // j #exception_blob_entry_point // Note that the code buffer's insts_mark is always relative to insts. // That's why we must use the macroassembler to generate a handler. C2_MacroAssembler _masm(&cbuf); @@ -1880,7 +1878,7 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) } int offset = __ offset(); - __ auipc(ra, 0); + __ _auipc(ra, 0); __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index fa718e5b08e86..76d3ebc09a074 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -344,12 +344,7 @@ static void patch_callers_callsite(MacroAssembler *masm) { __ mv(c_rarg0, xmethod); __ mv(c_rarg1, ra); - RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)); __ pop_CPU_state(); // restore sp @@ -1622,7 +1617,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ExternalAddress target((address)&DTraceMethodProbes); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lbu(t0, Address(t0, offset)); }); __ bnez(t0, dtrace_method_entry); @@ -1846,7 +1841,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ExternalAddress target((address)&DTraceMethodProbes); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lbu(t0, Address(t0, offset)); }); __ bnez(t0, dtrace_method_exit); @@ -1979,12 +1974,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, #ifndef PRODUCT assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); #endif - RuntimeAddress target(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); @@ -2156,12 +2146,7 @@ void SharedRuntime::generate_deopt_blob() { __ mv(xcpool, Deoptimization::Unpack_reexecute); __ mv(c_rarg0, xthread); __ orrw(c_rarg2, zr, xcpool); // exec mode - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); __ bind(retaddr); oop_maps->add_gc_map( __ pc()-start, map->deep_copy()); @@ -2253,12 +2238,7 @@ void SharedRuntime::generate_deopt_blob() { #endif // ASSERT __ mv(c_rarg0, xthread); __ mv(c_rarg1, xcpool); - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)); __ bind(retaddr); // Need to have an oopmap that tells fetch_unroll_info where to @@ -2400,12 +2380,7 @@ void SharedRuntime::generate_deopt_blob() { __ mv(c_rarg0, xthread); __ mv(c_rarg1, xcpool); // second arg: exec_mode - target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); // Set an oopmap for the call site // Use the same PC we used for the last java frame @@ -2495,12 +2470,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ mv(c_rarg0, xthread); __ mv(c_rarg2, Deoptimization::Unpack_uncommon_trap); - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); __ bind(retaddr); // Set an oopmap for the call site @@ -2622,12 +2592,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // sp should already be aligned __ mv(c_rarg0, xthread); __ mv(c_rarg1, Deoptimization::Unpack_uncommon_trap); - target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); // Set an oopmap for the call site // Use the same PC we used for the last java frame @@ -2696,12 +2661,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t // Do the call __ mv(c_rarg0, xthread); - RuntimeAddress target(call_ptr); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(call_ptr); __ bind(retaddr); // Set an oopmap for the call site. This oopmap will map all @@ -2809,12 +2769,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha __ set_last_Java_frame(sp, noreg, retaddr, t0); __ mv(c_rarg0, xthread); - RuntimeAddress target(destination); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(destination); __ bind(retaddr); } @@ -2943,13 +2898,7 @@ void OptoRuntime::generate_exception_blob() { address the_pc = __ pc(); __ set_last_Java_frame(sp, noreg, the_pc, t0); __ mv(c_rarg0, xthread); - RuntimeAddress target(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); - + __ rt_call(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)); // handle_exception_C is a special VM call which does not require an explicit // instruction sync afterwards. diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index ecc4520164d52..4525b840d7cd9 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2471,7 +2471,7 @@ void TemplateTable::jvmti_post_field_access(Register cache, Register index, ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lwu(x10, Address(t0, offset)); }); @@ -2682,7 +2682,7 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lwu(x10, Address(t0, offset)); }); __ beqz(x10, L1); @@ -2975,7 +2975,7 @@ void TemplateTable::jvmti_post_fast_field_mod() { ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lwu(c_rarg3, Address(t0, offset)); }); __ beqz(c_rarg3, L2); @@ -3111,7 +3111,7 @@ void TemplateTable::fast_accessfield(TosState state) { ExternalAddress target((address)JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ auipc(t0, target, offset); __ lwu(x12, Address(t0, offset)); }); __ beqz(x12, L1);