OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 // r1: preserved | 506 // r1: preserved |
507 // r2: preserved | 507 // r2: preserved |
508 | 508 |
509 // Drop the execution stack down to the frame pointer and restore | 509 // Drop the execution stack down to the frame pointer and restore |
510 // the caller frame pointer and return address. | 510 // the caller frame pointer and return address. |
511 mov(sp, fp); | 511 mov(sp, fp); |
512 ldm(ia_w, sp, fp.bit() | lr.bit()); | 512 ldm(ia_w, sp, fp.bit() | lr.bit()); |
513 } | 513 } |
514 | 514 |
515 | 515 |
516 void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode) { | 516 void MacroAssembler::EnterExitFrame() { |
517 // Compute the argv pointer and keep it in a callee-saved register. | 517 // Compute the argv pointer and keep it in a callee-saved register. |
518 // r0 is argc. | 518 // r0 is argc. |
519 add(r6, sp, Operand(r0, LSL, kPointerSizeLog2)); | 519 add(r6, sp, Operand(r0, LSL, kPointerSizeLog2)); |
520 sub(r6, r6, Operand(kPointerSize)); | 520 sub(r6, r6, Operand(kPointerSize)); |
521 | 521 |
522 // Compute callee's stack pointer before making changes and save it as | 522 // Compute callee's stack pointer before making changes and save it as |
523 // ip register so that it is restored as sp register on exit, thereby | 523 // ip register so that it is restored as sp register on exit, thereby |
524 // popping the args. | 524 // popping the args. |
525 | 525 |
526 // ip = sp + kPointerSize * #args; | 526 // ip = sp + kPointerSize * #args; |
(...skipping 22 matching lines...) Expand all Loading... |
549 | 549 |
550 // Save the frame pointer and the context in top. | 550 // Save the frame pointer and the context in top. |
551 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); | 551 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); |
552 str(fp, MemOperand(ip)); | 552 str(fp, MemOperand(ip)); |
553 mov(ip, Operand(ExternalReference(Top::k_context_address))); | 553 mov(ip, Operand(ExternalReference(Top::k_context_address))); |
554 str(cp, MemOperand(ip)); | 554 str(cp, MemOperand(ip)); |
555 | 555 |
556 // Setup argc and the builtin function in callee-saved registers. | 556 // Setup argc and the builtin function in callee-saved registers. |
557 mov(r4, Operand(r0)); | 557 mov(r4, Operand(r0)); |
558 mov(r5, Operand(r1)); | 558 mov(r5, Operand(r1)); |
559 | |
560 | |
561 #ifdef ENABLE_DEBUGGER_SUPPORT | |
562 // Save the state of all registers to the stack from the memory | |
563 // location. This is needed to allow nested break points. | |
564 if (mode == ExitFrame::MODE_DEBUG) { | |
565 // Use sp as base to push. | |
566 CopyRegistersFromMemoryToStack(sp, kJSCallerSaved); | |
567 } | |
568 #endif | |
569 } | 559 } |
570 | 560 |
571 | 561 |
572 void MacroAssembler::InitializeNewString(Register string, | 562 void MacroAssembler::InitializeNewString(Register string, |
573 Register length, | 563 Register length, |
574 Heap::RootListIndex map_index, | 564 Heap::RootListIndex map_index, |
575 Register scratch1, | 565 Register scratch1, |
576 Register scratch2) { | 566 Register scratch2) { |
577 mov(scratch1, Operand(length, LSL, kSmiTagSize)); | 567 mov(scratch1, Operand(length, LSL, kSmiTagSize)); |
578 LoadRoot(scratch2, map_index); | 568 LoadRoot(scratch2, map_index); |
(...skipping 14 matching lines...) Expand all Loading... |
593 #else // defined(V8_HOST_ARCH_ARM) | 583 #else // defined(V8_HOST_ARCH_ARM) |
594 // If we are using the simulator then we should always align to the expected | 584 // If we are using the simulator then we should always align to the expected |
595 // alignment. As the simulator is used to generate snapshots we do not know | 585 // alignment. As the simulator is used to generate snapshots we do not know |
596 // if the target platform will need alignment, so this is controlled from a | 586 // if the target platform will need alignment, so this is controlled from a |
597 // flag. | 587 // flag. |
598 return FLAG_sim_stack_alignment; | 588 return FLAG_sim_stack_alignment; |
599 #endif // defined(V8_HOST_ARCH_ARM) | 589 #endif // defined(V8_HOST_ARCH_ARM) |
600 } | 590 } |
601 | 591 |
602 | 592 |
603 void MacroAssembler::LeaveExitFrame(ExitFrame::Mode mode) { | 593 void MacroAssembler::LeaveExitFrame() { |
604 #ifdef ENABLE_DEBUGGER_SUPPORT | |
605 // Restore the memory copy of the registers by digging them out from | |
606 // the stack. This is needed to allow nested break points. | |
607 if (mode == ExitFrame::MODE_DEBUG) { | |
608 // This code intentionally clobbers r2 and r3. | |
609 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | |
610 const int kOffset = ExitFrameConstants::kCodeOffset - kCallerSavedSize; | |
611 add(r3, fp, Operand(kOffset)); | |
612 CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved); | |
613 } | |
614 #endif | |
615 | |
616 // Clear top frame. | 594 // Clear top frame. |
617 mov(r3, Operand(0)); | 595 mov(r3, Operand(0)); |
618 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); | 596 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); |
619 str(r3, MemOperand(ip)); | 597 str(r3, MemOperand(ip)); |
620 | 598 |
621 // Restore current context from top and clear it in debug mode. | 599 // Restore current context from top and clear it in debug mode. |
622 mov(ip, Operand(ExternalReference(Top::k_context_address))); | 600 mov(ip, Operand(ExternalReference(Top::k_context_address))); |
623 ldr(cp, MemOperand(ip)); | 601 ldr(cp, MemOperand(ip)); |
624 #ifdef DEBUG | 602 #ifdef DEBUG |
625 str(r3, MemOperand(ip)); | 603 str(r3, MemOperand(ip)); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 // Get the function and setup the context. | 750 // Get the function and setup the context. |
773 mov(r1, Operand(Handle<JSFunction>(function))); | 751 mov(r1, Operand(Handle<JSFunction>(function))); |
774 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 752 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
775 | 753 |
776 // Invoke the cached code. | 754 // Invoke the cached code. |
777 Handle<Code> code(function->code()); | 755 Handle<Code> code(function->code()); |
778 ParameterCount expected(function->shared()->formal_parameter_count()); | 756 ParameterCount expected(function->shared()->formal_parameter_count()); |
779 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); | 757 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); |
780 } | 758 } |
781 | 759 |
| 760 |
782 #ifdef ENABLE_DEBUGGER_SUPPORT | 761 #ifdef ENABLE_DEBUGGER_SUPPORT |
783 void MacroAssembler::SaveRegistersToMemory(RegList regs) { | |
784 ASSERT((regs & ~kJSCallerSaved) == 0); | |
785 // Copy the content of registers to memory location. | |
786 for (int i = 0; i < kNumJSCallerSaved; i++) { | |
787 int r = JSCallerSavedCode(i); | |
788 if ((regs & (1 << r)) != 0) { | |
789 Register reg = { r }; | |
790 mov(ip, Operand(ExternalReference(Debug_Address::Register(i)))); | |
791 str(reg, MemOperand(ip)); | |
792 } | |
793 } | |
794 } | |
795 | |
796 | |
797 void MacroAssembler::RestoreRegistersFromMemory(RegList regs) { | |
798 ASSERT((regs & ~kJSCallerSaved) == 0); | |
799 // Copy the content of memory location to registers. | |
800 for (int i = kNumJSCallerSaved; --i >= 0;) { | |
801 int r = JSCallerSavedCode(i); | |
802 if ((regs & (1 << r)) != 0) { | |
803 Register reg = { r }; | |
804 mov(ip, Operand(ExternalReference(Debug_Address::Register(i)))); | |
805 ldr(reg, MemOperand(ip)); | |
806 } | |
807 } | |
808 } | |
809 | |
810 | |
811 void MacroAssembler::CopyRegistersFromMemoryToStack(Register base, | |
812 RegList regs) { | |
813 ASSERT((regs & ~kJSCallerSaved) == 0); | |
814 // Copy the content of the memory location to the stack and adjust base. | |
815 for (int i = kNumJSCallerSaved; --i >= 0;) { | |
816 int r = JSCallerSavedCode(i); | |
817 if ((regs & (1 << r)) != 0) { | |
818 mov(ip, Operand(ExternalReference(Debug_Address::Register(i)))); | |
819 ldr(ip, MemOperand(ip)); | |
820 str(ip, MemOperand(base, 4, NegPreIndex)); | |
821 } | |
822 } | |
823 } | |
824 | |
825 | |
826 void MacroAssembler::CopyRegistersFromStackToMemory(Register base, | |
827 Register scratch, | |
828 RegList regs) { | |
829 ASSERT((regs & ~kJSCallerSaved) == 0); | |
830 // Copy the content of the stack to the memory location and adjust base. | |
831 for (int i = 0; i < kNumJSCallerSaved; i++) { | |
832 int r = JSCallerSavedCode(i); | |
833 if ((regs & (1 << r)) != 0) { | |
834 mov(ip, Operand(ExternalReference(Debug_Address::Register(i)))); | |
835 ldr(scratch, MemOperand(base, 4, PostIndex)); | |
836 str(scratch, MemOperand(ip)); | |
837 } | |
838 } | |
839 } | |
840 | |
841 | |
842 void MacroAssembler::DebugBreak() { | 762 void MacroAssembler::DebugBreak() { |
843 ASSERT(allow_stub_calls()); | 763 ASSERT(allow_stub_calls()); |
844 mov(r0, Operand(0)); | 764 mov(r0, Operand(0)); |
845 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak))); | 765 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak))); |
846 CEntryStub ces(1); | 766 CEntryStub ces(1); |
847 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 767 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
848 } | 768 } |
849 #endif | 769 #endif |
850 | 770 |
851 | 771 |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 | 1847 |
1928 void CodePatcher::Emit(Address addr) { | 1848 void CodePatcher::Emit(Address addr) { |
1929 masm()->emit(reinterpret_cast<Instr>(addr)); | 1849 masm()->emit(reinterpret_cast<Instr>(addr)); |
1930 } | 1850 } |
1931 #endif // ENABLE_DEBUGGER_SUPPORT | 1851 #endif // ENABLE_DEBUGGER_SUPPORT |
1932 | 1852 |
1933 | 1853 |
1934 } } // namespace v8::internal | 1854 } } // namespace v8::internal |
1935 | 1855 |
1936 #endif // V8_TARGET_ARCH_ARM | 1856 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |