8276314: [JVMCI] check alignment of call displacement during code installation
Reviewed-by: kvn
This commit is contained in:
parent
91607436b7
commit
2f4b5405f0
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user