8276314: [JVMCI] check alignment of call displacement during code installation

Reviewed-by: kvn
This commit is contained in:
Doug Simon 2021-11-18 08:32:54 +00:00
parent 91607436b7
commit 2f4b5405f0
3 changed files with 17 additions and 11 deletions

View File

@ -155,14 +155,15 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
method = JVMCIENV->asMethod(hotspot_method);
}
#endif
NativeCall* call = NULL;
switch (_next_call_type) {
case INLINE_INVOKE:
break;
return;
case INVOKEVIRTUAL:
case INVOKEINTERFACE: {
assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
call = nativeCall_at(_instructions->start() + pc_offset);
call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
_instructions->relocate(call->instruction_address(),
virtual_call_Relocation::spec(_invoke_mark_pc),
@ -172,7 +173,7 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
case INVOKESTATIC: {
assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
call = nativeCall_at(_instructions->start() + pc_offset);
call->set_destination(SharedRuntime::get_resolve_static_call_stub());
_instructions->relocate(call->instruction_address(),
relocInfo::static_call_type, Assembler::call32_operand);
@ -180,15 +181,18 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
}
case INVOKESPECIAL: {
assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
call = nativeCall_at(_instructions->start() + pc_offset);
call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
_instructions->relocate(call->instruction_address(),
relocInfo::opt_virtual_call_type, Assembler::call32_operand);
break;
}
default:
JVMCI_ERROR("invalid _next_call_type value");
break;
JVMCI_ERROR("invalid _next_call_type value: %d", _next_call_type);
return;
}
if (!call->is_displacement_aligned()) {
JVMCI_ERROR("unaligned displacement for call at offset %d", pc_offset);
}
}

View File

@ -260,6 +260,9 @@ void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
}
bool NativeCall::is_displacement_aligned() {
return (uintptr_t) displacement_address() % 4 == 0;
}
// Similar to replace_mt_safe, but just changes the destination. The
// important thing is that free-running threads are able to execute this
@ -282,8 +285,7 @@ void NativeCall::set_destination_mt_safe(address dest) {
CompiledICLocker::is_safe(instruction_address()), "concurrent code patching");
// Both C1 and C2 should now be generating code which aligns the patched address
// to be within a single cache line.
bool is_aligned = ((uintptr_t)displacement_address() + 0) / cache_line_size ==
((uintptr_t)displacement_address() + 3) / cache_line_size;
bool is_aligned = is_displacement_aligned();
guarantee(is_aligned, "destination must be aligned");

View File

@ -160,8 +160,6 @@ class NativeCall: public NativeInstruction {
return_address_offset = 5
};
enum { cache_line_size = BytesPerWord }; // conservative estimate!
address instruction_address() const { return addr_at(instruction_offset); }
address next_instruction_address() const { return addr_at(return_address_offset); }
int displacement() const { return (jint) int_at(displacement_offset); }
@ -175,9 +173,11 @@ class NativeCall: public NativeInstruction {
#endif // AMD64
set_int_at(displacement_offset, dest - return_address());
}
// Returns whether the 4-byte displacement operand is 4-byte aligned.
bool is_displacement_aligned();
void set_destination_mt_safe(address dest);
void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); }
void verify_alignment() { assert(is_displacement_aligned(), "displacement of call is not aligned"); }
void verify();
void print();