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 |