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