| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 722 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
| 723 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 723 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 724 // Pop arguments; result is popped in IP. | 724 // Pop arguments; result is popped in IP. |
| 725 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 725 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
| 726 __ mov(R0, ShifterOperand(IP)); | 726 __ mov(R0, ShifterOperand(IP)); |
| 727 __ LeaveStubFrame(); | 727 __ LeaveStubFrame(); |
| 728 __ Ret(); | 728 __ Ret(); |
| 729 } | 729 } |
| 730 | 730 |
| 731 | 731 |
| 732 // Input parameters: | |
| 733 // LR: return address. | |
| 734 // SP: address of last argument. | |
| 735 // R4: arguments descriptor array. | |
| 736 // Note: The closure object is the first argument to the function being | |
| 737 // called, the stub accesses the closure from this location directly | |
| 738 // when trying to resolve the call. | |
| 739 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | |
| 740 // Load num_args. | |
| 741 __ ldr(R0, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | |
| 742 __ sub(R0, R0, ShifterOperand(Smi::RawValue(1))); | |
| 743 // Load closure object in R1. | |
| 744 __ ldr(R1, Address(SP, R0, LSL, 1)); // R0 (num_args - 1) is a Smi. | |
| 745 | |
| 746 // Verify that R1 is a closure by checking its class. | |
| 747 Label not_closure; | |
| 748 __ LoadImmediate(R8, reinterpret_cast<intptr_t>(Object::null())); | |
| 749 __ cmp(R1, ShifterOperand(R8)); | |
| 750 // Not a closure, but null object. | |
| 751 __ b(¬_closure, EQ); | |
| 752 __ tst(R1, ShifterOperand(kSmiTagMask)); | |
| 753 __ b(¬_closure, EQ); // Not a closure, but a smi. | |
| 754 // Verify that the class of the object is a closure class by checking that | |
| 755 // class.signature_function() is not null. | |
| 756 __ LoadClass(R0, R1, R2); | |
| 757 __ ldr(R0, FieldAddress(R0, Class::signature_function_offset())); | |
| 758 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. | |
| 759 // Actual class is not a closure class. | |
| 760 __ b(¬_closure, EQ); | |
| 761 | |
| 762 // R0 is just the signature function. Load the actual closure function. | |
| 763 __ ldr(R0, FieldAddress(R1, Closure::function_offset())); | |
| 764 | |
| 765 // Load closure context in CTX; note that CTX has already been preserved. | |
| 766 __ ldr(CTX, FieldAddress(R1, Closure::context_offset())); | |
| 767 | |
| 768 // R4: Arguments descriptor. | |
| 769 // R0: Function. | |
| 770 __ ldr(R2, FieldAddress(R0, Function::code_offset())); | |
| 771 | |
| 772 // R2: code. | |
| 773 // R5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | |
| 774 __ LoadImmediate(R5, 0); | |
| 775 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); | |
| 776 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 777 __ bx(R2); | |
| 778 | |
| 779 __ Bind(¬_closure); | |
| 780 // Call runtime to attempt to resolve and invoke a call method on a | |
| 781 // non-closure object, passing the non-closure object and its arguments array, | |
| 782 // returning here. | |
| 783 // If no call method exists, throw a NoSuchMethodError. | |
| 784 // R1: non-closure object. | |
| 785 // R4: arguments descriptor array. | |
| 786 | |
| 787 // Create a stub frame as we are pushing some objects on the stack before | |
| 788 // calling into the runtime. | |
| 789 __ EnterStubFrame(); | |
| 790 | |
| 791 // Setup space on stack for result from error reporting. | |
| 792 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. | |
| 793 | |
| 794 // Load smi-tagged arguments array length, including the non-closure. | |
| 795 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | |
| 796 PushArgumentsArray(assembler); | |
| 797 | |
| 798 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); | |
| 799 // Remove arguments. | |
| 800 __ Drop(2); | |
| 801 __ Pop(R0); // Get result into R0. | |
| 802 | |
| 803 // Remove the stub frame as we are about to return. | |
| 804 __ LeaveStubFrame(); | |
| 805 __ Ret(); | |
| 806 } | |
| 807 | |
| 808 | |
| 809 // Called when invoking Dart code from C++ (VM code). | 732 // Called when invoking Dart code from C++ (VM code). |
| 810 // Input parameters: | 733 // Input parameters: |
| 811 // LR : points to return address. | 734 // LR : points to return address. |
| 812 // R0 : entrypoint of the Dart function to call. | 735 // R0 : entrypoint of the Dart function to call. |
| 813 // R1 : arguments descriptor array. | 736 // R1 : arguments descriptor array. |
| 814 // R2 : arguments array. | 737 // R2 : arguments array. |
| 815 // R3 : new context containing the current isolate pointer. | 738 // R3 : new context containing the current isolate pointer. |
| 816 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 739 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 817 // Save frame pointer coming in. | 740 // Save frame pointer coming in. |
| 818 __ EnterFrame((1 << FP) | (1 << LR), 0); | 741 __ EnterFrame((1 << FP) | (1 << LR), 0); |
| (...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1929 const Register right = R0; | 1852 const Register right = R0; |
| 1930 __ ldr(left, Address(SP, 1 * kWordSize)); | 1853 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 1931 __ ldr(right, Address(SP, 0 * kWordSize)); | 1854 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 1932 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1855 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1933 __ Ret(); | 1856 __ Ret(); |
| 1934 } | 1857 } |
| 1935 | 1858 |
| 1936 } // namespace dart | 1859 } // namespace dart |
| 1937 | 1860 |
| 1938 #endif // defined TARGET_ARCH_ARM | 1861 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |