7148486: At a method handle call returning with an exception may call the runtime with misaligned stack (x64)
Summary: stack must be realigned when calling the runtime for exception propagation at a call.
Reviewed-by: kvn, never
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Feb 27 09:17:44 2012 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Feb 27 11:42:30 2012 +0100
@@ -47,6 +47,12 @@
assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different");
assert(oop_result1 != thread && oop_result2 != thread, "registers must be different");
assert(args_size >= 0, "illegal args_size");
+ bool align_stack = false;
+#ifdef _LP64
+ // At a method handle call, the stack may not be properly aligned
+ // when returning with an exception.
+ align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
+#endif
#ifdef _LP64
mov(c_rarg0, thread);
@@ -59,11 +65,21 @@
push(thread);
#endif // _LP64
- set_last_Java_frame(thread, noreg, rbp, NULL);
+ int call_offset;
+ if (!align_stack) {
+ set_last_Java_frame(thread, noreg, rbp, NULL);
+ } else {
+ address the_pc = pc();
+ call_offset = offset();
+ set_last_Java_frame(thread, noreg, rbp, the_pc);
+ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
+ }
// do the call
call(RuntimeAddress(entry));
- int call_offset = offset();
+ if (!align_stack) {
+ call_offset = offset();
+ }
// verify callee-saved register
#ifdef ASSERT
guarantee(thread != rax, "change this code");
@@ -78,7 +94,7 @@
}
pop(rax);
#endif
- reset_last_Java_frame(thread, true, false);
+ reset_last_Java_frame(thread, true, align_stack);
// discard thread and arguments
NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Feb 27 09:17:44 2012 +0100
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Feb 27 11:42:30 2012 +0100
@@ -3620,8 +3620,12 @@
//
// address OptoRuntime::handle_exception_C(JavaThread* thread)
- __ set_last_Java_frame(noreg, noreg, NULL);
+ // At a method handle call, the stack may not be properly aligned
+ // when returning with an exception.
+ address the_pc = __ pc();
+ __ set_last_Java_frame(noreg, noreg, the_pc);
__ mov(c_rarg0, r15_thread);
+ __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)));
// Set an oopmap for the call site. This oopmap will only be used if we
@@ -3632,9 +3636,9 @@
OopMapSet* oop_maps = new OopMapSet();
- oop_maps->add_gc_map( __ pc()-start, new OopMap(SimpleRuntimeFrame::framesize, 0));
-
- __ reset_last_Java_frame(false, false);
+ oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
+
+ __ reset_last_Java_frame(false, true);
// Restore callee-saved registers