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/cpu.h" | 10 #include "vm/cpu.h" |
11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/flow_graph_compiler.h" | 13 #include "vm/flow_graph_compiler.h" |
14 #include "vm/heap.h" | 14 #include "vm/heap.h" |
15 #include "vm/instructions.h" | 15 #include "vm/instructions.h" |
16 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
18 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
19 #include "vm/tags.h" | 19 #include "vm/tags.h" |
20 | 20 |
21 #define __ assembler-> | 21 #define __ assembler-> |
22 | 22 |
23 namespace dart { | 23 namespace dart { |
24 | 24 |
25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); | 25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); |
26 DEFINE_FLAG(bool, use_slow_path, false, | 26 DEFINE_FLAG(bool, use_slow_path, false, |
27 "Set to true for debugging & verifying the slow paths."); | 27 "Set to true for debugging & verifying the slow paths."); |
28 DECLARE_FLAG(bool, trace_optimized_ic_calls); | 28 DECLARE_FLAG(bool, trace_optimized_ic_calls); |
29 | 29 |
30 DECLARE_FLAG(bool, enable_debugger); | |
30 | 31 |
31 // Input parameters: | 32 // Input parameters: |
32 // LR : return address. | 33 // LR : return address. |
33 // SP : address of last argument in argument array. | 34 // SP : address of last argument in argument array. |
34 // SP + 4*R4 - 4 : address of first argument in argument array. | 35 // SP + 4*R4 - 4 : address of first argument in argument array. |
35 // SP + 4*R4 : address of return value. | 36 // SP + 4*R4 : address of return value. |
36 // R5 : address of the runtime function to call. | 37 // R5 : address of the runtime function to call. |
37 // R4 : number of arguments to the call. | 38 // R4 : number of arguments to the call. |
38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 39 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
39 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 40 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1261 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); | 1262 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); |
1262 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1263 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
1263 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); | 1264 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); |
1264 __ CompareImmediate(R6, num_args); | 1265 __ CompareImmediate(R6, num_args); |
1265 __ b(&ok, EQ); | 1266 __ b(&ok, EQ); |
1266 __ Stop("Incorrect stub for IC data"); | 1267 __ Stop("Incorrect stub for IC data"); |
1267 __ Bind(&ok); | 1268 __ Bind(&ok); |
1268 } | 1269 } |
1269 #endif // DEBUG | 1270 #endif // DEBUG |
1270 | 1271 |
1271 // Check single stepping. | 1272 if (FLAG_enable_debugger) { |
1272 Label not_stepping; | 1273 // Check single stepping. |
1273 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1274 Label not_stepping; |
1274 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1275 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
1275 __ CompareImmediate(R6, 0); | 1276 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1276 __ b(¬_stepping, EQ); | 1277 __ CompareImmediate(R6, 0); |
1277 __ EnterStubFrame(); | 1278 __ b(¬_stepping, EQ); |
1278 __ Push(R5); // Preserve IC data. | 1279 __ EnterStubFrame(); |
1279 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1280 __ Push(R5); // Preserve IC data. |
1280 __ Pop(R5); | 1281 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1281 __ LeaveStubFrame(); | 1282 __ Pop(R5); |
1282 __ Bind(¬_stepping); | 1283 __ LeaveStubFrame(); |
1284 __ Bind(¬_stepping); | |
1285 } | |
1283 | 1286 |
1284 // Load arguments descriptor into R4. | 1287 // Load arguments descriptor into R4. |
1285 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1288 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
1286 // Preserve return address, since LR is needed for subroutine call. | 1289 // Preserve return address, since LR is needed for subroutine call. |
1287 __ mov(R8, ShifterOperand(LR)); | 1290 __ mov(R8, ShifterOperand(LR)); |
1288 // Loop that checks if there is an IC data match. | 1291 // Loop that checks if there is an IC data match. |
1289 Label loop, update, test, found, get_class_id_as_smi; | 1292 Label loop, update, test, found, get_class_id_as_smi; |
1290 // R5: IC data object (preserved). | 1293 // R5: IC data object (preserved). |
1291 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); | 1294 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); |
1292 // R6: ic_data_array with check entries: classes and target functions. | 1295 // R6: ic_data_array with check entries: classes and target functions. |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1477 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1480 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
1478 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); | 1481 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); |
1479 __ CompareImmediate(R6, 0); | 1482 __ CompareImmediate(R6, 0); |
1480 __ b(&ok, EQ); | 1483 __ b(&ok, EQ); |
1481 __ Stop("Incorrect IC data for unoptimized static call"); | 1484 __ Stop("Incorrect IC data for unoptimized static call"); |
1482 __ Bind(&ok); | 1485 __ Bind(&ok); |
1483 } | 1486 } |
1484 #endif // DEBUG | 1487 #endif // DEBUG |
1485 | 1488 |
1486 // Check single stepping. | 1489 // Check single stepping. |
1487 Label not_stepping; | 1490 Label not_stepping; |
hausner
2014/05/22 23:28:08
Check the runtime flag here too?
| |
1488 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1491 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
1489 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1492 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1490 __ CompareImmediate(R6, 0); | 1493 __ CompareImmediate(R6, 0); |
1491 __ b(¬_stepping, EQ); | 1494 __ b(¬_stepping, EQ); |
1492 __ EnterStubFrame(); | 1495 __ EnterStubFrame(); |
1493 __ Push(R5); // Preserve IC data. | 1496 __ Push(R5); // Preserve IC data. |
1494 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1497 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1495 __ Pop(R5); | 1498 __ Pop(R5); |
1496 __ LeaveStubFrame(); | 1499 __ LeaveStubFrame(); |
1497 __ Bind(¬_stepping); | 1500 __ Bind(¬_stepping); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1566 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); | 1569 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); |
1567 __ LeaveStubFrame(); | 1570 __ LeaveStubFrame(); |
1568 __ bx(R0); | 1571 __ bx(R0); |
1569 } | 1572 } |
1570 | 1573 |
1571 | 1574 |
1572 // Called only from unoptimized code. All relevant registers have been saved. | 1575 // Called only from unoptimized code. All relevant registers have been saved. |
1573 void StubCode::GenerateDebugStepCheckStub( | 1576 void StubCode::GenerateDebugStepCheckStub( |
1574 Assembler* assembler) { | 1577 Assembler* assembler) { |
1575 // Check single stepping. | 1578 // Check single stepping. |
1576 Label not_stepping; | 1579 Label not_stepping; |
hausner
2014/05/22 23:28:08
ditto
srdjan
2014/05/22 23:38:27
Done.
| |
1577 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); | 1580 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); |
1578 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); | 1581 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); |
1579 __ CompareImmediate(R1, 0); | 1582 __ CompareImmediate(R1, 0); |
1580 __ b(¬_stepping, EQ); | 1583 __ b(¬_stepping, EQ); |
1581 __ EnterStubFrame(); | 1584 __ EnterStubFrame(); |
1582 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1585 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1583 __ LeaveStubFrame(); | 1586 __ LeaveStubFrame(); |
1584 __ Bind(¬_stepping); | 1587 __ Bind(¬_stepping); |
1585 __ Ret(); | 1588 __ Ret(); |
1586 } | 1589 } |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1815 | 1818 |
1816 | 1819 |
1817 // Called only from unoptimized code. All relevant registers have been saved. | 1820 // Called only from unoptimized code. All relevant registers have been saved. |
1818 // LR: return address. | 1821 // LR: return address. |
1819 // SP + 4: left operand. | 1822 // SP + 4: left operand. |
1820 // SP + 0: right operand. | 1823 // SP + 0: right operand. |
1821 // Return Zero condition flag set if equal. | 1824 // Return Zero condition flag set if equal. |
1822 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 1825 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
1823 Assembler* assembler) { | 1826 Assembler* assembler) { |
1824 // Check single stepping. | 1827 // Check single stepping. |
1825 Label not_stepping; | 1828 Label not_stepping; |
hausner
2014/05/22 23:28:08
ditto
srdjan
2014/05/22 23:38:27
Done.
| |
1826 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); | 1829 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); |
1827 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); | 1830 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); |
1828 __ CompareImmediate(R1, 0); | 1831 __ CompareImmediate(R1, 0); |
1829 __ b(¬_stepping, EQ); | 1832 __ b(¬_stepping, EQ); |
1830 __ EnterStubFrame(); | 1833 __ EnterStubFrame(); |
1831 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1834 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1832 __ LeaveStubFrame(); | 1835 __ LeaveStubFrame(); |
1833 __ Bind(¬_stepping); | 1836 __ Bind(¬_stepping); |
1834 | 1837 |
1835 const Register temp = R2; | 1838 const Register temp = R2; |
(...skipping 18 matching lines...) Expand all Loading... | |
1854 const Register right = R0; | 1857 const Register right = R0; |
1855 __ ldr(left, Address(SP, 1 * kWordSize)); | 1858 __ ldr(left, Address(SP, 1 * kWordSize)); |
1856 __ ldr(right, Address(SP, 0 * kWordSize)); | 1859 __ ldr(right, Address(SP, 0 * kWordSize)); |
1857 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1860 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1858 __ Ret(); | 1861 __ Ret(); |
1859 } | 1862 } |
1860 | 1863 |
1861 } // namespace dart | 1864 } // namespace dart |
1862 | 1865 |
1863 #endif // defined TARGET_ARCH_ARM | 1866 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |