8293770: RISC-V: Reuse runtime call trampolines
Co-authored-by: zifeihan <caogui@iscas.ac.cn> Reviewed-by: fyang, shade
This commit is contained in:
parent
9dce8652f2
commit
7c60e6d2d6
@ -27,6 +27,56 @@
|
|||||||
#include "asm/codeBuffer.inline.hpp"
|
#include "asm/codeBuffer.inline.hpp"
|
||||||
#include "asm/macroAssembler.hpp"
|
#include "asm/macroAssembler.hpp"
|
||||||
|
|
||||||
bool CodeBuffer::pd_finalize_stubs() {
|
void CodeBuffer::share_trampoline_for(address dest, int caller_offset) {
|
||||||
return emit_shared_stubs_to_interp<MacroAssembler>(this, _shared_stub_to_interp_requests);
|
if (_shared_trampoline_requests == nullptr) {
|
||||||
|
constexpr unsigned init_size = 8;
|
||||||
|
constexpr unsigned max_size = 256;
|
||||||
|
_shared_trampoline_requests = new SharedTrampolineRequests(init_size, max_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool created;
|
||||||
|
Offsets* offsets = _shared_trampoline_requests->put_if_absent(dest, &created);
|
||||||
|
if (created) {
|
||||||
|
_shared_trampoline_requests->maybe_grow();
|
||||||
|
}
|
||||||
|
offsets->add(caller_offset);
|
||||||
|
_finalize_stubs = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool emit_shared_trampolines(CodeBuffer* cb, CodeBuffer::SharedTrampolineRequests* requests) {
|
||||||
|
if (requests == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroAssembler masm(cb);
|
||||||
|
|
||||||
|
bool p_succeeded = true;
|
||||||
|
auto emit = [&](address dest, const CodeBuffer::Offsets &offsets) {
|
||||||
|
masm.set_code_section(cb->stubs());
|
||||||
|
masm.align(wordSize, NativeCallTrampolineStub::data_offset);
|
||||||
|
|
||||||
|
LinkedListIterator<int> it(offsets.head());
|
||||||
|
int offset = *it.next();
|
||||||
|
for (; !it.is_empty(); offset = *it.next()) {
|
||||||
|
masm.relocate(trampoline_stub_Relocation::spec(cb->insts()->start() + offset));
|
||||||
|
}
|
||||||
|
masm.set_code_section(cb->insts());
|
||||||
|
|
||||||
|
address stub = masm.emit_trampoline_stub(offset, dest);
|
||||||
|
if (stub == nullptr) {
|
||||||
|
ciEnv::current()->record_failure("CodeCache is full");
|
||||||
|
p_succeeded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_succeeded;
|
||||||
|
};
|
||||||
|
|
||||||
|
requests->iterate(emit);
|
||||||
|
|
||||||
|
return p_succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodeBuffer::pd_finalize_stubs() {
|
||||||
|
return emit_shared_stubs_to_interp<MacroAssembler>(this, _shared_stub_to_interp_requests)
|
||||||
|
&& emit_shared_trampolines(this, _shared_trampoline_requests);
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,6 @@ public:
|
|||||||
void flush_bundle(bool start_new_bundle) {}
|
void flush_bundle(bool start_new_bundle) {}
|
||||||
static constexpr bool supports_shared_stubs() { return true; }
|
static constexpr bool supports_shared_stubs() { return true; }
|
||||||
|
|
||||||
|
void share_trampoline_for(address dest, int caller_offset);
|
||||||
|
|
||||||
#endif // CPU_RISCV_CODEBUFFER_RISCV_HPP
|
#endif // CPU_RISCV_CODEBUFFER_RISCV_HPP
|
||||||
|
@ -2801,6 +2801,8 @@ address MacroAssembler::trampoline_call(Address entry) {
|
|||||||
entry.rspec().type() == relocInfo::static_call_type ||
|
entry.rspec().type() == relocInfo::static_call_type ||
|
||||||
entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
|
entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
|
||||||
|
|
||||||
|
address target = entry.target();
|
||||||
|
|
||||||
// We need a trampoline if branches are far.
|
// We need a trampoline if branches are far.
|
||||||
if (far_branches()) {
|
if (far_branches()) {
|
||||||
bool in_scratch_emit_size = false;
|
bool in_scratch_emit_size = false;
|
||||||
@ -2813,12 +2815,18 @@ address MacroAssembler::trampoline_call(Address entry) {
|
|||||||
Compile::current()->output()->in_scratch_emit_size());
|
Compile::current()->output()->in_scratch_emit_size());
|
||||||
#endif
|
#endif
|
||||||
if (!in_scratch_emit_size) {
|
if (!in_scratch_emit_size) {
|
||||||
address stub = emit_trampoline_stub(offset(), entry.target());
|
if (entry.rspec().type() == relocInfo::runtime_call_type) {
|
||||||
if (stub == NULL) {
|
assert(CodeBuffer::supports_shared_stubs(), "must support shared stubs");
|
||||||
postcond(pc() == badAddress);
|
code()->share_trampoline_for(entry.target(), offset());
|
||||||
return NULL; // CodeCache is full
|
} else {
|
||||||
|
address stub = emit_trampoline_stub(offset(), target);
|
||||||
|
if (stub == NULL) {
|
||||||
|
postcond(pc() == badAddress);
|
||||||
|
return NULL; // CodeCache is full
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
target = pc();
|
||||||
}
|
}
|
||||||
|
|
||||||
address call_pc = pc();
|
address call_pc = pc();
|
||||||
@ -2828,11 +2836,7 @@ address MacroAssembler::trampoline_call(Address entry) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
relocate(entry.rspec());
|
relocate(entry.rspec());
|
||||||
if (!far_branches()) {
|
jal(target);
|
||||||
jal(entry.target());
|
|
||||||
} else {
|
|
||||||
jal(pc());
|
|
||||||
}
|
|
||||||
|
|
||||||
postcond(pc() != badAddress);
|
postcond(pc() != badAddress);
|
||||||
return call_pc;
|
return call_pc;
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
* @bug 8280152
|
* @bug 8280152
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
*
|
*
|
||||||
* @requires vm.debug & os.arch=="aarch64"
|
* @requires os.arch=="aarch64" | os.arch=="riscv64"
|
||||||
|
* @requires vm.debug
|
||||||
*
|
*
|
||||||
* @run driver compiler.sharedstubs.SharedTrampolineTest
|
* @run driver compiler.sharedstubs.SharedTrampolineTest
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user