Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: src/arm/macro-assembler-arm.cc

Issue 1530043: Ensure stack alignment in ARM port... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/macro-assembler-arm.cc
===================================================================
--- src/arm/macro-assembler-arm.cc (revision 4424)
+++ src/arm/macro-assembler-arm.cc (working copy)
@@ -355,10 +355,19 @@
// ip = sp + kPointerSize * #args;
add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
- // Align the stack at this point. After this point we have 5 pushes,
- // so in fact we have to unalign here! See also the assert on the
- // alignment in AlignStack.
- AlignStack(1);
+ // Prepare the stack to be aligned when calling into C. After this point there
+ // are 5 pushes before the call into C, so the stack needs to be aligned after
+ // 5 pushes.
+ int frame_alignment = ActivationFrameAlignment();
+ int frame_alignment_mask = frame_alignment - 1;
+ if (frame_alignment != kPointerSize) {
+ // The following code needs to be more general if this assert does not hold.
+ ASSERT(frame_alignment == 2 * kPointerSize);
+ // With 5 pushes left the frame must be unaligned at this point.
+ mov(r7, Operand(Smi::FromInt(0)));
+ tst(sp, Operand((frame_alignment - kPointerSize) & frame_alignment_mask));
+ push(r7, eq); // Push if aligned to make it unaligned.
+ }
// Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
@@ -389,27 +398,20 @@
}
-void MacroAssembler::AlignStack(int offset) {
+int MacroAssembler::ActivationFrameAlignment() {
#if defined(V8_HOST_ARCH_ARM)
// Running on the real platform. Use the alignment as mandated by the local
// environment.
// Note: This will break if we ever start generating snapshots on one ARM
// platform for another ARM platform with a different alignment.
- int activation_frame_alignment = OS::ActivationFrameAlignment();
+ return OS::ActivationFrameAlignment();
#else // defined(V8_HOST_ARCH_ARM)
// If we are using the simulator then we should always align to the expected
// alignment. As the simulator is used to generate snapshots we do not know
- // if the target platform will need alignment, so we will always align at
- // this point here.
- int activation_frame_alignment = 2 * kPointerSize;
+ // if the target platform will need alignment, so this is controlled from a
+ // flag.
+ return FLAG_sim_stack_alignment;
#endif // defined(V8_HOST_ARCH_ARM)
- if (activation_frame_alignment != kPointerSize) {
- // This code needs to be made more general if this assert doesn't hold.
- ASSERT(activation_frame_alignment == 2 * kPointerSize);
- mov(r7, Operand(Smi::FromInt(0)));
- tst(sp, Operand(activation_frame_alignment - offset));
- push(r7, eq); // Conditional push instruction.
- }
}
@@ -1572,16 +1574,16 @@
void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
- int frameAlignment = OS::ActivationFrameAlignment();
+ int frame_alignment = ActivationFrameAlignment();
// Up to four simple arguments are passed in registers r0..r3.
int stack_passed_arguments = (num_arguments <= 4) ? 0 : num_arguments - 4;
- if (frameAlignment > kPointerSize) {
+ if (frame_alignment > kPointerSize) {
// Make stack end at alignment and make room for num_arguments - 4 words
// and the original value of sp.
mov(scratch, sp);
sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize));
- ASSERT(IsPowerOf2(frameAlignment));
- and_(sp, sp, Operand(-frameAlignment));
+ ASSERT(IsPowerOf2(frame_alignment));
+ and_(sp, sp, Operand(-frame_alignment));
str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
} else {
sub(sp, sp, Operand(stack_passed_arguments * kPointerSize));
@@ -1597,6 +1599,26 @@
void MacroAssembler::CallCFunction(Register function, int num_arguments) {
+ // Make sure that the stack is aligned before calling a C function unless
+ // running in the simulator. The simulator has its own alignment check which
+ // provides more information.
+#if defined(V8_HOST_ARCH_ARM)
+ if (FLAG_debug_code) {
+ int frame_alignment = OS::ActivationFrameAlignment();
+ int frame_alignment_mask = frame_alignment - 1;
+ if (frame_alignment > kPointerSize) {
+ ASSERT(IsPowerOf2(frame_alignment));
+ Label alignment_as_expected;
+ tst(sp, Operand(frame_alignment_mask));
+ b(eq, &alignment_as_expected);
+ // Don't use Check here, as it will call Runtime_Abort possibly
+ // re-entering here.
+ stop("Unexpected alignment");
+ bind(&alignment_as_expected);
+ }
+ }
+#endif
+
// Just call directly. The function called cannot cause a GC, or
// allow preemption, so the return address in the link register
// stays correct.
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698