| 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.
|
|
|