7147740: add assertions to check stack alignment on VM entry from generated code (x64)
Summary: check stack alignment on VM entry on x64.
Reviewed-by: kvn, never
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -710,6 +710,21 @@
return start;
}
+ // Support for intptr_t get_previous_sp()
+ //
+ // This routine is used to find the previous stack pointer for the
+ // caller.
+ address generate_get_previous_sp() {
+ StubCodeMark mark(this, "StubRoutines", "get_previous_sp");
+ address start = __ pc();
+
+ __ movptr(rax, rsp);
+ __ addptr(rax, 8); // return address is at the top of the stack.
+ __ ret(0);
+
+ return start;
+ }
+
//----------------------------------------------------------------------------------------------------
// Support for void verify_mxcsr()
//
@@ -3060,6 +3075,7 @@
// platform dependent
StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
+ StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -43,6 +43,7 @@
// a description of how to extend it, see the stubRoutines.hpp file.
address StubRoutines::x86::_get_previous_fp_entry = NULL;
+address StubRoutines::x86::_get_previous_sp_entry = NULL;
address StubRoutines::x86::_verify_mxcsr_entry = NULL;
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Mon Feb 27 09:17:44 2012 +0100
@@ -41,6 +41,7 @@
private:
static address _get_previous_fp_entry;
+ static address _get_previous_sp_entry;
static address _verify_mxcsr_entry;
static address _f2i_fixup;
@@ -61,6 +62,11 @@
return _get_previous_fp_entry;
}
+ static address get_previous_sp_entry()
+ {
+ return _get_previous_sp_entry;
+ }
+
static address verify_mxcsr_entry()
{
return _verify_mxcsr_entry;
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -1013,15 +1013,6 @@
// use debugger to set breakpoint here
}
-// Returns an estimate of the current stack pointer. Result must be guaranteed to
-// point into the calling threads stack, and be no lower than the current stack
-// pointer.
-address os::current_stack_pointer() {
- volatile int dummy;
- address sp = (address)&dummy + 8; // %%%% need to confirm if this is right
- return sp;
-}
-
static thread_t main_thread;
// Thread start routine for all new Java threads
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -324,16 +324,6 @@
os::breakpoint();
}
-// Returns an estimate of the current stack pointer. Result must be guaranteed
-// to point into the calling threads stack, and be no lower than the current
-// stack pointer.
-
-address os::current_stack_pointer() {
- int dummy;
- address sp = (address)&dummy;
- return sp;
-}
-
// os::current_stack_base()
//
// Returns the base of the stack, which is the stack's
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -1126,3 +1126,8 @@
: "r" (fpu_cntrl) : "memory");
#endif // !AMD64
}
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -562,3 +562,8 @@
}
};
#endif // !_LP64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -756,3 +756,8 @@
// guard page, only enable glibc guard page for non-Java threads.
return (thr_type == java_thread ? 0 : page_size());
}
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -862,3 +862,11 @@
: "r" (fpu_cntrl) : "memory");
#endif // !AMD64
}
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -506,3 +506,8 @@
}
};
#endif // !_LP64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -251,6 +251,15 @@
return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
}
+// Returns an estimate of the current stack pointer. Result must be guaranteed to
+// point into the calling threads stack, and be no lower than the current stack
+// pointer.
+address os::current_stack_pointer() {
+ volatile int dummy;
+ address sp = (address)&dummy + 8; // %%%% need to confirm if this is right
+ return sp;
+}
+
frame os::current_frame() {
intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
frame myframe(sp, frame::unpatchable,
@@ -815,3 +824,8 @@
__asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :);
}
#endif //defined(__sparc) && defined(COMPILER2)
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -237,6 +237,12 @@
return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
}
+extern "C" intptr_t *_get_current_sp(); // in .il file
+
+address os::current_stack_pointer() {
+ return (address)_get_current_sp();
+}
+
extern "C" intptr_t *_get_current_fp(); // in .il file
frame os::current_frame() {
@@ -954,3 +960,11 @@
_solaris_raw_setup_fpu(fpu_cntrl);
}
#endif // AMD64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Mon Feb 27 09:17:44 2012 +0100
@@ -37,6 +37,12 @@
movl %gs:0, %eax
.end
+ // Get current sp
+ .inline _get_current_sp,0
+ .volatile
+ movl %esp, %eax
+ .end
+
// Get current fp
.inline _get_current_fp,0
.volatile
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Mon Feb 27 09:17:44 2012 +0100
@@ -30,6 +30,12 @@
movq %fs:0, %rax
.end
+ // Get current sp
+ .inline _get_current_sp,0
+ .volatile
+ movq %rsp, %rax
+ .end
+
// Get current fp
.inline _get_current_fp,0
.volatile
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Mon Feb 27 09:17:44 2012 +0100
@@ -370,6 +370,26 @@
return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
}
+#ifndef AMD64
+// Returns an estimate of the current stack pointer. Result must be guaranteed
+// to point into the calling threads stack, and be no lower than the current
+// stack pointer.
+address os::current_stack_pointer() {
+ int dummy;
+ address sp = (address)&dummy;
+ return sp;
+}
+#else
+// Returns the current stack pointer. Accurate value needed for
+// os::verify_stack_alignment().
+address os::current_stack_pointer() {
+ typedef address get_sp_func();
+ get_sp_func* func = CAST_TO_FN_PTR(get_sp_func*,
+ StubRoutines::x86::get_previous_sp_entry());
+ return (*func)();
+}
+#endif
+
#ifndef AMD64
intptr_t* _get_previous_fp() {
@@ -546,3 +566,11 @@
__asm fldcw fpu_cntrl_word;
#endif // !AMD64
}
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Mon Feb 27 09:17:44 2012 +0100
@@ -436,6 +436,7 @@
#define VM_LEAF_BASE(result_type, header) \
TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \
+ os::verify_stack_alignment(); \
/* begin of body */
@@ -445,6 +446,7 @@
TRACE_CALL(result_type, header) \
HandleMarkCleaner __hm(thread); \
Thread* THREAD = thread; \
+ os::verify_stack_alignment(); \
/* begin of body */
@@ -454,6 +456,7 @@
TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \
Thread* THREAD = thread; \
+ os::verify_stack_alignment(); \
/* begin of body */
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Feb 24 12:33:31 2012 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp Mon Feb 27 09:17:44 2012 +0100
@@ -404,6 +404,8 @@
static address current_stack_base();
static size_t current_stack_size();
+ static void verify_stack_alignment() PRODUCT_RETURN;
+
static int message_box(const char* title, const char* message);
static char* do_you_want_to_debug(const char* message);