Skip to content

8362515: RISC-V: cleanup NativeFarCall #26370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 24 additions & 121 deletions src/hotspot/cpu/riscv/nativeInst_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,44 +46,11 @@ bool NativeInstruction::is_call_at(address addr) {
}

//-----------------------------------------------------------------------------
// NativeFarCall
//
// Implements direct far calling loading an address from the stub section version of reloc call.

class NativeFarCall: public NativeInstruction {
public:
enum RISCV_specific_constants {
return_address_offset = 3 * NativeInstruction::instruction_size, // auipc + ld + jalr
};

address instruction_address() const { return addr_at(0); }
address next_instruction_address() const { return addr_at(return_address_offset); }
address return_address() const { return addr_at(return_address_offset); }
address destination() const;
address reloc_destination();

void set_destination(address dest);
void verify();
void print();

bool set_destination_mt_safe(address dest);
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);
};
// NativeCall

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

address destination = MacroAssembler::target_addr_for_insn(addr);

Expand All @@ -96,9 +63,9 @@ address NativeFarCall::destination() const {
return stub_address_destination_at(destination);
}

address NativeFarCall::reloc_destination() {
address NativeCall::reloc_destination() {
address call_addr = instruction_address();
assert(NativeFarCall::is_at(call_addr), "unexpected code at call site");
assert(NativeCall::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");
Expand All @@ -115,25 +82,19 @@ address NativeFarCall::reloc_destination() {
return stub_addr;
}

void NativeFarCall::set_destination(address dest) {
address addr = instruction_address();
assert(NativeFarCall::is_at(addr), "unexpected code at call site");
Unimplemented();
}

void NativeFarCall::verify() {
assert(NativeFarCall::is_at(instruction_address()), "unexpected code at call site");
void NativeCall::verify() {
assert(NativeCall::is_at(instruction_address()), "unexpected code at call site");
}

void NativeFarCall::print() {
assert(NativeFarCall::is_at(instruction_address()), "unexpected code at call site");
tty->print_cr(PTR_FORMAT ": auipc,ld,jalr x1, offset/reg, ", p2i(addr_at(0)));
void NativeCall::print() {
assert(NativeCall::is_at(instruction_address()), "unexpected code at call site");
tty->print_cr(PTR_FORMAT ": auipc,ld,jalr x1, offset/reg, ", p2i(instruction_address()));
}

bool NativeFarCall::set_destination_mt_safe(address dest) {
assert(NativeFarCall::is_at(addr_at(0)), "unexpected code at call site");
bool NativeCall::set_destination_mt_safe(address dest) {
assert(NativeCall::is_at(instruction_address()), "unexpected code at call site");
assert((CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
CompiledICLocker::is_safe(addr_at(0)),
CompiledICLocker::is_safe(instruction_address()),
"concurrent code patching");

address stub_addr = stub_address();
Expand All @@ -145,9 +106,9 @@ bool NativeFarCall::set_destination_mt_safe(address dest) {
return false;
}

bool NativeFarCall::reloc_set_destination(address dest) {
address call_addr = addr_at(0);
assert(NativeFarCall::is_at(call_addr), "unexpected code at call site");
bool NativeCall::reloc_set_destination(address dest) {
address call_addr = instruction_address();
assert(NativeCall::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");
Expand All @@ -163,39 +124,32 @@ bool NativeFarCall::reloc_set_destination(address dest) {
return true;
}

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

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

address NativeFarCall::stub_address_destination_at(address src) {
address NativeCall::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);
address NativeCall::stub_address() {
address call_addr = instruction_address();

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);
address dest = MacroAssembler::target_addr_for_insn(call_addr);
assert(code->contains(dest), "Sanity");
return dest;
}

NativeFarCall* NativeFarCall::at(address addr) {
assert_cond(addr != nullptr);
assert(NativeFarCall::is_at(addr), "unexpected code at call site: %p", addr);
NativeFarCall* call = (NativeFarCall*)(addr);
return call;
}

bool NativeFarCall::is_at(address addr) {
bool NativeCall::is_at(address addr) {
assert_cond(addr != nullptr);
const int instr_size = NativeInstruction::instruction_size;
if (MacroAssembler::is_auipc_at(addr) &&
Expand All @@ -211,59 +165,8 @@ bool NativeFarCall::is_at(address addr) {
return false;
}

bool NativeFarCall::is_call_before(address return_address) {
return NativeFarCall::is_at(return_address - return_address_offset);
}

//-----------------------------------------------------------------------------
// NativeCall

address NativeCall::instruction_address() const {
return NativeFarCall::at(addr_at(0))->instruction_address();
}

address NativeCall::next_instruction_address() const {
return NativeFarCall::at(addr_at(0))->next_instruction_address();
}

address NativeCall::return_address() const {
return NativeFarCall::at(addr_at(0))->return_address();
}

address NativeCall::destination() const {
return NativeFarCall::at(addr_at(0))->destination();
}

address NativeCall::reloc_destination() {
return NativeFarCall::at(addr_at(0))->reloc_destination();
}

void NativeCall::set_destination(address dest) {
NativeFarCall::at(addr_at(0))->set_destination(dest);
}

void NativeCall::verify() {
NativeFarCall::at(addr_at(0))->verify();;
}

void NativeCall::print() {
NativeFarCall::at(addr_at(0))->print();;
}

bool NativeCall::set_destination_mt_safe(address dest) {
return NativeFarCall::at(addr_at(0))->set_destination_mt_safe(dest);
}

bool NativeCall::reloc_set_destination(address dest) {
return NativeFarCall::at(addr_at(0))->reloc_set_destination(dest);
}

bool NativeCall::is_at(address addr) {
return NativeFarCall::is_at(addr);
}

bool NativeCall::is_call_before(address return_address) {
return NativeFarCall::is_call_before(return_address);
return NativeCall::is_at(return_address - NativeCall::instruction_size);
}

NativeCall* nativeCall_at(address addr) {
Expand All @@ -276,7 +179,7 @@ NativeCall* nativeCall_at(address addr) {
NativeCall* nativeCall_before(address return_address) {
assert_cond(return_address != nullptr);
NativeCall* call = nullptr;
call = (NativeCall*)(return_address - NativeFarCall::return_address_offset);
call = (NativeCall*)(return_address - NativeCall::instruction_size);
DEBUG_ONLY(call->verify());
return call;
}
Expand Down
23 changes: 17 additions & 6 deletions src/hotspot/cpu/riscv/nativeInst_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,41 +111,52 @@ NativeCall* nativeCall_before(address return_address);
// The NativeCall is an abstraction for accessing/manipulating native
// call instructions (used to manipulate inline caches, primitive &
// DSO calls, etc.).
// NativeCall is reloc call on RISC-V. See MacroAssembler::reloc_call.
class NativeCall: private NativeInstruction {
// private: when common code is using byte_size()
private:
enum {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the enum of NativeFarCall was named as RISCV_specific_constants, do we need this for NativeCall?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you having a look.

Seems not, there is no name for this enum in orignal code . And in this file some enums have names, some not, but seems either way is fine, although I think the names are all redundant here.

// Use byte_size() as it can be changed in runtime
// Since instruction_size exists on NativeInstruction we need
// to overload and hide it.
instruction_size = 3 * Assembler::instruction_size // auipc + ld + jalr
instruction_size = 3 * NativeInstruction::instruction_size // auipc + ld + jalr
};
public:

static int byte_size() {
return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
return NativeCall::instruction_size; // auipc + ld + jalr
}

// Creation
friend NativeCall* nativeCall_at(address addr);
friend NativeCall* nativeCall_before(address return_address);

address instruction_address() const;
address next_instruction_address() const;
address return_address() const;
address instruction_address() const { return addr_at(0); }
address next_instruction_address() const { return addr_at(NativeCall::instruction_size); }
address return_address() const { return addr_at(NativeCall::instruction_size); }
address destination() const;
address reloc_destination();

void verify_alignment() {} // do nothing on riscv
void verify();
void print();

void set_destination(address dest);
void set_destination(address dest) { Unimplemented(); }
// patch stub to target address of the reloc call
bool set_destination_mt_safe(address dest);
// patch reloc call to stub address
bool reloc_set_destination(address dest);

static bool is_at(address addr);
static bool is_call_before(address return_address);

private:
// return stub address, without checking stub address in locs
address stub_address();
// set target address at stub
static void set_stub_address_destination_at(address dest, address value);
// return target address at stub
static address stub_address_destination_at(address src);
};

// An interface for accessing/manipulating native mov reg, imm instructions.
Expand Down