Skip to content

Commit

Permalink
Use CP for addr
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Jun 27, 2024
1 parent 442680b commit d12caf2
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 86 deletions.
23 changes: 12 additions & 11 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4030,28 +4030,29 @@ address MacroAssembler::load_and_call(Address entry) {
entry.rspec().type() == relocInfo::static_call_type ||
entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");


address target = entry.target();
address addr_to_cp_entry = nullptr;

if (!in_scratch_emit_size()) {
address stub = emit_address_stub(offset(), target);
if (stub == nullptr) {
postcond(pc() == badAddress);
addr_to_cp_entry = address_constant(target);
if (addr_to_cp_entry == nullptr) {
return nullptr; // CodeCache is full
}
}

address call_pc = pc();
#ifdef ASSERT
if (entry.rspec().type() != relocInfo::runtime_call_type) {
assert_alignment(call_pc);
RelocationHolder rh = section_word_Relocation::spec(addr_to_cp_entry, CodeBuffer::SECT_CONSTS);
relocate(rh);
} else {
addr_to_cp_entry = pc();
}
#endif

address call_at = pc();
relocate(entry.rspec(), [&] {
load_link_jump(target);
load_link_jump(addr_to_cp_entry);
});

postcond(pc() != badAddress);
return call_pc;
return call_at;
}

address MacroAssembler::ic_call(address entry, jint method_index) {
Expand Down
110 changes: 38 additions & 72 deletions src/hotspot/cpu/riscv/nativeInst_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,48 +324,31 @@ class NativeFarCall: public NativeInstruction {
bool set_destination_mt_safe(address dest, bool assert_lock = true);
bool reloc_set_destination(address dest);

private:
address stub_address();

static void set_stub_address_destination_at(address dest, address value);
static address stub_address_destination_at(address src);
public:

static NativeFarCall* at(address addr);
static bool is_at(address addr);
static bool is_call_before(address return_address);
};

address NativeFarCall::destination() const {
address addr = instruction_address();
assert(NativeFarCall::is_at(addr), "unexpected code at call site");

address destination = MacroAssembler::target_addr_for_insn(addr);

CodeBlob* cb = CodeCache::find_blob(addr);
assert(cb && cb->is_nmethod(), "sanity");
nmethod *nm = (nmethod *)cb;
assert(nm != nullptr, "Sanity");
assert(nm->stub_contains(destination), "Sanity");
assert(destination != nullptr, "Sanity");
return stub_address_destination_at(destination);
address addr = addr_at(0);
address dest_addr = MacroAssembler::target_addr_for_insn(addr);
address dest = (address)get_data64_at(dest_addr);
return dest;
}

address NativeFarCall::reloc_destination(address orig_address) {
address call_addr = instruction_address();
address new_addr = instruction_address();

CodeBlob *code = CodeCache::find_blob(call_addr);
assert(code != nullptr, "Could not find the containing code blob");

address stub_addr = nullptr;
if (code != nullptr && code->is_nmethod()) {
stub_addr = trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code);
}

if (stub_addr != nullptr) {
stub_addr = MacroAssembler::target_addr_for_insn(call_addr);
if (orig_address != nullptr) {
assert(NativeFarCall::is_at(orig_address), "unexpected code at call site");
address old_cp_dest = MacroAssembler::target_addr_for_insn(orig_address);
address old_dest = (address)get_data64_at(old_cp_dest);
return old_dest;
} else {
address new_cp_dest = MacroAssembler::target_addr_for_insn(new_addr);
address new_dest = (address)get_data64_at(new_cp_dest);
return new_dest;
}
return stub_addr;
}

void NativeFarCall::set_destination(address dest) {
Expand All @@ -391,60 +374,43 @@ bool NativeFarCall::set_destination_mt_safe(address dest, bool assert_lock) {
"concurrent code patching");

address call_addr = addr_at(0);
assert(NativeFarCall::is_at(call_addr), "unexpected code at call site");
address cp_pool_addr = MacroAssembler::target_addr_for_insn(call_addr);

address stub_addr = stub_address();

if (stub_addr != nullptr) {
set_stub_address_destination_at(stub_addr, dest);
return true;
}

return false;
assert(cp_pool_addr != nullptr, "Must be");
set_data64_at(cp_pool_addr, (uint64_t)dest);
OrderAccess::release();
return true;
}

bool NativeFarCall::reloc_set_destination(address dest) {
address call_addr = addr_at(0);
assert(NativeFarCall::is_at(call_addr), "unexpected code at call site");

CodeBlob *code = CodeCache::find_blob(call_addr);
assert(code != nullptr, "Could not find the containing code blob");
CodeBlob* cb = CodeCache::find_blob(call_addr);
assert(cb != nullptr, "Could not find code blob");
nmethod* nm = cb->as_nmethod_or_null();

address stub_addr = nullptr;
if (code != nullptr && code->is_nmethod()) {
stub_addr = trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code);
address cp_entry_addr = nullptr;
if (nm != nullptr) {
RelocIterator iter(nm, instruction_address(), next_instruction_address());
while (iter.next()) {
if (iter.type() == relocInfo::section_word_type) {
cp_entry_addr = iter.section_word_reloc()->target();
break;
}
}
}

if (stub_addr != nullptr) {
MacroAssembler::pd_patch_instruction_size(call_addr, stub_addr);
if (cp_entry_addr != nullptr) {
MacroAssembler::pd_patch_instruction_size(call_addr, cp_entry_addr);
} else {
cp_entry_addr = MacroAssembler::target_addr_for_insn(call_addr);
}

return true;
}
assert(MacroAssembler::target_addr_for_insn(call_addr) == cp_entry_addr, "Must be");

void NativeFarCall::set_stub_address_destination_at(address dest, address value) {
assert_cond(dest != nullptr);
assert_cond(value != nullptr);
set_data64_at(cp_entry_addr, (uint64_t)dest);

set_data64_at(dest, (uint64_t)value);
OrderAccess::release();
}

address NativeFarCall::stub_address_destination_at(address src) {
assert_cond(src != nullptr);
address dest = (address)get_data64_at(src);
return dest;
}

address NativeFarCall::stub_address() {
address call_addr = addr_at(0);

CodeBlob *code = CodeCache::find_blob(call_addr);
assert(code != nullptr, "Could not find the containing code blob");

address dest = MacroAssembler::pd_call_destination(call_addr);
assert(code->contains(dest), "Sanity");
return dest;
return true;
}

NativeFarCall* NativeFarCall::at(address addr) {
Expand Down
12 changes: 11 additions & 1 deletion src/hotspot/share/code/compiledIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) {

CompiledIC* CompiledIC_at(nmethod* nm, address call_site) {
RelocIterator iter(nm, call_site, call_site + 1);
iter.next();
while (iter.next()) {
if (iter.reloc()->type() == relocInfo::virtual_call_type) {
break;
}
}
return CompiledIC_at(&iter);
}

Expand Down Expand Up @@ -333,7 +337,10 @@ void CompiledDirectCall::set_to_clean() {
case relocInfo::opt_virtual_call_type:
_call->set_destination_mt_safe(SharedRuntime::get_resolve_opt_virtual_call_stub());
break;
case relocInfo::section_word_type:
break;
default:
assert(false, "Type: %d", iter.type());
ShouldNotReachHere();
}
}
Expand Down Expand Up @@ -402,7 +409,10 @@ address CompiledDirectCall::find_stub_for(address instruction) {
// from the CompiledIC implementation
case relocInfo::opt_virtual_call_type:
return iter.opt_virtual_call_reloc()->static_stub();
case relocInfo::section_word_type:
break;
default:
assert(false, "Type: %d", iter.type());
ShouldNotReachHere();
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/share/runtime/sharedRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,12 @@ JRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address cal
// call address would be; let's peek at it
address callsite_addr = (address)nativeCall_before(return_pc);
RelocIterator iter(caller, callsite_addr, callsite_addr + 1);
while (iter.next()) {
if (iter.reloc()->type() == relocInfo::static_call_type ||
iter.reloc()->type() == relocInfo::opt_virtual_call_type) {
break;
}
}
if (!iter.next()) {
// No reloc entry found; not a static or optimized virtual call
return;
Expand Down Expand Up @@ -2748,14 +2754,14 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
struct { double data[20]; } locs_buf;
struct { double data[20]; } stubs_locs_buf;
buffer.insts()->initialize_shared_locs((relocInfo*)&locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
#if defined(AARCH64) || defined(PPC64)
#if defined(AARCH64) || defined(PPC64) || defined(RISCV)
// On AArch64 with ZGC and nmethod entry barriers, we need all oops to be
// in the constant pool to ensure ordering between the barrier and oops
// accesses. For native_wrappers we need a constant.
// On PPC64 the continuation enter intrinsic needs the constant pool for the compiled
// static java call that is resolved in the runtime.
if (PPC64_ONLY(method->is_continuation_enter_intrinsic() &&) true) {
buffer.initialize_consts_size(8 PPC64_ONLY(+ 24));
buffer.initialize_consts_size(8 PPC64_ONLY(+ 24) RISCV_ONLY(+ 8));
}
#endif
buffer.stubs()->initialize_shared_locs((relocInfo*)&stubs_locs_buf, sizeof(stubs_locs_buf) / sizeof(relocInfo));
Expand Down

0 comments on commit d12caf2

Please sign in to comment.