OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
10 | 10 |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
828 uint32_t** pc, | 828 uint32_t** pc, |
829 RawObject*** FP, | 829 RawObject*** FP, |
830 RawObject*** SP, | 830 RawObject*** SP, |
831 bool optimized) { | 831 bool optimized) { |
832 ASSERT(icdata->GetClassId() == kICDataCid); | 832 ASSERT(icdata->GetClassId() == kICDataCid); |
833 | 833 |
834 const intptr_t kCheckedArgs = 1; | 834 const intptr_t kCheckedArgs = 1; |
835 RawObject** args = call_base; | 835 RawObject** args = call_base; |
836 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 836 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
837 | 837 |
838 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 838 const intptr_t type_args_len = Smi::Value(*reinterpret_cast<RawSmi**>( |
839 reinterpret_cast<uword>(icdata->ptr()->args_descriptor_->ptr()) + | |
840 Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex))); | |
841 const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; | |
842 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx]); | |
839 | 843 |
840 bool found = false; | 844 bool found = false; |
841 const intptr_t length = Smi::Value(cache->length_); | 845 const intptr_t length = Smi::Value(cache->length_); |
842 intptr_t i; | 846 intptr_t i; |
843 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 847 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
844 if (cache->data()[i + 0] == receiver_cid) { | 848 if (cache->data()[i + 0] == receiver_cid) { |
845 top[0] = cache->data()[i + kCheckedArgs]; | 849 top[0] = cache->data()[i + kCheckedArgs]; |
846 found = true; | 850 found = true; |
847 break; | 851 break; |
848 } | 852 } |
849 } | 853 } |
850 | 854 |
851 if (found) { | 855 if (found) { |
852 if (!optimized) { | 856 if (!optimized) { |
853 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 857 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
854 } | 858 } |
855 } else { | 859 } else { |
856 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 860 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top, |
857 *SP); | 861 *pc, *FP, *SP); |
858 } | 862 } |
859 | 863 |
860 *argdesc = icdata->ptr()->args_descriptor_; | 864 *argdesc = icdata->ptr()->args_descriptor_; |
861 Invoke(thread, call_base, top, pp, pc, FP, SP); | 865 Invoke(thread, call_base, top, pp, pc, FP, SP); |
862 } | 866 } |
863 | 867 |
864 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 868 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
865 RawICData* icdata, | 869 RawICData* icdata, |
866 RawObject** call_base, | 870 RawObject** call_base, |
867 RawObject** top, | 871 RawObject** top, |
868 RawArray** argdesc, | 872 RawArray** argdesc, |
869 RawObjectPool** pp, | 873 RawObjectPool** pp, |
870 uint32_t** pc, | 874 uint32_t** pc, |
871 RawObject*** FP, | 875 RawObject*** FP, |
872 RawObject*** SP, | 876 RawObject*** SP, |
873 bool optimized) { | 877 bool optimized) { |
874 ASSERT(icdata->GetClassId() == kICDataCid); | 878 ASSERT(icdata->GetClassId() == kICDataCid); |
875 | 879 |
876 const intptr_t kCheckedArgs = 2; | 880 const intptr_t kCheckedArgs = 2; |
877 RawObject** args = call_base; | 881 RawObject** args = call_base; |
878 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 882 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
879 | 883 |
880 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 884 const intptr_t type_args_len = Smi::Value(*reinterpret_cast<RawSmi**>( |
zra
2017/08/08 17:47:18
Maybe pull the type_args_len calculation out into
regis
2017/08/08 22:58:28
Done.
| |
881 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 885 reinterpret_cast<uword>(icdata->ptr()->args_descriptor_->ptr()) + |
886 Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex))); | |
887 const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; | |
888 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx]); | |
889 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx + 1]); | |
882 | 890 |
883 bool found = false; | 891 bool found = false; |
884 const intptr_t length = Smi::Value(cache->length_); | 892 const intptr_t length = Smi::Value(cache->length_); |
885 intptr_t i; | 893 intptr_t i; |
886 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 894 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
887 if ((cache->data()[i + 0] == receiver_cid) && | 895 if ((cache->data()[i + 0] == receiver_cid) && |
888 (cache->data()[i + 1] == arg0_cid)) { | 896 (cache->data()[i + 1] == arg0_cid)) { |
889 top[0] = cache->data()[i + kCheckedArgs]; | 897 top[0] = cache->data()[i + kCheckedArgs]; |
890 found = true; | 898 found = true; |
891 break; | 899 break; |
892 } | 900 } |
893 } | 901 } |
894 | 902 |
895 if (found) { | 903 if (found) { |
896 if (!optimized) { | 904 if (!optimized) { |
897 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 905 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
898 } | 906 } |
899 } else { | 907 } else { |
900 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 908 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top, |
901 *SP); | 909 *pc, *FP, *SP); |
902 } | 910 } |
903 | 911 |
904 *argdesc = icdata->ptr()->args_descriptor_; | 912 *argdesc = icdata->ptr()->args_descriptor_; |
905 Invoke(thread, call_base, top, pp, pc, FP, SP); | 913 Invoke(thread, call_base, top, pp, pc, FP, SP); |
906 } | 914 } |
907 | 915 |
908 // Note: functions below are marked DART_NOINLINE to recover performance on | 916 // Note: functions below are marked DART_NOINLINE to recover performance on |
909 // ARM where inlining these functions into the interpreter loop seemed to cause | 917 // ARM where inlining these functions into the interpreter loop seemed to cause |
910 // some code quality issues. | 918 // some code quality issues. |
911 static DART_NOINLINE bool InvokeRuntime(Thread* thread, | 919 static DART_NOINLINE bool InvokeRuntime(Thread* thread, |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1254 fp_[1 + i] = arguments.At(i); | 1262 fp_[1 + i] = arguments.At(i); |
1255 } | 1263 } |
1256 | 1264 |
1257 FP[kFunctionSlotFromFp] = code.function(); | 1265 FP[kFunctionSlotFromFp] = code.function(); |
1258 FP[kPcMarkerSlotFromFp] = code.raw(); | 1266 FP[kPcMarkerSlotFromFp] = code.raw(); |
1259 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); | 1267 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); |
1260 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); | 1268 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); |
1261 | 1269 |
1262 // Load argument descriptor. | 1270 // Load argument descriptor. |
1263 argdesc = arguments_descriptor.raw(); | 1271 argdesc = arguments_descriptor.raw(); |
1272 ASSERT(ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() == 0); | |
1264 | 1273 |
1265 // Ready to start executing bytecode. Load entry point and corresponding | 1274 // Ready to start executing bytecode. Load entry point and corresponding |
1266 // object pool. | 1275 // object pool. |
1267 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); | 1276 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); |
1268 pc_ = reinterpret_cast<uword>(pc); // For the profiler. | 1277 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
1269 pp = code.object_pool()->ptr(); | 1278 pp = code.object_pool()->ptr(); |
1270 | 1279 |
1271 // Cache some frequently used values in the frame. | 1280 // Cache some frequently used values in the frame. |
1272 RawBool* true_value = Bool::True().raw(); | 1281 RawBool* true_value = Bool::True().raw(); |
1273 RawBool* false_value = Bool::False().raw(); | 1282 RawBool* false_value = Bool::False().raw(); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1425 ASSERT(num_opt_pos_params != 0); | 1434 ASSERT(num_opt_pos_params != 0); |
1426 if (named_count != 0) { | 1435 if (named_count != 0) { |
1427 // Function can't have both named and optional positional parameters. | 1436 // Function can't have both named and optional positional parameters. |
1428 // This kind of mismatch can only occur if the current function | 1437 // This kind of mismatch can only occur if the current function |
1429 // is a closure. | 1438 // is a closure. |
1430 goto ClosureNoSuchMethod; | 1439 goto ClosureNoSuchMethod; |
1431 } | 1440 } |
1432 | 1441 |
1433 // Process the list of default values encoded as a sequence of | 1442 // Process the list of default values encoded as a sequence of |
1434 // LoadConstant instructions after EntryOpt bytecode. | 1443 // LoadConstant instructions after EntryOpt bytecode. |
1435 // Execute only those that correspond to parameters the were not passed. | 1444 // Execute only those that correspond to parameters that were not passed. |
1436 for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params; | 1445 for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params; |
1437 i++) { | 1446 i++) { |
1438 const uint32_t load_value = pc[i]; | 1447 const uint32_t load_value = pc[i]; |
1439 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); | 1448 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); |
1440 #if defined(DEBUG) | 1449 #if defined(DEBUG) |
1441 const uint8_t reg = Bytecode::DecodeA(load_value); | 1450 const uint8_t reg = Bytecode::DecodeA(load_value); |
1442 ASSERT((num_fixed_params + i) == reg); | 1451 ASSERT((num_fixed_params + i) == reg); |
1443 #endif | 1452 #endif |
1444 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); | 1453 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); |
1445 } | 1454 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1547 BYTECODE(CheckStackAlwaysExit, A); | 1556 BYTECODE(CheckStackAlwaysExit, A); |
1548 { | 1557 { |
1549 Exit(thread, FP, SP + 1, pc); | 1558 Exit(thread, FP, SP + 1, pc); |
1550 NativeArguments args(thread, 0, NULL, NULL); | 1559 NativeArguments args(thread, 0, NULL, NULL); |
1551 INVOKE_RUNTIME(DRT_StackOverflow, args); | 1560 INVOKE_RUNTIME(DRT_StackOverflow, args); |
1552 } | 1561 } |
1553 DISPATCH(); | 1562 DISPATCH(); |
1554 } | 1563 } |
1555 | 1564 |
1556 { | 1565 { |
1566 BYTECODE(CheckFunctionTypeArgs, A_D); | |
1567 const uint16_t declared_type_args_len = rA; | |
1568 const uint16_t first_stack_local_index = rD; | |
1569 | |
1570 // Decode arguments descriptor's type args len. | |
1571 const intptr_t type_args_len = Smi::Value(*reinterpret_cast<RawSmi**>( | |
1572 reinterpret_cast<uword>(argdesc->ptr()) + | |
1573 Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex))); | |
1574 if (type_args_len > 0) { | |
1575 // Decode arguments descriptor's argument count (excluding type args). | |
1576 const intptr_t arg_count = Smi::Value(*reinterpret_cast<RawSmi**>( | |
1577 reinterpret_cast<uword>(argdesc->ptr()) + | |
1578 Array::element_offset(ArgumentsDescriptor::kCountIndex))); | |
1579 // Copy passed-in type args to first local slot. | |
1580 FP[first_stack_local_index] = *FrameArguments(FP, arg_count + 1); | |
1581 } else { | |
1582 FP[first_stack_local_index] = Object::null(); | |
1583 } | |
1584 | |
1585 // TODO(regis): Verify that type_args_len is correct. | |
1586 USE(declared_type_args_len); | |
1587 | |
1588 DISPATCH(); | |
1589 } | |
1590 | |
1591 { | |
1557 BYTECODE(DebugStep, A); | 1592 BYTECODE(DebugStep, A); |
1558 if (thread->isolate()->single_step()) { | 1593 if (thread->isolate()->single_step()) { |
1559 Exit(thread, FP, SP + 1, pc); | 1594 Exit(thread, FP, SP + 1, pc); |
1560 NativeArguments args(thread, 0, NULL, NULL); | 1595 NativeArguments args(thread, 0, NULL, NULL); |
1561 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1596 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1562 } | 1597 } |
1563 DISPATCH(); | 1598 DISPATCH(); |
1564 } | 1599 } |
1565 | 1600 |
1566 { | 1601 { |
(...skipping 2340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3907 pc_ = pc; | 3942 pc_ = pc; |
3908 } | 3943 } |
3909 | 3944 |
3910 buf->Longjmp(); | 3945 buf->Longjmp(); |
3911 UNREACHABLE(); | 3946 UNREACHABLE(); |
3912 } | 3947 } |
3913 | 3948 |
3914 } // namespace dart | 3949 } // namespace dart |
3915 | 3950 |
3916 #endif // defined TARGET_ARCH_DBC | 3951 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |