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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 // Pop arguments; result is popped in IP. | 819 // Pop arguments; result is popped in IP. |
820 __ lw(V0, Address(SP, 2 * kWordSize)); | 820 __ lw(V0, Address(SP, 2 * kWordSize)); |
821 __ lw(A1, Address(SP, 1 * kWordSize)); | 821 __ lw(A1, Address(SP, 1 * kWordSize)); |
822 __ lw(A0, Address(SP, 0 * kWordSize)); | 822 __ lw(A0, Address(SP, 0 * kWordSize)); |
823 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 823 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
824 | 824 |
825 __ LeaveStubFrameAndReturn(); | 825 __ LeaveStubFrameAndReturn(); |
826 } | 826 } |
827 | 827 |
828 | 828 |
829 // Input parameters: | |
830 // RA: return address. | |
831 // SP: address of last argument. | |
832 // S4: Arguments descriptor array. | |
833 // Return: V0. | |
834 // Note: The closure object is the first argument to the function being | |
835 // called, the stub accesses the closure from this location directly | |
836 // when trying to resolve the call. | |
837 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | |
838 // Load num_args. | |
839 __ TraceSimMsg("GenerateCallClosureFunctionStub"); | |
840 __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | |
841 __ LoadImmediate(TMP, Smi::RawValue(1)); | |
842 __ subu(T0, T0, TMP); | |
843 | |
844 // Load closure object in T1. | |
845 __ sll(T1, T0, 1); // T0 (num_args - 1) is a Smi. | |
846 __ addu(T1, SP, T1); | |
847 __ lw(T1, Address(T1)); | |
848 | |
849 // Verify that T1 is a closure by checking its class. | |
850 Label not_closure; | |
851 | |
852 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | |
853 | |
854 // See if it is not a closure, but null object. | |
855 __ beq(T1, T7, ¬_closure); | |
856 | |
857 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); | |
858 __ beq(CMPRES1, ZR, ¬_closure); // Not a closure, but a smi. | |
859 | |
860 // Verify that the class of the object is a closure class by checking that | |
861 // class.signature_function() is not null. | |
862 __ LoadClass(T0, T1); | |
863 __ lw(T0, FieldAddress(T0, Class::signature_function_offset())); | |
864 | |
865 // See if actual class is not a closure class. | |
866 __ beq(T0, T7, ¬_closure); | |
867 | |
868 // T0 is just the signature function. Load the actual closure function. | |
869 __ lw(T0, FieldAddress(T1, Closure::function_offset())); | |
870 | |
871 // Load closure context in CTX; note that CTX has already been preserved. | |
872 __ lw(CTX, FieldAddress(T1, Closure::context_offset())); | |
873 | |
874 // Load closure function code in T2. | |
875 // S4: arguments descriptor array. | |
876 // S5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | |
877 __ LoadImmediate(S5, 0); | |
878 __ lw(T2, FieldAddress(T0, Function::code_offset())); | |
879 __ lw(T2, FieldAddress(T2, Code::instructions_offset())); | |
880 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag); | |
881 __ jr(T2); | |
882 | |
883 __ Bind(¬_closure); | |
884 // Call runtime to attempt to resolve and invoke a call method on a | |
885 // non-closure object, passing the non-closure object and its arguments array, | |
886 // returning here. | |
887 // If no call method exists, throw a NoSuchMethodError. | |
888 // T1: non-closure object. | |
889 // S4: arguments descriptor array. | |
890 | |
891 // Create a stub frame as we are pushing some objects on the stack before | |
892 // calling into the runtime. | |
893 __ EnterStubFrame(); | |
894 | |
895 // Setup space on stack for result from error reporting. | |
896 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
897 // Arguments descriptor and raw null. | |
898 __ sw(T7, Address(SP, 1 * kWordSize)); | |
899 __ sw(S4, Address(SP, 0 * kWordSize)); | |
900 | |
901 // Load smi-tagged arguments array length, including the non-closure. | |
902 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | |
903 PushArgumentsArray(assembler); | |
904 | |
905 // Stack: | |
906 // TOS + 0: Argument array. | |
907 // TOS + 1: Arguments descriptor array. | |
908 // TOS + 2: Place for result from the call. | |
909 // TOS + 3: Saved FP of previous frame. | |
910 // TOS + 4: Dart code return address. | |
911 // TOS + 5: PC marker (0 for stub). | |
912 // TOS + 6: Last argument of caller. | |
913 // .... | |
914 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); | |
915 __ lw(V0, Address(SP, 2 * kWordSize)); // Get result into V0. | |
916 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Remove arguments. | |
917 | |
918 // Remove the stub frame as we are about to return. | |
919 __ LeaveStubFrameAndReturn(); | |
920 } | |
921 | |
922 | |
923 // Called when invoking Dart code from C++ (VM code). | 829 // Called when invoking Dart code from C++ (VM code). |
924 // Input parameters: | 830 // Input parameters: |
925 // RA : points to return address. | 831 // RA : points to return address. |
926 // A0 : entrypoint of the Dart function to call. | 832 // A0 : entrypoint of the Dart function to call. |
927 // A1 : arguments descriptor array. | 833 // A1 : arguments descriptor array. |
928 // A2 : arguments array. | 834 // A2 : arguments array. |
929 // A3 : new context containing the current isolate pointer. | 835 // A3 : new context containing the current isolate pointer. |
930 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 836 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
931 // Save frame pointer coming in. | 837 // Save frame pointer coming in. |
932 __ TraceSimMsg("InvokeDartCodeStub"); | 838 __ TraceSimMsg("InvokeDartCodeStub"); |
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 const Register right = T0; | 2100 const Register right = T0; |
2195 __ lw(left, Address(SP, 1 * kWordSize)); | 2101 __ lw(left, Address(SP, 1 * kWordSize)); |
2196 __ lw(right, Address(SP, 0 * kWordSize)); | 2102 __ lw(right, Address(SP, 0 * kWordSize)); |
2197 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2103 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2198 __ Ret(); | 2104 __ Ret(); |
2199 } | 2105 } |
2200 | 2106 |
2201 } // namespace dart | 2107 } // namespace dart |
2202 | 2108 |
2203 #endif // defined TARGET_ARCH_MIPS | 2109 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |