Skip to content

Commit 81cd594

Browse files
author
Vladimir Kozlov
committed
8276314: [JVMCI] check alignment of call displacement during code installation
Backport-of: 2f4b5405f0b53782f3ed5274f68b31eb968efb6d
1 parent 9d0bfe1 commit 81cd594

File tree

3 files changed

+17
-11
lines changed

3 files changed

+17
-11
lines changed

src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,15 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
155155
method = JVMCIENV->asMethod(hotspot_method);
156156
}
157157
#endif
158+
NativeCall* call = NULL;
158159
switch (_next_call_type) {
159160
case INLINE_INVOKE:
160-
break;
161+
return;
161162
case INVOKEVIRTUAL:
162163
case INVOKEINTERFACE: {
163164
assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
164165

165-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
166+
call = nativeCall_at(_instructions->start() + pc_offset);
166167
call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
167168
_instructions->relocate(call->instruction_address(),
168169
virtual_call_Relocation::spec(_invoke_mark_pc),
@@ -172,23 +173,26 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
172173
case INVOKESTATIC: {
173174
assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
174175

175-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
176+
call = nativeCall_at(_instructions->start() + pc_offset);
176177
call->set_destination(SharedRuntime::get_resolve_static_call_stub());
177178
_instructions->relocate(call->instruction_address(),
178179
relocInfo::static_call_type, Assembler::call32_operand);
179180
break;
180181
}
181182
case INVOKESPECIAL: {
182183
assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
183-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
184+
call = nativeCall_at(_instructions->start() + pc_offset);
184185
call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
185186
_instructions->relocate(call->instruction_address(),
186187
relocInfo::opt_virtual_call_type, Assembler::call32_operand);
187188
break;
188189
}
189190
default:
190-
JVMCI_ERROR("invalid _next_call_type value");
191-
break;
191+
JVMCI_ERROR("invalid _next_call_type value: %d", _next_call_type);
192+
return;
193+
}
194+
if (!call->is_displacement_aligned()) {
195+
JVMCI_ERROR("unaligned displacement for call at offset %d", pc_offset);
192196
}
193197
}
194198

src/hotspot/cpu/x86/nativeInst_x86.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
260260

261261
}
262262

263+
bool NativeCall::is_displacement_aligned() {
264+
return (uintptr_t) displacement_address() % 4 == 0;
265+
}
263266

264267
// Similar to replace_mt_safe, but just changes the destination. The
265268
// important thing is that free-running threads are able to execute this
@@ -282,8 +285,7 @@ void NativeCall::set_destination_mt_safe(address dest) {
282285
CompiledICLocker::is_safe(instruction_address()), "concurrent code patching");
283286
// Both C1 and C2 should now be generating code which aligns the patched address
284287
// to be within a single cache line.
285-
bool is_aligned = ((uintptr_t)displacement_address() + 0) / cache_line_size ==
286-
((uintptr_t)displacement_address() + 3) / cache_line_size;
288+
bool is_aligned = is_displacement_aligned();
287289

288290
guarantee(is_aligned, "destination must be aligned");
289291

src/hotspot/cpu/x86/nativeInst_x86.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ class NativeCall: public NativeInstruction {
160160
return_address_offset = 5
161161
};
162162

163-
enum { cache_line_size = BytesPerWord }; // conservative estimate!
164-
165163
address instruction_address() const { return addr_at(instruction_offset); }
166164
address next_instruction_address() const { return addr_at(return_address_offset); }
167165
int displacement() const { return (jint) int_at(displacement_offset); }
@@ -175,9 +173,11 @@ class NativeCall: public NativeInstruction {
175173
#endif // AMD64
176174
set_int_at(displacement_offset, dest - return_address());
177175
}
176+
// Returns whether the 4-byte displacement operand is 4-byte aligned.
177+
bool is_displacement_aligned();
178178
void set_destination_mt_safe(address dest);
179179

180-
void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); }
180+
void verify_alignment() { assert(is_displacement_aligned(), "displacement of call is not aligned"); }
181181
void verify();
182182
void print();
183183

0 commit comments

Comments
 (0)