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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 __ mov(CTX, ShifterOperand(R2)); | 191 __ mov(CTX, ShifterOperand(R2)); |
192 | 192 |
193 __ LeaveFrame((1 << FP) | (1 << LR)); | 193 __ LeaveFrame((1 << FP) | (1 << LR)); |
194 __ Ret(); | 194 __ Ret(); |
195 } | 195 } |
196 | 196 |
197 | 197 |
198 // Input parameters: | 198 // Input parameters: |
199 // R4: arguments descriptor array. | 199 // R4: arguments descriptor array. |
200 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 200 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 201 // Create a stub frame as we are pushing some objects on the stack before |
| 202 // calling into the runtime. |
201 __ EnterStubFrame(); | 203 __ EnterStubFrame(); |
202 // Setup space on stack for return value and preserve arguments descriptor. | 204 // Setup space on stack for return value and preserve arguments descriptor. |
203 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 205 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
204 __ PushList((1 << R0) | (1 << R4)); | 206 __ PushList((1 << R0) | (1 << R4)); |
205 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 207 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
206 // Get Code object result and restore arguments descriptor array. | 208 // Get Code object result and restore arguments descriptor array. |
207 __ PopList((1 << R0) | (1 << R4)); | 209 __ PopList((1 << R0) | (1 << R4)); |
208 // Remove the stub frame as we are about to jump to the dart function. | 210 // Remove the stub frame. |
209 __ LeaveStubFrame(); | 211 __ LeaveStubFrame(); |
210 | 212 // Jump to the dart function. |
211 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 213 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
212 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 214 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
213 __ bx(R0); | 215 __ bx(R0); |
214 } | 216 } |
215 | 217 |
216 | 218 |
| 219 // Called from a static call only when an invalid code has been entered |
| 220 // (invalid because its function was optimized or deoptimized). |
| 221 // R4: arguments descriptor array. |
217 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 222 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
218 __ Unimplemented("FixCallersTarget stub"); | 223 // Create a stub frame as we are pushing some objects on the stack before |
| 224 // calling into the runtime. |
| 225 __ EnterStubFrame(); |
| 226 // Setup space on stack for return value and preserve arguments descriptor. |
| 227 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 228 __ PushList((1 << R0) | (1 << R4)); |
| 229 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
| 230 // Get Code object result and restore arguments descriptor array. |
| 231 __ PopList((1 << R0) | (1 << R4)); |
| 232 // Remove the stub frame. |
| 233 __ LeaveStubFrame(); |
| 234 // Jump to the dart function. |
| 235 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 236 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 237 __ bx(R0); |
219 } | 238 } |
220 | 239 |
221 | 240 |
222 // Input parameters: | 241 // Input parameters: |
223 // R2: smi-tagged argument count, may be zero. | 242 // R2: smi-tagged argument count, may be zero. |
224 // FP[kLastParamSlotIndex]: last argument. | 243 // FP[kLastParamSlotIndex]: last argument. |
225 static void PushArgumentsArray(Assembler* assembler) { | 244 static void PushArgumentsArray(Assembler* assembler) { |
226 // Allocate array to store arguments of caller. | 245 // Allocate array to store arguments of caller. |
227 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); | 246 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); |
228 // R1: null element type for raw Array. | 247 // R1: null element type for raw Array. |
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { | 1397 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { |
1379 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1398 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1380 } | 1399 } |
1381 | 1400 |
1382 | 1401 |
1383 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1402 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
1384 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1403 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1385 } | 1404 } |
1386 | 1405 |
1387 | 1406 |
| 1407 // LR: return address (Dart code). |
| 1408 // R4: Arguments descriptor array. |
1388 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1409 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1389 __ Unimplemented("BreakpointStatic stub"); | 1410 // Create a stub frame as we are pushing some objects on the stack before |
| 1411 // calling into the runtime. |
| 1412 __ EnterStubFrame(); |
| 1413 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 1414 // // Preserve arguments descriptor and make room for result. |
| 1415 __ PushList((1 << R0) | (1 << R4)); |
| 1416 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1417 // Pop code object result and restore arguments descriptor. |
| 1418 __ PopList((1 << R0) | (1 << R4)); |
| 1419 __ LeaveStubFrame(); |
| 1420 |
| 1421 // Now call the static function. The breakpoint handler function |
| 1422 // ensures that the call target is compiled. |
| 1423 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 1424 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 1425 __ bx(R0); |
1390 } | 1426 } |
1391 | 1427 |
1392 | 1428 |
| 1429 // R0: return value. |
1393 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1430 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1394 __ Unimplemented("BreakpointReturn stub"); | 1431 // Create a stub frame as we are pushing some objects on the stack before |
| 1432 // calling into the runtime. |
| 1433 __ EnterStubFrame(); |
| 1434 __ Push(R0); |
| 1435 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
| 1436 __ Pop(R0); |
| 1437 __ LeaveStubFrame(); |
| 1438 |
| 1439 // Instead of returning to the patched Dart function, emulate the |
| 1440 // smashed return code pattern and return to the function's caller. |
| 1441 __ LeaveDartFrame(); |
| 1442 __ Ret(); |
1395 } | 1443 } |
1396 | 1444 |
1397 | 1445 |
| 1446 // LR: return address (Dart code). |
| 1447 // R5: Inline cache data array. |
| 1448 // R4: Arguments descriptor array. |
1398 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1449 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1399 __ Unimplemented("BreakpointDynamic stub"); | 1450 // Create a stub frame as we are pushing some objects on the stack before |
| 1451 // calling into the runtime. |
| 1452 __ EnterStubFrame(); |
| 1453 __ PushList((1 << R4) | (1 << R5)); |
| 1454 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
| 1455 __ PopList((1 << R4) | (1 << R5)); |
| 1456 __ LeaveStubFrame(); |
| 1457 |
| 1458 // Find out which dispatch stub to call. |
| 1459 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); |
| 1460 __ cmp(IP, ShifterOperand(1)); |
| 1461 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); |
| 1462 __ cmp(IP, ShifterOperand(2)); |
| 1463 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); |
| 1464 __ cmp(IP, ShifterOperand(3)); |
| 1465 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel(), EQ); |
| 1466 __ Stop("Unsupported number of arguments tested."); |
1400 } | 1467 } |
1401 | 1468 |
1402 | 1469 |
1403 // Used to check class and type arguments. Arguments passed in registers: | 1470 // Used to check class and type arguments. Arguments passed in registers: |
1404 // LR: return address. | 1471 // LR: return address. |
1405 // R0: instance (must be preserved). | 1472 // R0: instance (must be preserved). |
1406 // R1: instantiator type arguments or NULL. | 1473 // R1: instantiator type arguments or NULL. |
1407 // R2: cache array. | 1474 // R2: cache array. |
1408 // Result in R1: null -> not found, otherwise result (true or false). | 1475 // Result in R1: null -> not found, otherwise result (true or false). |
1409 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1476 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1721 __ Bind(&reference_compare); | 1788 __ Bind(&reference_compare); |
1722 __ cmp(left, ShifterOperand(right)); | 1789 __ cmp(left, ShifterOperand(right)); |
1723 __ Bind(&done); | 1790 __ Bind(&done); |
1724 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | 1791 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); |
1725 __ Ret(); | 1792 __ Ret(); |
1726 } | 1793 } |
1727 | 1794 |
1728 } // namespace dart | 1795 } // namespace dart |
1729 | 1796 |
1730 #endif // defined TARGET_ARCH_ARM | 1797 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |