aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroland <none@none>2012-02-27 11:42:30 +0100
committerroland <none@none>2012-02-27 11:42:30 +0100
commitd0885aac2590a72cc3031bc703706f0cf52b0362 (patch)
tree10c4d02370f5f2f3136b062a71d966456603c34a
parentc69e69033671193977e501108e9ec507e0fa6943 (diff)
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
-rw-r--r--src/cpu/x86/vm/c1_Runtime1_x86.cpp22
-rw-r--r--src/cpu/x86/vm/sharedRuntime_x86_64.cpp10
2 files changed, 26 insertions, 6 deletions
diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp
index 5f2cf3886..30df6087d 100644
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp
@@ -47,6 +47,12 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
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 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
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 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
}
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));
diff --git a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
index b7af4544d..6c2a56545 100644
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
@@ -3620,8 +3620,12 @@ void OptoRuntime::generate_exception_blob() {
//
// 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 @@ void OptoRuntime::generate_exception_blob() {
OopMapSet* oop_maps = new OopMapSet();
- oop_maps->add_gc_map( __ pc()-start, new OopMap(SimpleRuntimeFrame::framesize, 0));
+ oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
- __ reset_last_Java_frame(false, false);
+ __ reset_last_Java_frame(false, true);
// Restore callee-saved registers