7147740: add assertions to check stack alignment on VM entry from generated code (x64)
authorroland
Mon, 27 Feb 2012 09:17:44 +0100
changeset 11961 0abd4cd26e5a
parent 11960 57898a1b4b44
child 11962 42ae1f21ed2b
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
hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
hotspot/src/os/solaris/vm/os_solaris.cpp
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
hotspot/src/share/vm/runtime/interfaceSupport.hpp
hotspot/src/share/vm/runtime/os.hpp
--- 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);