提交 e8dc2c2a 编写于 作者: R roland

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
上级 55d3fd6e
...@@ -710,6 +710,21 @@ class StubGenerator: public StubCodeGenerator { ...@@ -710,6 +710,21 @@ class StubGenerator: public StubCodeGenerator {
return start; 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() // Support for void verify_mxcsr()
// //
...@@ -3060,6 +3075,7 @@ class StubGenerator: public StubCodeGenerator { ...@@ -3060,6 +3075,7 @@ class StubGenerator: public StubCodeGenerator {
// platform dependent // platform dependent
StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); 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(); StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
// a description of how to extend it, see the stubRoutines.hpp file. // 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_fp_entry = NULL;
address StubRoutines::x86::_get_previous_sp_entry = NULL;
address StubRoutines::x86::_verify_mxcsr_entry = NULL; address StubRoutines::x86::_verify_mxcsr_entry = NULL;
......
...@@ -41,6 +41,7 @@ class x86 { ...@@ -41,6 +41,7 @@ class x86 {
private: private:
static address _get_previous_fp_entry; static address _get_previous_fp_entry;
static address _get_previous_sp_entry;
static address _verify_mxcsr_entry; static address _verify_mxcsr_entry;
static address _f2i_fixup; static address _f2i_fixup;
...@@ -61,6 +62,11 @@ class x86 { ...@@ -61,6 +62,11 @@ class x86 {
return _get_previous_fp_entry; return _get_previous_fp_entry;
} }
static address get_previous_sp_entry()
{
return _get_previous_sp_entry;
}
static address verify_mxcsr_entry() static address verify_mxcsr_entry()
{ {
return _verify_mxcsr_entry; return _verify_mxcsr_entry;
......
...@@ -1013,15 +1013,6 @@ extern "C" void breakpoint() { ...@@ -1013,15 +1013,6 @@ extern "C" void breakpoint() {
// use debugger to set breakpoint here // 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; static thread_t main_thread;
// Thread start routine for all new Java threads // Thread start routine for all new Java threads
......
...@@ -324,16 +324,6 @@ extern "C" void breakpoint() { ...@@ -324,16 +324,6 @@ extern "C" void breakpoint() {
os::breakpoint(); 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() // os::current_stack_base()
// //
// Returns the base of the stack, which is the stack's // Returns the base of the stack, which is the stack's
......
...@@ -1126,3 +1126,8 @@ void os::setup_fpu() { ...@@ -1126,3 +1126,8 @@ void os::setup_fpu() {
: "r" (fpu_cntrl) : "memory"); : "r" (fpu_cntrl) : "memory");
#endif // !AMD64 #endif // !AMD64
} }
#ifndef PRODUCT
void os::verify_stack_alignment() {
}
#endif
...@@ -562,3 +562,8 @@ extern "C" { ...@@ -562,3 +562,8 @@ extern "C" {
} }
}; };
#endif // !_LP64 #endif // !_LP64
#ifndef PRODUCT
void os::verify_stack_alignment() {
}
#endif
...@@ -756,3 +756,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) { ...@@ -756,3 +756,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
// guard page, only enable glibc guard page for non-Java threads. // guard page, only enable glibc guard page for non-Java threads.
return (thr_type == java_thread ? 0 : page_size()); return (thr_type == java_thread ? 0 : page_size());
} }
#ifndef PRODUCT
void os::verify_stack_alignment() {
}
#endif
...@@ -862,3 +862,11 @@ void os::setup_fpu() { ...@@ -862,3 +862,11 @@ void os::setup_fpu() {
: "r" (fpu_cntrl) : "memory"); : "r" (fpu_cntrl) : "memory");
#endif // !AMD64 #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
...@@ -506,3 +506,8 @@ extern "C" { ...@@ -506,3 +506,8 @@ extern "C" {
} }
}; };
#endif // !_LP64 #endif // !_LP64
#ifndef PRODUCT
void os::verify_stack_alignment() {
}
#endif
...@@ -251,6 +251,15 @@ frame os::get_sender_for_C_frame(frame* fr) { ...@@ -251,6 +251,15 @@ frame os::get_sender_for_C_frame(frame* fr) {
return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); 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() { frame os::current_frame() {
intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
frame myframe(sp, frame::unpatchable, frame myframe(sp, frame::unpatchable,
...@@ -815,3 +824,8 @@ add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; ...@@ -815,3 +824,8 @@ add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
__asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :); __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :);
} }
#endif //defined(__sparc) && defined(COMPILER2) #endif //defined(__sparc) && defined(COMPILER2)
#ifndef PRODUCT
void os::verify_stack_alignment() {
}
#endif
...@@ -237,6 +237,12 @@ frame os::get_sender_for_C_frame(frame* fr) { ...@@ -237,6 +237,12 @@ frame os::get_sender_for_C_frame(frame* fr) {
return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); 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 extern "C" intptr_t *_get_current_fp(); // in .il file
frame os::current_frame() { frame os::current_frame() {
...@@ -954,3 +960,11 @@ void os::setup_fpu() { ...@@ -954,3 +960,11 @@ void os::setup_fpu() {
_solaris_raw_setup_fpu(fpu_cntrl); _solaris_raw_setup_fpu(fpu_cntrl);
} }
#endif // AMD64 #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
...@@ -37,6 +37,12 @@ ...@@ -37,6 +37,12 @@
movl %gs:0, %eax movl %gs:0, %eax
.end .end
// Get current sp
.inline _get_current_sp,0
.volatile
movl %esp, %eax
.end
// Get current fp // Get current fp
.inline _get_current_fp,0 .inline _get_current_fp,0
.volatile .volatile
......
...@@ -30,6 +30,12 @@ ...@@ -30,6 +30,12 @@
movq %fs:0, %rax movq %fs:0, %rax
.end .end
// Get current sp
.inline _get_current_sp,0
.volatile
movq %rsp, %rax
.end
// Get current fp // Get current fp
.inline _get_current_fp,0 .inline _get_current_fp,0
.volatile .volatile
......
...@@ -370,6 +370,26 @@ frame os::get_sender_for_C_frame(frame* fr) { ...@@ -370,6 +370,26 @@ frame os::get_sender_for_C_frame(frame* fr) {
return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); 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 #ifndef AMD64
intptr_t* _get_previous_fp() { intptr_t* _get_previous_fp() {
...@@ -546,3 +566,11 @@ void os::setup_fpu() { ...@@ -546,3 +566,11 @@ void os::setup_fpu() {
__asm fldcw fpu_cntrl_word; __asm fldcw fpu_cntrl_word;
#endif // !AMD64 #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
...@@ -436,6 +436,7 @@ class RuntimeHistogramElement : public HistogramElement { ...@@ -436,6 +436,7 @@ class RuntimeHistogramElement : public HistogramElement {
#define VM_LEAF_BASE(result_type, header) \ #define VM_LEAF_BASE(result_type, header) \
TRACE_CALL(result_type, header) \ TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \ debug_only(NoHandleMark __hm;) \
os::verify_stack_alignment(); \
/* begin of body */ /* begin of body */
...@@ -445,6 +446,7 @@ class RuntimeHistogramElement : public HistogramElement { ...@@ -445,6 +446,7 @@ class RuntimeHistogramElement : public HistogramElement {
TRACE_CALL(result_type, header) \ TRACE_CALL(result_type, header) \
HandleMarkCleaner __hm(thread); \ HandleMarkCleaner __hm(thread); \
Thread* THREAD = thread; \ Thread* THREAD = thread; \
os::verify_stack_alignment(); \
/* begin of body */ /* begin of body */
...@@ -454,6 +456,7 @@ class RuntimeHistogramElement : public HistogramElement { ...@@ -454,6 +456,7 @@ class RuntimeHistogramElement : public HistogramElement {
TRACE_CALL(result_type, header) \ TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \ debug_only(NoHandleMark __hm;) \
Thread* THREAD = thread; \ Thread* THREAD = thread; \
os::verify_stack_alignment(); \
/* begin of body */ /* begin of body */
......
...@@ -404,6 +404,8 @@ class os: AllStatic { ...@@ -404,6 +404,8 @@ class os: AllStatic {
static address current_stack_base(); static address current_stack_base();
static size_t current_stack_size(); static size_t current_stack_size();
static void verify_stack_alignment() PRODUCT_RETURN;
static int message_box(const char* title, const char* message); static int message_box(const char* title, const char* message);
static char* do_you_want_to_debug(const char* message); static char* do_you_want_to_debug(const char* message);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册