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