| 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 __ Stop("GenerateOptimizedUsageCounterIncrement"); | 738 __ Stop("GenerateOptimizedUsageCounterIncrement"); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 // Loads function into 'temp_reg'. | 742 // Loads function into 'temp_reg'. |
| 743 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, | 743 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, |
| 744 Register temp_reg) { | 744 Register temp_reg) { |
| 745 Register ic_reg = R5; | 745 Register ic_reg = R5; |
| 746 Register func_reg = temp_reg; | 746 Register func_reg = temp_reg; |
| 747 ASSERT(temp_reg == R6); | 747 ASSERT(temp_reg == R6); |
| 748 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::function_offset()); | 748 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset()); |
| 749 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset()); | 749 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset()); |
| 750 __ AddImmediate(R7, R7, 1, PP); | 750 __ AddImmediate(R7, R7, 1, PP); |
| 751 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset()); | 751 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset()); |
| 752 } | 752 } |
| 753 | 753 |
| 754 | 754 |
| 755 // Generate inline cache check for 'num_args'. | 755 // Generate inline cache check for 'num_args'. |
| 756 // LR: return address. | 756 // LR: return address. |
| 757 // R5: inline cache data object. | 757 // R5: inline cache data object. |
| 758 // Control flow: | 758 // Control flow: |
| 759 // - If receiver is null -> jump to IC miss. | 759 // - If receiver is null -> jump to IC miss. |
| 760 // - If receiver is Smi -> load Smi class. | 760 // - If receiver is Smi -> load Smi class. |
| 761 // - If receiver is not-Smi -> load receiver's class. | 761 // - If receiver is not-Smi -> load receiver's class. |
| 762 // - Check if 'num_args' (including receiver) match any IC data group. | 762 // - Check if 'num_args' (including receiver) match any IC data group. |
| 763 // - Match found -> jump to target. | 763 // - Match found -> jump to target. |
| 764 // - Match not found -> jump to IC miss. | 764 // - Match not found -> jump to IC miss. |
| 765 void StubCode::GenerateNArgsCheckInlineCacheStub( | 765 void StubCode::GenerateNArgsCheckInlineCacheStub( |
| 766 Assembler* assembler, | 766 Assembler* assembler, |
| 767 intptr_t num_args, | 767 intptr_t num_args, |
| 768 const RuntimeEntry& handle_ic_miss) { | 768 const RuntimeEntry& handle_ic_miss) { |
| 769 ASSERT(num_args > 0); | 769 ASSERT(num_args > 0); |
| 770 #if defined(DEBUG) | 770 #if defined(DEBUG) |
| 771 { Label ok; | 771 { Label ok; |
| 772 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. | 772 // Check that the IC data array has NumArgsTested() == num_args. |
| 773 // 'num_args_tested' is stored as an untagged int. | 773 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 774 __ LoadFieldFromOffset(R6, R5, ICData::num_args_tested_offset()); | 774 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| 775 kUnsignedWord); |
| 776 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 777 __ andi(R6, R6, ICData::NumArgsTestedMask()); |
| 775 __ CompareImmediate(R6, num_args, PP); | 778 __ CompareImmediate(R6, num_args, PP); |
| 776 __ b(&ok, EQ); | 779 __ b(&ok, EQ); |
| 777 __ Stop("Incorrect stub for IC data"); | 780 __ Stop("Incorrect stub for IC data"); |
| 778 __ Bind(&ok); | 781 __ Bind(&ok); |
| 779 } | 782 } |
| 780 #endif // DEBUG | 783 #endif // DEBUG |
| 781 | 784 |
| 782 // Check single stepping. | 785 // Check single stepping. |
| 783 Label not_stepping; | 786 Label not_stepping; |
| 784 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset()); | 787 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset()); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 | 1006 |
| 1004 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1007 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
| 1005 __ Stop("GenerateMegamorphicCallStub"); | 1008 __ Stop("GenerateMegamorphicCallStub"); |
| 1006 } | 1009 } |
| 1007 | 1010 |
| 1008 | 1011 |
| 1009 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1012 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1010 GenerateUsageCounterIncrement(assembler, R6); | 1013 GenerateUsageCounterIncrement(assembler, R6); |
| 1011 #if defined(DEBUG) | 1014 #if defined(DEBUG) |
| 1012 { Label ok; | 1015 { Label ok; |
| 1013 // Check that the IC data array has NumberOfArgumentsChecked() == 0. | 1016 // Check that the IC data array has NumArgsTested() == 0. |
| 1014 // 'num_args_tested' is stored as an untagged int. | 1017 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1015 __ LoadFieldFromOffset(R6, R5, ICData::num_args_tested_offset()); | 1018 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| 1019 kUnsignedWord); |
| 1020 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1021 __ andi(R6, R6, ICData::NumArgsTestedMask()); |
| 1016 __ CompareImmediate(R6, 0, PP); | 1022 __ CompareImmediate(R6, 0, PP); |
| 1017 __ b(&ok, EQ); | 1023 __ b(&ok, EQ); |
| 1018 __ Stop("Incorrect IC data for unoptimized static call"); | 1024 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1019 __ Bind(&ok); | 1025 __ Bind(&ok); |
| 1020 } | 1026 } |
| 1021 #endif // DEBUG | 1027 #endif // DEBUG |
| 1022 | 1028 |
| 1023 // Check single stepping. | 1029 // Check single stepping. |
| 1024 Label not_stepping; | 1030 Label not_stepping; |
| 1025 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset()); | 1031 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset()); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 | 1246 |
| 1241 | 1247 |
| 1242 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( | 1248 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( |
| 1243 Assembler* assembler) { | 1249 Assembler* assembler) { |
| 1244 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); | 1250 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); |
| 1245 } | 1251 } |
| 1246 | 1252 |
| 1247 } // namespace dart | 1253 } // namespace dart |
| 1248 | 1254 |
| 1249 #endif // defined TARGET_ARCH_ARM64 | 1255 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |