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 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1217 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1218 } | 1218 } |
1219 | 1219 |
1220 | 1220 |
1221 // Loads function into 'temp_reg'. | 1221 // Loads function into 'temp_reg'. |
1222 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, | 1222 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, |
1223 Register temp_reg) { | 1223 Register temp_reg) { |
1224 Register ic_reg = R5; | 1224 Register ic_reg = R5; |
1225 Register func_reg = temp_reg; | 1225 Register func_reg = temp_reg; |
1226 ASSERT(temp_reg == R6); | 1226 ASSERT(temp_reg == R6); |
1227 __ ldr(func_reg, FieldAddress(ic_reg, ICData::function_offset())); | 1227 __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset())); |
1228 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1228 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1229 __ add(R7, R7, ShifterOperand(1)); | 1229 __ add(R7, R7, ShifterOperand(1)); |
1230 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1230 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
1231 } | 1231 } |
1232 | 1232 |
1233 | 1233 |
1234 // Generate inline cache check for 'num_args'. | 1234 // Generate inline cache check for 'num_args'. |
1235 // LR: return address. | 1235 // LR: return address. |
1236 // R5: inline cache data object. | 1236 // R5: inline cache data object. |
1237 // Control flow: | 1237 // Control flow: |
1238 // - If receiver is null -> jump to IC miss. | 1238 // - If receiver is null -> jump to IC miss. |
1239 // - If receiver is Smi -> load Smi class. | 1239 // - If receiver is Smi -> load Smi class. |
1240 // - If receiver is not-Smi -> load receiver's class. | 1240 // - If receiver is not-Smi -> load receiver's class. |
1241 // - Check if 'num_args' (including receiver) match any IC data group. | 1241 // - Check if 'num_args' (including receiver) match any IC data group. |
1242 // - Match found -> jump to target. | 1242 // - Match found -> jump to target. |
1243 // - Match not found -> jump to IC miss. | 1243 // - Match not found -> jump to IC miss. |
1244 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1244 void StubCode::GenerateNArgsCheckInlineCacheStub( |
1245 Assembler* assembler, | 1245 Assembler* assembler, |
1246 intptr_t num_args, | 1246 intptr_t num_args, |
1247 const RuntimeEntry& handle_ic_miss) { | 1247 const RuntimeEntry& handle_ic_miss) { |
1248 ASSERT(num_args > 0); | 1248 ASSERT(num_args > 0); |
1249 #if defined(DEBUG) | 1249 #if defined(DEBUG) |
1250 { Label ok; | 1250 { Label ok; |
1251 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. | 1251 // Check that the IC data array has NumArgsTested() == num_args. |
1252 // 'num_args_tested' is stored as an untagged int. | 1252 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1253 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset())); | 1253 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); |
| 1254 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1255 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); |
1254 __ CompareImmediate(R6, num_args); | 1256 __ CompareImmediate(R6, num_args); |
1255 __ b(&ok, EQ); | 1257 __ b(&ok, EQ); |
1256 __ Stop("Incorrect stub for IC data"); | 1258 __ Stop("Incorrect stub for IC data"); |
1257 __ Bind(&ok); | 1259 __ Bind(&ok); |
1258 } | 1260 } |
1259 #endif // DEBUG | 1261 #endif // DEBUG |
1260 | 1262 |
1261 // Check single stepping. | 1263 // Check single stepping. |
1262 Label not_stepping; | 1264 Label not_stepping; |
1263 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1265 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 } | 1462 } |
1461 | 1463 |
1462 | 1464 |
1463 // Intermediary stub between a static call and its target. ICData contains | 1465 // Intermediary stub between a static call and its target. ICData contains |
1464 // the target function and the call count. | 1466 // the target function and the call count. |
1465 // R5: ICData | 1467 // R5: ICData |
1466 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1468 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
1467 GenerateUsageCounterIncrement(assembler, R6); | 1469 GenerateUsageCounterIncrement(assembler, R6); |
1468 #if defined(DEBUG) | 1470 #if defined(DEBUG) |
1469 { Label ok; | 1471 { Label ok; |
1470 // Check that the IC data array has NumberOfArgumentsChecked() == 0. | 1472 // Check that the IC data array has NumArgsTested() == 0. |
1471 // 'num_args_tested' is stored as an untagged int. | 1473 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1472 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset())); | 1474 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); |
| 1475 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1476 __ and_(R6, R6, ShifterOperand(ICData::NumArgsTestedMask())); |
1473 __ CompareImmediate(R6, 0); | 1477 __ CompareImmediate(R6, 0); |
1474 __ b(&ok, EQ); | 1478 __ b(&ok, EQ); |
1475 __ Stop("Incorrect IC data for unoptimized static call"); | 1479 __ Stop("Incorrect IC data for unoptimized static call"); |
1476 __ Bind(&ok); | 1480 __ Bind(&ok); |
1477 } | 1481 } |
1478 #endif // DEBUG | 1482 #endif // DEBUG |
1479 | 1483 |
1480 // Check single stepping. | 1484 // Check single stepping. |
1481 Label not_stepping; | 1485 Label not_stepping; |
1482 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1486 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 const Register right = R0; | 1852 const Register right = R0; |
1849 __ ldr(left, Address(SP, 1 * kWordSize)); | 1853 __ ldr(left, Address(SP, 1 * kWordSize)); |
1850 __ ldr(right, Address(SP, 0 * kWordSize)); | 1854 __ ldr(right, Address(SP, 0 * kWordSize)); |
1851 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1855 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1852 __ Ret(); | 1856 __ Ret(); |
1853 } | 1857 } |
1854 | 1858 |
1855 } // namespace dart | 1859 } // namespace dart |
1856 | 1860 |
1857 #endif // defined TARGET_ARCH_ARM | 1861 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |