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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 6247019: Change ARM exit frame layout and alingment handling... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/frames-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 // r2: preserved 608 // r2: preserved
609 609
610 // Drop the execution stack down to the frame pointer and restore 610 // Drop the execution stack down to the frame pointer and restore
611 // the caller frame pointer and return address. 611 // the caller frame pointer and return address.
612 mov(sp, fp); 612 mov(sp, fp);
613 ldm(ia_w, sp, fp.bit() | lr.bit()); 613 ldm(ia_w, sp, fp.bit() | lr.bit());
614 } 614 }
615 615
616 616
617 void MacroAssembler::EnterExitFrame(bool save_doubles) { 617 void MacroAssembler::EnterExitFrame(bool save_doubles) {
618 // r0 is argc. 618 // Compute the argv pointer in a callee-saved register.
619 // Compute callee's stack pointer before making changes and save it as 619 add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
620 // ip register so that it is restored as sp register on exit, thereby 620 sub(r6, r6, Operand(kPointerSize));
621 // popping the args.
622 621
623 // ip = sp + kPointerSize * #args; 622 // Setup the frame structure on the stack.
624 add(ip, sp, Operand(r0, LSL, kPointerSizeLog2)); 623 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
625 624 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
626 // Compute the argv pointer and keep it in a callee-saved register. 625 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
627 sub(r6, ip, Operand(kPointerSize)); 626 Push(lr, fp);
628 627 mov(fp, Operand(sp)); // Setup new frame pointer.
629 // Prepare the stack to be aligned when calling into C. After this point there 628 // Reserve room for saved entry sp and code object.
630 // are 5 pushes before the call into C, so the stack needs to be aligned after 629 sub(sp, sp, Operand(2 * kPointerSize));
631 // 5 pushes. 630 if (FLAG_debug_code) {
632 int frame_alignment = ActivationFrameAlignment(); 631 mov(ip, Operand(0));
633 int frame_alignment_mask = frame_alignment - 1; 632 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
634 if (frame_alignment != kPointerSize) {
635 // The following code needs to be more general if this assert does not hold.
636 ASSERT(frame_alignment == 2 * kPointerSize);
637 // With 5 pushes left the frame must be unaligned at this point.
638 mov(r7, Operand(Smi::FromInt(0)));
639 tst(sp, Operand((frame_alignment - kPointerSize) & frame_alignment_mask));
640 push(r7, eq); // Push if aligned to make it unaligned.
641 } 633 }
642
643 // Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
644 stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
645 mov(fp, Operand(sp)); // Setup new frame pointer.
646
647 mov(ip, Operand(CodeObject())); 634 mov(ip, Operand(CodeObject()));
648 push(ip); // Accessed from ExitFrame::code_slot. 635 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
649 636
650 // Save the frame pointer and the context in top. 637 // Save the frame pointer and the context in top.
651 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); 638 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
652 str(fp, MemOperand(ip)); 639 str(fp, MemOperand(ip));
653 mov(ip, Operand(ExternalReference(Top::k_context_address))); 640 mov(ip, Operand(ExternalReference(Top::k_context_address)));
654 str(cp, MemOperand(ip)); 641 str(cp, MemOperand(ip));
655 642
656 // Setup argc and the builtin function in callee-saved registers. 643 // Setup argc and the builtin function in callee-saved registers.
657 mov(r4, Operand(r0)); 644 mov(r4, Operand(r0));
658 mov(r5, Operand(r1)); 645 mov(r5, Operand(r1));
659 646
660 // Optionally save all double registers. 647 // Optionally save all double registers.
661 if (save_doubles) { 648 if (save_doubles) {
662 // TODO(regis): Use vstrm instruction. 649 sub(sp, sp, Operand(DwVfpRegister::kNumRegisters * kDoubleSize));
663 // The stack alignment code above made sp unaligned, so add space for one 650 const int offset = -2 * kPointerSize;
664 // more double register and use aligned addresses.
665 ASSERT(kDoubleSize == frame_alignment);
666 // Mark the frame as containing doubles by pushing a non-valid return
667 // address, i.e. 0.
668 ASSERT(ExitFrameConstants::kMarkerOffset == -2 * kPointerSize);
669 mov(ip, Operand(0)); // Marker and alignment word.
670 push(ip);
671 int space = DwVfpRegister::kNumRegisters * kDoubleSize + kPointerSize;
672 sub(sp, sp, Operand(space));
673 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { 651 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
674 DwVfpRegister reg = DwVfpRegister::from_code(i); 652 DwVfpRegister reg = DwVfpRegister::from_code(i);
675 vstr(reg, sp, i * kDoubleSize + kPointerSize); 653 vstr(reg, fp, offset - ((i + 1) * kDoubleSize));
676 } 654 }
677 // Note that d0 will be accessible at fp - 2*kPointerSize - 655 // Note that d0 will be accessible at
678 // DwVfpRegister::kNumRegisters * kDoubleSize, since the code slot and the 656 // fp - 2 * kPointerSize - DwVfpRegister::kNumRegisters * kDoubleSize,
679 // alignment word were pushed after the fp. 657 // since the sp slot and code slot were pushed after the fp.
680 } 658 }
659
660 // Reserve place for the return address and align the frame preparing for
661 // calling the runtime function.
662 const int frame_alignment = MacroAssembler::ActivationFrameAlignment();
663 sub(sp, sp, Operand(kPointerSize));
664 if (frame_alignment > 0) {
665 ASSERT(IsPowerOf2(frame_alignment));
666 and_(sp, sp, Operand(-frame_alignment));
667 }
668
669 // Set the exit frame sp value to point just before the return address
670 // location.
671 add(ip, sp, Operand(kPointerSize));
672 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
681 } 673 }
682 674
683 675
684 void MacroAssembler::InitializeNewString(Register string, 676 void MacroAssembler::InitializeNewString(Register string,
685 Register length, 677 Register length,
686 Heap::RootListIndex map_index, 678 Heap::RootListIndex map_index,
687 Register scratch1, 679 Register scratch1,
688 Register scratch2) { 680 Register scratch2) {
689 mov(scratch1, Operand(length, LSL, kSmiTagSize)); 681 mov(scratch1, Operand(length, LSL, kSmiTagSize));
690 LoadRoot(scratch2, map_index); 682 LoadRoot(scratch2, map_index);
(...skipping 17 matching lines...) Expand all
708 // if the target platform will need alignment, so this is controlled from a 700 // if the target platform will need alignment, so this is controlled from a
709 // flag. 701 // flag.
710 return FLAG_sim_stack_alignment; 702 return FLAG_sim_stack_alignment;
711 #endif // defined(V8_HOST_ARCH_ARM) 703 #endif // defined(V8_HOST_ARCH_ARM)
712 } 704 }
713 705
714 706
715 void MacroAssembler::LeaveExitFrame(bool save_doubles) { 707 void MacroAssembler::LeaveExitFrame(bool save_doubles) {
716 // Optionally restore all double registers. 708 // Optionally restore all double registers.
717 if (save_doubles) { 709 if (save_doubles) {
718 // TODO(regis): Use vldrm instruction.
719 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { 710 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
720 DwVfpRegister reg = DwVfpRegister::from_code(i); 711 DwVfpRegister reg = DwVfpRegister::from_code(i);
721 // Register d15 is just below the marker. 712 const int offset = -2 * kPointerSize;
722 const int offset = ExitFrameConstants::kMarkerOffset; 713 vldr(reg, fp, offset - ((i + 1) * kDoubleSize));
723 vldr(reg, fp, (i - DwVfpRegister::kNumRegisters) * kDoubleSize + offset);
724 } 714 }
725 } 715 }
726 716
727 // Clear top frame. 717 // Clear top frame.
728 mov(r3, Operand(0, RelocInfo::NONE)); 718 mov(r3, Operand(0, RelocInfo::NONE));
729 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); 719 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
730 str(r3, MemOperand(ip)); 720 str(r3, MemOperand(ip));
731 721
732 // Restore current context from top and clear it in debug mode. 722 // Restore current context from top and clear it in debug mode.
733 mov(ip, Operand(ExternalReference(Top::k_context_address))); 723 mov(ip, Operand(ExternalReference(Top::k_context_address)));
734 ldr(cp, MemOperand(ip)); 724 ldr(cp, MemOperand(ip));
735 #ifdef DEBUG 725 #ifdef DEBUG
736 str(r3, MemOperand(ip)); 726 str(r3, MemOperand(ip));
737 #endif 727 #endif
738 728
739 // Pop the arguments, restore registers, and return. 729 // Tear down the exit frame, pop the arguments, and return. Callee-saved
740 mov(sp, Operand(fp)); // respect ABI stack constraint 730 // register r4 still holds argc.
741 ldm(ia, sp, fp.bit() | sp.bit() | pc.bit()); 731 mov(sp, Operand(fp));
732 ldm(ia_w, sp, fp.bit() | lr.bit());
733 add(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
734 mov(pc, lr);
742 } 735 }
743 736
744 737
745 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 738 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
746 const ParameterCount& actual, 739 const ParameterCount& actual,
747 Handle<Code> code_constant, 740 Handle<Code> code_constant,
748 Register code_reg, 741 Register code_reg,
749 Label* done, 742 Label* done,
750 InvokeFlag flag, 743 InvokeFlag flag,
751 PostCallGenerator* post_call_generator) { 744 PostCallGenerator* post_call_generator) {
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 2245
2253 void CodePatcher::Emit(Address addr) { 2246 void CodePatcher::Emit(Address addr) {
2254 masm()->emit(reinterpret_cast<Instr>(addr)); 2247 masm()->emit(reinterpret_cast<Instr>(addr));
2255 } 2248 }
2256 #endif // ENABLE_DEBUGGER_SUPPORT 2249 #endif // ENABLE_DEBUGGER_SUPPORT
2257 2250
2258 2251
2259 } } // namespace v8::internal 2252 } } // namespace v8::internal
2260 2253
2261 #endif // V8_TARGET_ARCH_ARM 2254 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/frames-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698