Skip to content

Commit 8989823

Browse files
author
Vladimir Kozlov
committed
8276314: [JVMCI] check alignment of call displacement during code installation
Reviewed-by: dnsimon, goetz Backport-of: 2f4b5405f0b53782f3ed5274f68b31eb968efb6d
1 parent fdf21b6 commit 8989823

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,15 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method,
153153
method = getMethodFromHotSpotMethod(hotspot_method());
154154
}
155155
#endif
156+
NativeCall* call = NULL;
156157
switch (_next_call_type) {
157158
case INLINE_INVOKE:
158-
break;
159+
return;
159160
case INVOKEVIRTUAL:
160161
case INVOKEINTERFACE: {
161162
assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
162163

163-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
164+
call = nativeCall_at(_instructions->start() + pc_offset);
164165
call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
165166
_instructions->relocate(call->instruction_address(),
166167
virtual_call_Relocation::spec(_invoke_mark_pc),
@@ -170,23 +171,26 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method,
170171
case INVOKESTATIC: {
171172
assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
172173

173-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
174+
call = nativeCall_at(_instructions->start() + pc_offset);
174175
call->set_destination(SharedRuntime::get_resolve_static_call_stub());
175176
_instructions->relocate(call->instruction_address(),
176177
relocInfo::static_call_type, Assembler::call32_operand);
177178
break;
178179
}
179180
case INVOKESPECIAL: {
180181
assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
181-
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
182+
call = nativeCall_at(_instructions->start() + pc_offset);
182183
call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
183184
_instructions->relocate(call->instruction_address(),
184185
relocInfo::opt_virtual_call_type, Assembler::call32_operand);
185186
break;
186187
}
187188
default:
188-
JVMCI_ERROR("invalid _next_call_type value");
189-
break;
189+
JVMCI_ERROR("invalid _next_call_type value: %d", _next_call_type);
190+
return;
191+
}
192+
if (!call->is_displacement_aligned()) {
193+
JVMCI_ERROR("unaligned displacement for call at offset %d", pc_offset);
190194
}
191195
}
192196

src/hotspot/cpu/x86/nativeInst_x86.cpp

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

242242
}
243243

244+
bool NativeCall::is_displacement_aligned() {
245+
return (uintptr_t) displacement_address() % 4 == 0;
246+
}
244247

245248
// Similar to replace_mt_safe, but just changes the destination. The
246249
// important thing is that free-running threads are able to execute this
@@ -264,16 +267,15 @@ void NativeCall::set_destination_mt_safe(address dest) {
264267
// Both C1 and C2 should now be generating code which aligns the patched address
265268
// to be within a single cache line except that C1 does not do the alignment on
266269
// uniprocessor systems.
267-
bool is_aligned = ((uintptr_t)displacement_address() + 0) / cache_line_size ==
268-
((uintptr_t)displacement_address() + 3) / cache_line_size;
270+
bool is_aligned = is_displacement_aligned();
269271

270272
guarantee(!os::is_MP() || is_aligned, "destination must be aligned");
271273

272274
if (is_aligned) {
273275
// Simple case: The destination lies within a single cache line.
274276
set_destination(dest);
275-
} else if ((uintptr_t)instruction_address() / cache_line_size ==
276-
((uintptr_t)instruction_address()+1) / cache_line_size) {
277+
} else if ((uintptr_t)instruction_address() / 4 ==
278+
((uintptr_t)instruction_address()+1) / 4) {
277279
// Tricky case: The instruction prefix lies within a single cache line.
278280
intptr_t disp = dest - return_address();
279281
#ifdef AMD64

src/hotspot/cpu/x86/nativeInst_x86.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ class NativeCall: public NativeInstruction {
163163
return_address_offset = 5
164164
};
165165

166-
enum { cache_line_size = BytesPerWord }; // conservative estimate!
167-
168166
address instruction_address() const { return addr_at(instruction_offset); }
169167
address next_instruction_address() const { return addr_at(return_address_offset); }
170168
int displacement() const { return (jint) int_at(displacement_offset); }
@@ -178,9 +176,11 @@ class NativeCall: public NativeInstruction {
178176
#endif // AMD64
179177
set_int_at(displacement_offset, dest - return_address());
180178
}
179+
// Returns whether the 4-byte displacement operand is 4-byte aligned.
180+
bool is_displacement_aligned();
181181
void set_destination_mt_safe(address dest);
182182

183-
void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); }
183+
void verify_alignment() { assert(is_displacement_aligned(), "displacement of call is not aligned"); }
184184
void verify();
185185
void print();
186186

0 commit comments

Comments
 (0)