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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 // Save current Context pointer into Isolate structure. | 56 // Save current Context pointer into Isolate structure. |
57 __ sw(CTX, Address(A0, Isolate::top_context_offset())); | 57 __ sw(CTX, Address(A0, Isolate::top_context_offset())); |
58 | 58 |
59 // Cache Isolate pointer into CTX while executing runtime code. | 59 // Cache Isolate pointer into CTX while executing runtime code. |
60 __ mov(CTX, A0); | 60 __ mov(CTX, A0); |
61 | 61 |
62 // Reserve space for arguments and align frame before entering C++ world. | 62 // Reserve space for arguments and align frame before entering C++ world. |
63 // NativeArguments are passed in registers. | 63 // NativeArguments are passed in registers. |
64 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 64 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
65 __ ReserveAlignedFrameSpace(0); | 65 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments. |
66 | 66 |
67 // Pass NativeArguments structure by value and call runtime. | 67 // Pass NativeArguments structure by value and call runtime. |
68 // Registers A0, A1, A2, and A3 are used. | 68 // Registers A0, A1, A2, and A3 are used. |
69 | 69 |
70 ASSERT(isolate_offset == 0 * kWordSize); | 70 ASSERT(isolate_offset == 0 * kWordSize); |
71 // Set isolate in NativeArgs: A0 already contains CTX. | 71 // Set isolate in NativeArgs: A0 already contains CTX. |
72 | 72 |
73 // There are no runtime calls to closures, so we do not need to set the tag | 73 // There are no runtime calls to closures, so we do not need to set the tag |
74 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 74 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
75 ASSERT(argc_tag_offset == 1 * kWordSize); | 75 ASSERT(argc_tag_offset == 1 * kWordSize); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 // Save exit frame information to enable stack walking as we are about | 154 // Save exit frame information to enable stack walking as we are about |
155 // to transition to native code. | 155 // to transition to native code. |
156 __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset())); | 156 __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset())); |
157 | 157 |
158 // Save current Context pointer into Isolate structure. | 158 // Save current Context pointer into Isolate structure. |
159 __ sw(CTX, Address(A0, Isolate::top_context_offset())); | 159 __ sw(CTX, Address(A0, Isolate::top_context_offset())); |
160 | 160 |
161 // Cache Isolate pointer into CTX while executing native code. | 161 // Cache Isolate pointer into CTX while executing native code. |
162 __ mov(CTX, A0); | 162 __ mov(CTX, A0); |
163 | 163 |
164 // Reserve space for the native arguments structure passed on the stack (the | |
165 // outgoing pointer parameter to the native arguments structure is passed in | |
166 // R0) and align frame before entering the C++ world. | |
167 __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); | |
168 | |
169 // Initialize NativeArguments structure and call native function. | 164 // Initialize NativeArguments structure and call native function. |
170 // Registers A0, A1, A2, and A3 are used. | 165 // Registers A0, A1, A2, and A3 are used. |
171 | 166 |
172 ASSERT(isolate_offset == 0 * kWordSize); | 167 ASSERT(isolate_offset == 0 * kWordSize); |
173 // Set isolate in NativeArgs: A0 already contains CTX. | 168 // Set isolate in NativeArgs: A0 already contains CTX. |
174 | 169 |
175 // There are no native calls to closures, so we do not need to set the tag | 170 // There are no native calls to closures, so we do not need to set the tag |
176 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 171 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
177 ASSERT(argc_tag_offset == 1 * kWordSize); | 172 ASSERT(argc_tag_offset == 1 * kWordSize); |
178 // Set argc in NativeArguments: T1 already contains argc. | 173 // Set argc in NativeArguments: T1 already contains argc. |
179 | 174 |
180 ASSERT(argv_offset == 2 * kWordSize); | 175 ASSERT(argv_offset == 2 * kWordSize); |
181 // Set argv in NativeArguments: T2 already contains argv. | 176 // Set argv in NativeArguments: T2 already contains argv. |
182 | 177 |
183 ASSERT(retval_offset == 3 * kWordSize); | 178 ASSERT(retval_offset == 3 * kWordSize); |
184 __ addiu(A3, FP, Immediate(2 * kWordSize)); // Set retval in NativeArgs. | 179 __ addiu(A3, FP, Immediate(2 * kWordSize)); // Set retval in NativeArgs. |
185 | 180 |
186 // TODO(regis): Should we pass the structure by value as in runtime calls? | 181 // TODO(regis): Should we pass the structure by value as in runtime calls? |
187 // It would require changing Dart API for native functions. | 182 // It would require changing Dart API for native functions. |
188 // For now, space is reserved on the stack and we pass a pointer to it. | 183 // For now, space is reserved on the stack and we pass a pointer to it. |
189 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 184 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
190 __ sw(A3, Address(SP, 3 * kWordSize)); | 185 __ sw(A3, Address(SP, 3 * kWordSize)); |
191 __ sw(A2, Address(SP, 2 * kWordSize)); | 186 __ sw(A2, Address(SP, 2 * kWordSize)); |
192 __ sw(A1, Address(SP, 1 * kWordSize)); | 187 __ sw(A1, Address(SP, 1 * kWordSize)); |
193 __ sw(A0, Address(SP, 0 * kWordSize)); | 188 __ sw(A0, Address(SP, 0 * kWordSize)); |
| 189 __ mov(A0, SP); // Pass the pointer to the NativeArguments. |
| 190 |
| 191 __ ReserveAlignedFrameSpace(kWordSize); // Just passing A0. |
194 | 192 |
195 // Call native function or redirection via simulator. | 193 // Call native function or redirection via simulator. |
196 __ jalr(T5); | 194 __ jalr(T5); |
197 __ delay_slot()->mov(A0, SP); // Pass the pointer to the NativeArguments. | |
198 __ TraceSimMsg("CallNativeCFunctionStub return"); | 195 __ TraceSimMsg("CallNativeCFunctionStub return"); |
199 | 196 |
200 // Reset exit frame information in Isolate structure. | 197 // Reset exit frame information in Isolate structure. |
201 __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset())); | 198 __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset())); |
202 | 199 |
203 // Load Context pointer from Isolate structure into A2. | 200 // Load Context pointer from Isolate structure into A2. |
204 __ lw(A2, Address(CTX, Isolate::top_context_offset())); | 201 __ lw(A2, Address(CTX, Isolate::top_context_offset())); |
205 | 202 |
206 // Reload NULLREG. | 203 // Reload NULLREG. |
207 __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null())); | 204 __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null())); |
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 // but only at exit so that we have collected all type feedback before | 1468 // but only at exit so that we have collected all type feedback before |
1472 // optimizing. | 1469 // optimizing. |
1473 } | 1470 } |
1474 __ addiu(T1, T1, Immediate(1)); | 1471 __ addiu(T1, T1, Immediate(1)); |
1475 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); | 1472 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); |
1476 __ Bind(&is_hot); | 1473 __ Bind(&is_hot); |
1477 } | 1474 } |
1478 | 1475 |
1479 | 1476 |
1480 // Generate inline cache check for 'num_args'. | 1477 // Generate inline cache check for 'num_args'. |
1481 // AR: return address | 1478 // RA: return address |
1482 // S5: Inline cache data object. | 1479 // S5: Inline cache data object. |
1483 // S4: Arguments descriptor array. | 1480 // S4: Arguments descriptor array. |
1484 // Control flow: | 1481 // Control flow: |
1485 // - If receiver is null -> jump to IC miss. | 1482 // - If receiver is null -> jump to IC miss. |
1486 // - If receiver is Smi -> load Smi class. | 1483 // - If receiver is Smi -> load Smi class. |
1487 // - If receiver is not-Smi -> load receiver's class. | 1484 // - If receiver is not-Smi -> load receiver's class. |
1488 // - Check if 'num_args' (including receiver) match any IC data group. | 1485 // - Check if 'num_args' (including receiver) match any IC data group. |
1489 // - Match found -> jump to target. | 1486 // - Match found -> jump to target. |
1490 // - Match not found -> jump to IC miss. | 1487 // - Match not found -> jump to IC miss. |
1491 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1488 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2165 __ mov(TMP1, ZR); | 2162 __ mov(TMP1, ZR); |
2166 __ lw(T0, Address(SP, 0 * kWordSize)); | 2163 __ lw(T0, Address(SP, 0 * kWordSize)); |
2167 __ lw(T1, Address(SP, 1 * kWordSize)); | 2164 __ lw(T1, Address(SP, 1 * kWordSize)); |
2168 __ Ret(); | 2165 __ Ret(); |
2169 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); | 2166 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
2170 } | 2167 } |
2171 | 2168 |
2172 } // namespace dart | 2169 } // namespace dart |
2173 | 2170 |
2174 #endif // defined TARGET_ARCH_MIPS | 2171 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |