Commit f6cce432 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Add stack alignment check to ia32 and x64

The stack is now checked for proper alignment before calling into C code when the flag --debug-code is turned on.
Review URL: http://codereview.chromium.org/1637015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4428 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 61085478
......@@ -11740,7 +11740,17 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Result returned in eax, or eax+edx if result_size_ is 2.
// Check stack alignment.
if (FLAG_debug_code) {
__ CheckStackAlignment();
}
if (do_gc) {
// Pass failure code returned from last attempt as first argument to
// PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
// stack alignment is known to be correct. This function takes one argument
// which is passed on the stack, and we know that the stack has been
// prepared to pass at least one argument.
__ mov(Operand(esp, 0 * kPointerSize), eax); // Result.
__ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
}
......
......@@ -1535,6 +1535,21 @@ void MacroAssembler::Check(Condition cc, const char* msg) {
}
void MacroAssembler::CheckStackAlignment() {
int frame_alignment = OS::ActivationFrameAlignment();
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment > kPointerSize) {
ASSERT(IsPowerOf2(frame_alignment));
Label alignment_as_expected;
test(esp, Immediate(frame_alignment_mask));
j(zero, &alignment_as_expected);
// Abort if stack is not aligned.
int3();
bind(&alignment_as_expected);
}
}
void MacroAssembler::Abort(const char* msg) {
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned
......@@ -1634,6 +1649,11 @@ void MacroAssembler::CallCFunction(ExternalReference function,
void MacroAssembler::CallCFunction(Register function,
int num_arguments) {
// Check stack alignment.
if (FLAG_debug_code) {
CheckStackAlignment();
}
call(Operand(function));
if (OS::ActivationFrameAlignment() != 0) {
mov(esp, Operand(esp, num_arguments * kPointerSize));
......
......@@ -463,6 +463,9 @@ class MacroAssembler: public Assembler {
// Print a message to stdout and abort execution.
void Abort(const char* msg);
// Check that the stack is aligned.
void CheckStackAlignment();
// Verify restrictions about code generated in stubs.
void set_generating_stub(bool value) { generating_stub_ = value; }
bool generating_stub() { return generating_stub_; }
......
......@@ -159,7 +159,7 @@ int OS::ActivationFrameAlignment() {
#elif V8_TARGET_ARCH_MIPS
return 8;
#endif
// With gcc 4.4 the tree vectorization optimiser can generate code
// With gcc 4.4 the tree vectorization optimizer can generate code
// that requires 16 byte alignment such as movdqa on x86.
return 16;
}
......
......@@ -8249,8 +8249,16 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Complex results must be written to address passed as first argument.
// AMD64 calling convention: a struct of two pointers in rax+rdx
// Check stack alignment.
if (FLAG_debug_code) {
__ CheckStackAlignment();
}
if (do_gc) {
// Pass failure code returned from last attempt as first argument to GC.
// Pass failure code returned from last attempt as first argument to
// PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
// stack is known to be aligned. This function takes one argument which is
// passed in register.
#ifdef _WIN64
__ movq(rcx, rax);
#else // ! defined(_WIN64)
......
......@@ -291,6 +291,21 @@ void MacroAssembler::Check(Condition cc, const char* msg) {
}
void MacroAssembler::CheckStackAlignment() {
int frame_alignment = OS::ActivationFrameAlignment();
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment > kPointerSize) {
ASSERT(IsPowerOf2(frame_alignment));
Label alignment_as_expected;
testq(rsp, Immediate(frame_alignment_mask));
j(zero, &alignment_as_expected);
// Abort if stack is not aligned.
int3();
bind(&alignment_as_expected);
}
}
void MacroAssembler::NegativeZeroTest(Register result,
Register op,
Label* then_label) {
......@@ -2628,6 +2643,11 @@ void MacroAssembler::CallCFunction(ExternalReference function,
void MacroAssembler::CallCFunction(Register function, int num_arguments) {
// Check stack alignment.
if (FLAG_debug_code) {
CheckStackAlignment();
}
call(function);
ASSERT(OS::ActivationFrameAlignment() != 0);
ASSERT(num_arguments >= 0);
......
......@@ -737,6 +737,9 @@ class MacroAssembler: public Assembler {
// Print a message to stdout and abort execution.
void Abort(const char* msg);
// Check that the stack is aligned.
void CheckStackAlignment();
// Verify restrictions about code generated in stubs.
void set_generating_stub(bool value) { generating_stub_ = value; }
bool generating_stub() { return generating_stub_; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment