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 |