Chromium Code Reviews| 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 |