| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 __ Push(R6); // Preserve. | 1285 __ Push(R6); // Preserve. |
| 1286 __ Push(R5); // Preserve. | 1286 __ Push(R5); // Preserve. |
| 1287 __ Push(ic_reg); // Argument. | 1287 __ Push(ic_reg); // Argument. |
| 1288 __ Push(func_reg); // Argument. | 1288 __ Push(func_reg); // Argument. |
| 1289 __ CallRuntime(kTraceICCallRuntimeEntry, 2); | 1289 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
| 1290 __ Drop(2); // Discard argument; | 1290 __ Drop(2); // Discard argument; |
| 1291 __ Pop(R5); // Restore. | 1291 __ Pop(R5); // Restore. |
| 1292 __ Pop(R6); // Restore. | 1292 __ Pop(R6); // Restore. |
| 1293 __ LeaveStubFrame(); | 1293 __ LeaveStubFrame(); |
| 1294 } | 1294 } |
| 1295 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(), kNoPP); | 1295 __ LoadFieldFromOffset( |
| 1296 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); |
| 1296 __ add(R7, R7, Operand(1)); | 1297 __ add(R7, R7, Operand(1)); |
| 1297 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(), kNoPP); | 1298 __ StoreFieldToOffset( |
| 1299 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); |
| 1298 } | 1300 } |
| 1299 | 1301 |
| 1300 | 1302 |
| 1301 // Loads function into 'temp_reg'. | 1303 // Loads function into 'temp_reg'. |
| 1302 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, | 1304 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, |
| 1303 Register temp_reg) { | 1305 Register temp_reg) { |
| 1304 Register ic_reg = R5; | 1306 Register ic_reg = R5; |
| 1305 Register func_reg = temp_reg; | 1307 Register func_reg = temp_reg; |
| 1306 ASSERT(temp_reg == R6); | 1308 ASSERT(temp_reg == R6); |
| 1307 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset(), kNoPP); | 1309 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset(), kNoPP); |
| 1308 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(), kNoPP); | 1310 __ LoadFieldFromOffset( |
| 1311 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); |
| 1309 __ AddImmediate(R7, R7, 1, kNoPP); | 1312 __ AddImmediate(R7, R7, 1, kNoPP); |
| 1310 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(), kNoPP); | 1313 __ StoreFieldToOffset( |
| 1314 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); |
| 1311 } | 1315 } |
| 1312 | 1316 |
| 1313 | 1317 |
| 1314 // Generate inline cache check for 'num_args'. | 1318 // Generate inline cache check for 'num_args'. |
| 1315 // LR: return address. | 1319 // LR: return address. |
| 1316 // R5: inline cache data object. | 1320 // R5: inline cache data object. |
| 1317 // Control flow: | 1321 // Control flow: |
| 1318 // - If receiver is null -> jump to IC miss. | 1322 // - If receiver is null -> jump to IC miss. |
| 1319 // - If receiver is Smi -> load Smi class. | 1323 // - If receiver is Smi -> load Smi class. |
| 1320 // - If receiver is not-Smi -> load receiver's class. | 1324 // - If receiver is not-Smi -> load receiver's class. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 __ Push(R5); // Preserve IC data. | 1357 __ Push(R5); // Preserve IC data. |
| 1354 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1358 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1355 __ Pop(R5); | 1359 __ Pop(R5); |
| 1356 __ LeaveStubFrame(); | 1360 __ LeaveStubFrame(); |
| 1357 __ Bind(¬_stepping); | 1361 __ Bind(¬_stepping); |
| 1358 } | 1362 } |
| 1359 | 1363 |
| 1360 // Load arguments descriptor into R4. | 1364 // Load arguments descriptor into R4. |
| 1361 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP); | 1365 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP); |
| 1362 // Loop that checks if there is an IC data match. | 1366 // Loop that checks if there is an IC data match. |
| 1363 Label loop, update, test, found, get_class_id_as_smi; | 1367 Label loop, update, test, found; |
| 1364 // R5: IC data object (preserved). | 1368 // R5: IC data object (preserved). |
| 1365 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); | 1369 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); |
| 1366 // R6: ic_data_array with check entries: classes and target functions. | 1370 // R6: ic_data_array with check entries: classes and target functions. |
| 1367 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); | 1371 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); |
| 1368 // R6: points directly to the first ic data array element. | 1372 // R6: points directly to the first ic data array element. |
| 1369 | 1373 |
| 1370 // Get the receiver's class ID (first read number of arguments from | 1374 // Get the receiver's class ID (first read number of arguments from |
| 1371 // arguments descriptor array and then access the receiver from the stack). | 1375 // arguments descriptor array and then access the receiver from the stack). |
| 1372 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset(), kNoPP); | 1376 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset(), kNoPP); |
| 1373 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode. | 1377 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode. |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 // R2: cache array. | 1674 // R2: cache array. |
| 1671 // Result in R1: null -> not found, otherwise result (true or false). | 1675 // Result in R1: null -> not found, otherwise result (true or false). |
| 1672 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1676 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
| 1673 ASSERT((1 <= n) && (n <= 3)); | 1677 ASSERT((1 <= n) && (n <= 3)); |
| 1674 if (n > 1) { | 1678 if (n > 1) { |
| 1675 // Get instance type arguments. | 1679 // Get instance type arguments. |
| 1676 __ LoadClass(R3, R0, kNoPP); | 1680 __ LoadClass(R3, R0, kNoPP); |
| 1677 // Compute instance type arguments into R4. | 1681 // Compute instance type arguments into R4. |
| 1678 Label has_no_type_arguments; | 1682 Label has_no_type_arguments; |
| 1679 __ LoadObject(R4, Object::null_object(), PP); | 1683 __ LoadObject(R4, Object::null_object(), PP); |
| 1680 __ LoadFieldFromOffset( | 1684 __ LoadFieldFromOffset(R5, R3, |
| 1681 R5, R3, Class::type_arguments_field_offset_in_words_offset(), kNoPP); | 1685 Class::type_arguments_field_offset_in_words_offset(), kNoPP, kWord); |
| 1682 __ CompareImmediate(R5, Class::kNoTypeArguments, kNoPP); | 1686 __ CompareImmediate(R5, Class::kNoTypeArguments, kNoPP); |
| 1683 __ b(&has_no_type_arguments, EQ); | 1687 __ b(&has_no_type_arguments, EQ); |
| 1684 __ add(R5, R0, Operand(R5, LSL, 3)); | 1688 __ add(R5, R0, Operand(R5, LSL, 3)); |
| 1685 __ LoadFieldFromOffset(R4, R5, 0, kNoPP); | 1689 __ LoadFieldFromOffset(R4, R5, 0, kNoPP); |
| 1686 __ Bind(&has_no_type_arguments); | 1690 __ Bind(&has_no_type_arguments); |
| 1687 } | 1691 } |
| 1688 __ LoadClassId(R3, R0, kNoPP); | 1692 __ LoadClassId(R3, R0, kNoPP); |
| 1689 // R0: instance. | 1693 // R0: instance. |
| 1690 // R1: instantiator type arguments or NULL. | 1694 // R1: instantiator type arguments or NULL. |
| 1691 // R2: SubtypeTestCache. | 1695 // R2: SubtypeTestCache. |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1925 const Register right = R0; | 1929 const Register right = R0; |
| 1926 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 1930 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
| 1927 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); | 1931 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); |
| 1928 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1932 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1929 __ ret(); | 1933 __ ret(); |
| 1930 } | 1934 } |
| 1931 | 1935 |
| 1932 } // namespace dart | 1936 } // namespace dart |
| 1933 | 1937 |
| 1934 #endif // defined TARGET_ARCH_ARM64 | 1938 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |