Skip to content

Commit 5c612c2

Browse files
committed
8332689: RISC-V: Use load instead of trampolines
Reviewed-by: fyang, mli, luhenry
1 parent 6fcd49f commit 5c612c2

16 files changed

+720
-275
lines changed

src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
318318
}
319319
Address resolve(SharedRuntime::get_resolve_static_call_stub(),
320320
relocInfo::static_call_type);
321-
address call = __ trampoline_call(resolve);
321+
address call = __ reloc_call(resolve);
322322
if (call == nullptr) {
323323
ce->bailout("trampoline stub overflow");
324324
return;

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ void LIR_Assembler::align_call(LIR_Code code) {
13461346
}
13471347

13481348
void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
1349-
address call = __ trampoline_call(Address(op->addr(), rtype));
1349+
address call = __ reloc_call(Address(op->addr(), rtype));
13501350
if (call == nullptr) {
13511351
bailout("trampoline stub overflow");
13521352
return;

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ friend class ArrayCopyStub;
6969
enum {
7070
// See emit_static_call_stub for detail
7171
// CompiledDirectCall::to_interp_stub_size() (14) + CompiledDirectCall::to_trampoline_stub_size() (1 + 3 + address)
72-
_call_stub_size = 14 * NativeInstruction::instruction_size +
73-
(NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size),
72+
_call_stub_size = 14 * MacroAssembler::instruction_size +
73+
(MacroAssembler::instruction_size + MacroAssembler::NativeShortCall::trampoline_size),
7474
// See emit_exception_handler for detail
7575
// verify_not_null_oop + far_call + should_not_reach_here + invalidate_registers(DEBUG_ONLY)
7676
_exception_handler_size = DEBUG_ONLY(584) NOT_DEBUG(548), // or smaller
7777
// See emit_deopt_handler for detail
7878
// auipc (1) + far_jump (6 or 2)
79-
_deopt_handler_size = 1 * NativeInstruction::instruction_size +
80-
6 * NativeInstruction::instruction_size // or smaller
79+
_deopt_handler_size = 1 * MacroAssembler::instruction_size +
80+
6 * MacroAssembler::instruction_size // or smaller
8181
};
8282

8383
void check_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp,

src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle,
10401040
stub = RuntimeAddress(StubRoutines::riscv::string_indexof_linear_uu());
10411041
assert(stub.target() != nullptr, "string_indexof_linear_uu stub has not been generated");
10421042
}
1043-
address call = trampoline_call(stub);
1043+
address call = reloc_call(stub);
10441044
if (call == nullptr) {
10451045
DEBUG_ONLY(reset_labels(LINEARSEARCH, DONE, NOMATCH));
10461046
ciEnv::current()->record_failure("CodeCache is full");
@@ -1478,7 +1478,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
14781478
ShouldNotReachHere();
14791479
}
14801480
assert(stub.target() != nullptr, "compare_long_string stub has not been generated");
1481-
address call = trampoline_call(stub);
1481+
address call = reloc_call(stub);
14821482
if (call == nullptr) {
14831483
DEBUG_ONLY(reset_labels(DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, SHORT_LOOP_START));
14841484
ciEnv::current()->record_failure("CodeCache is full");

src/hotspot/cpu/riscv/codeBuffer_riscv.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,18 @@ static bool emit_shared_trampolines(CodeBuffer* cb, CodeBuffer::SharedTrampoline
5050
if (requests == nullptr) {
5151
return true;
5252
}
53+
assert(UseTrampolines, "We are not using trampolines");
5354

5455
MacroAssembler masm(cb);
5556

5657
auto emit = [&](address dest, const CodeBuffer::Offsets &offsets) {
57-
assert(cb->stubs()->remaining() >= MacroAssembler::max_trampoline_stub_size(), "pre-allocated trampolines");
58+
assert(cb->stubs()->remaining() >= MacroAssembler::max_reloc_call_stub_size(), "pre-allocated trampolines");
5859
LinkedListIterator<int> it(offsets.head());
5960
int offset = *it.next();
6061
address stub = __ emit_trampoline_stub(offset, dest);
6162
assert(stub, "pre-allocated trampolines");
6263

63-
address reloc_pc = cb->stubs()->end() - NativeCallTrampolineStub::instruction_size;
64+
address reloc_pc = cb->stubs()->end() - MacroAssembler::NativeShortCall::trampoline_size;
6465
while (!it.is_empty()) {
6566
offset = *it.next();
6667
address caller_pc = cb->insts()->start() + offset;
@@ -70,7 +71,7 @@ static bool emit_shared_trampolines(CodeBuffer* cb, CodeBuffer::SharedTrampoline
7071
};
7172

7273
assert(requests->number_of_entries() >= 1, "at least one");
73-
const int total_requested_size = MacroAssembler::max_trampoline_stub_size() * requests->number_of_entries();
74+
const int total_requested_size = MacroAssembler::max_reloc_call_stub_size() * requests->number_of_entries();
7475
if (cb->stubs()->maybe_expand_to_ensure_remaining(total_requested_size) && cb->blob() == nullptr) {
7576
return false;
7677
}

src/hotspot/cpu/riscv/codeBuffer_riscv.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
public:
3535
void flush_bundle(bool start_new_bundle) {}
36-
static constexpr bool supports_shared_stubs() { return true; }
36+
static bool supports_shared_stubs() { return UseTrampolines; }
3737

3838
void share_trampoline_for(address dest, int caller_offset);
3939

src/hotspot/cpu/riscv/compiledIC_riscv.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ int CompiledDirectCall::to_interp_stub_size() {
6969
}
7070

7171
int CompiledDirectCall::to_trampoline_stub_size() {
72-
// Somewhat pessimistically, we count 4 instructions here (although
73-
// there are only 3) because we sometimes emit an alignment nop.
72+
// We count instructions and an additional alignment nop.
7473
// Trampoline stubs are always word aligned.
75-
return MacroAssembler::max_trampoline_stub_size();
74+
return MacroAssembler::max_reloc_call_stub_size();
7675
}
7776

7877
// Relocation entries for call stub, compiled java to interpreter.

src/hotspot/cpu/riscv/globals_riscv.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ define_pd_global(intx, InlineSmallCode, 1000);
120120
product(bool, UseZvkn, false, EXPERIMENTAL, \
121121
"Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
122122
product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \
123-
"Use RVV instructions for left/right shift of BigInteger")
123+
"Use RVV instructions for left/right shift of BigInteger") \
124+
product(bool, UseTrampolines, false, EXPERIMENTAL, \
125+
"Far calls uses jal to trampoline.")
124126

125127
#endif // CPU_RISCV_GLOBALS_RISCV_HPP

src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCI_TRAPS) {
4040
address pc = (address) inst;
4141
if (inst->is_call()) {
42-
return pc_offset + NativeCall::instruction_size;
42+
return pc_offset + NativeCall::byte_size();
4343
} else if (inst->is_jump()) {
4444
return pc_offset + NativeJump::instruction_size;
4545
} else if (inst->is_movptr1()) {

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -978,36 +978,23 @@ void MacroAssembler::li(Register Rd, int64_t imm) {
978978
}
979979
}
980980

981+
void MacroAssembler::load_link_jump(const address source, Register temp) {
982+
assert(temp != noreg && temp != x0, "expecting a register");
983+
assert_cond(source != nullptr);
984+
int64_t distance = source - pc();
985+
assert(is_simm32(distance), "Must be");
986+
auipc(temp, (int32_t)distance + 0x800);
987+
ld(temp, Address(temp, ((int32_t)distance << 20) >> 20));
988+
jalr(temp);
989+
}
990+
981991
void MacroAssembler::jump_link(const address dest, Register temp) {
992+
assert(UseTrampolines, "Must be");
982993
assert_cond(dest != nullptr);
983994
int64_t distance = dest - pc();
984-
if (is_simm21(distance) && ((distance % 2) == 0)) {
985-
Assembler::jal(x1, distance);
986-
} else {
987-
assert(temp != noreg && temp != x0, "expecting a register");
988-
int32_t offset = 0;
989-
la(temp, dest, offset);
990-
jalr(temp, offset);
991-
}
992-
}
993-
994-
void MacroAssembler::jump_link(const Address &adr, Register temp) {
995-
switch (adr.getMode()) {
996-
case Address::literal: {
997-
relocate(adr.rspec(), [&] {
998-
jump_link(adr.target(), temp);
999-
});
1000-
break;
1001-
}
1002-
case Address::base_plus_offset: {
1003-
int32_t offset = ((int32_t)adr.offset() << 20) >> 20;
1004-
la(temp, Address(adr.base(), adr.offset() - offset));
1005-
jalr(temp, offset);
1006-
break;
1007-
}
1008-
default:
1009-
ShouldNotReachHere();
1010-
}
995+
assert(is_simm21(distance), "Must be");
996+
assert((distance % 2) == 0, "Must be");
997+
jal(x1, distance);
1011998
}
1012999

10131000
void MacroAssembler::j(const address dest, Register temp) {
@@ -3941,15 +3928,7 @@ bool MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass,
39413928
// The next slot to be inspected, by the stub we're about to call,
39423929
// is secondary_supers[r_array_index]. Bits 0 and 1 in the bitmap
39433930
// have been checked.
3944-
Address stub = RuntimeAddress(StubRoutines::lookup_secondary_supers_table_slow_path_stub());
3945-
if (stub_is_near) {
3946-
jump_link(stub, t0);
3947-
} else {
3948-
address call = trampoline_call(stub);
3949-
if (call == nullptr) {
3950-
return false; // trampoline allocation failed
3951-
}
3952-
}
3931+
rt_call(StubRoutines::lookup_secondary_supers_table_slow_path_stub());
39533932

39543933
BLOCK_COMMENT("} lookup_secondary_supers_table");
39553934

@@ -4258,12 +4237,42 @@ address MacroAssembler::trampoline_call(Address entry) {
42584237
return call_pc;
42594238
}
42604239

4240+
address MacroAssembler::load_and_call(Address entry) {
4241+
assert(entry.rspec().type() == relocInfo::runtime_call_type ||
4242+
entry.rspec().type() == relocInfo::opt_virtual_call_type ||
4243+
entry.rspec().type() == relocInfo::static_call_type ||
4244+
entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
4245+
4246+
address target = entry.target();
4247+
4248+
if (!in_scratch_emit_size()) {
4249+
address stub = emit_address_stub(offset(), target);
4250+
if (stub == nullptr) {
4251+
postcond(pc() == badAddress);
4252+
return nullptr; // CodeCache is full
4253+
}
4254+
}
4255+
4256+
address call_pc = pc();
4257+
#ifdef ASSERT
4258+
if (entry.rspec().type() != relocInfo::runtime_call_type) {
4259+
assert_alignment(call_pc);
4260+
}
4261+
#endif
4262+
relocate(entry.rspec(), [&] {
4263+
load_link_jump(target);
4264+
});
4265+
4266+
postcond(pc() != badAddress);
4267+
return call_pc;
4268+
}
4269+
42614270
address MacroAssembler::ic_call(address entry, jint method_index) {
42624271
RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index);
42634272
IncompressibleRegion ir(this); // relocations
42644273
movptr(t1, (address)Universe::non_oop_word(), t0);
42654274
assert_cond(entry != nullptr);
4266-
return trampoline_call(Address(entry, rh));
4275+
return reloc_call(Address(entry, rh));
42674276
}
42684277

42694278
int MacroAssembler::ic_check_size() {
@@ -4308,6 +4317,34 @@ int MacroAssembler::ic_check(int end_alignment) {
43084317
return uep_offset;
43094318
}
43104319

4320+
address MacroAssembler::emit_address_stub(int insts_call_instruction_offset, address dest) {
4321+
address stub = start_a_stub(max_reloc_call_stub_size());
4322+
if (stub == nullptr) {
4323+
return nullptr; // CodeBuffer::expand failed
4324+
}
4325+
4326+
// We are always 4-byte aligned here.
4327+
assert_alignment(pc());
4328+
4329+
// Make sure the address of destination 8-byte aligned.
4330+
align(wordSize, 0);
4331+
4332+
RelocationHolder rh = trampoline_stub_Relocation::spec(code()->insts()->start() +
4333+
insts_call_instruction_offset);
4334+
const int stub_start_offset = offset();
4335+
relocate(rh, [&] {
4336+
assert(offset() - stub_start_offset == 0,
4337+
"%ld - %ld == %ld : should be", (long)offset(), (long)stub_start_offset, (long)0);
4338+
assert(offset() % wordSize == 0, "bad alignment");
4339+
emit_int64((int64_t)dest);
4340+
});
4341+
4342+
const address stub_start_addr = addr_at(stub_start_offset);
4343+
end_a_stub();
4344+
4345+
return stub_start_addr;
4346+
}
4347+
43114348
// Emit a trampoline stub for a call to a target which is too far away.
43124349
//
43134350
// code sequences:
@@ -4322,11 +4359,13 @@ int MacroAssembler::ic_check(int end_alignment) {
43224359
address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,
43234360
address dest) {
43244361
// Max stub size: alignment nop, TrampolineStub.
4325-
address stub = start_a_stub(max_trampoline_stub_size());
4362+
address stub = start_a_stub(max_reloc_call_stub_size());
43264363
if (stub == nullptr) {
43274364
return nullptr; // CodeBuffer::expand failed
43284365
}
43294366

4367+
assert(UseTrampolines, "Must be using trampos.");
4368+
43304369
// We are always 4-byte aligned here.
43314370
assert_alignment(pc());
43324371

@@ -4335,7 +4374,7 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,
43354374
// instructions code-section.
43364375

43374376
// Make sure the address of destination 8-byte aligned after 3 instructions.
4338-
align(wordSize, MacroAssembler::trampoline_stub_data_offset);
4377+
align(wordSize, MacroAssembler::NativeShortCall::trampoline_data_offset);
43394378

43404379
RelocationHolder rh = trampoline_stub_Relocation::spec(code()->insts()->start() +
43414380
insts_call_instruction_offset);
@@ -4348,23 +4387,25 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,
43484387
ld(t0, target); // auipc + ld
43494388
jr(t0); // jalr
43504389
bind(target);
4351-
assert(offset() - stub_start_offset == MacroAssembler::trampoline_stub_data_offset,
4390+
assert(offset() - stub_start_offset == MacroAssembler::NativeShortCall::trampoline_data_offset,
43524391
"should be");
43534392
assert(offset() % wordSize == 0, "bad alignment");
43544393
emit_int64((int64_t)dest);
43554394
});
43564395

43574396
const address stub_start_addr = addr_at(stub_start_offset);
43584397

4359-
assert(MacroAssembler::is_trampoline_stub_at(stub_start_addr), "doesn't look like a trampoline");
4360-
43614398
end_a_stub();
4399+
43624400
return stub_start_addr;
43634401
}
43644402

4365-
int MacroAssembler::max_trampoline_stub_size() {
4403+
int MacroAssembler::max_reloc_call_stub_size() {
43664404
// Max stub size: alignment nop, TrampolineStub.
4367-
return MacroAssembler::instruction_size + MacroAssembler::trampoline_stub_instruction_size;
4405+
if (UseTrampolines) {
4406+
return instruction_size + MacroAssembler::NativeShortCall::trampoline_size;
4407+
}
4408+
return instruction_size + wordSize;
43684409
}
43694410

43704411
int MacroAssembler::static_call_stub_size() {
@@ -5083,14 +5124,14 @@ address MacroAssembler::zero_words(Register ptr, Register cnt) {
50835124
RuntimeAddress zero_blocks(StubRoutines::riscv::zero_blocks());
50845125
assert(zero_blocks.target() != nullptr, "zero_blocks stub has not been generated");
50855126
if (StubRoutines::riscv::complete()) {
5086-
address tpc = trampoline_call(zero_blocks);
5127+
address tpc = reloc_call(zero_blocks);
50875128
if (tpc == nullptr) {
50885129
DEBUG_ONLY(reset_labels(around));
50895130
postcond(pc() == badAddress);
50905131
return nullptr;
50915132
}
50925133
} else {
5093-
jump_link(zero_blocks, t0);
5134+
rt_call(zero_blocks.target());
50945135
}
50955136
}
50965137
bind(around);

0 commit comments

Comments
 (0)