| 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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 DART_FORCE_INLINE static T* Untag(T* tagged) { | 167 DART_FORCE_INLINE static T* Untag(T* tagged) { |
| 168 return tagged->ptr(); | 168 return tagged->ptr(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) { | 171 DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) { |
| 172 return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) && | 172 return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) && |
| 173 (reinterpret_cast<intptr_t>(index) < | 173 (reinterpret_cast<intptr_t>(index) < |
| 174 reinterpret_cast<intptr_t>(length)); | 174 reinterpret_cast<intptr_t>(length)); |
| 175 } | 175 } |
| 176 | 176 |
| 177 DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(RawArray* argdesc) { |
| 178 return Smi::Value(*reinterpret_cast<RawSmi**>( |
| 179 reinterpret_cast<uword>(argdesc->ptr()) + |
| 180 Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex))); |
| 181 } |
| 182 |
| 183 DART_FORCE_INLINE static intptr_t ArgDescArgCount(RawArray* argdesc) { |
| 184 return Smi::Value(*reinterpret_cast<RawSmi**>( |
| 185 reinterpret_cast<uword>(argdesc->ptr()) + |
| 186 Array::element_offset(ArgumentsDescriptor::kCountIndex))); |
| 187 } |
| 188 |
| 189 DART_FORCE_INLINE static intptr_t ArgDescPosCount(RawArray* argdesc) { |
| 190 return Smi::Value(*reinterpret_cast<RawSmi**>( |
| 191 reinterpret_cast<uword>(argdesc->ptr()) + |
| 192 Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); |
| 193 } |
| 194 |
| 177 static bool ObjectArraySetIndexed(Thread* thread, | 195 static bool ObjectArraySetIndexed(Thread* thread, |
| 178 RawObject** FP, | 196 RawObject** FP, |
| 179 RawObject** result) { | 197 RawObject** result) { |
| 180 if (thread->isolate()->type_checks()) { | 198 if (thread->isolate()->type_checks()) { |
| 181 return false; | 199 return false; |
| 182 } | 200 } |
| 183 | 201 |
| 184 RawObject** args = FrameArguments(FP, 3); | 202 RawObject** args = FrameArguments(FP, 3); |
| 185 RawSmi* index = static_cast<RawSmi*>(args[1]); | 203 RawSmi* index = static_cast<RawSmi*>(args[1]); |
| 186 RawArray* array = static_cast<RawArray*>(args[0]); | 204 RawArray* array = static_cast<RawArray*>(args[0]); |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 uint32_t** pc, | 846 uint32_t** pc, |
| 829 RawObject*** FP, | 847 RawObject*** FP, |
| 830 RawObject*** SP, | 848 RawObject*** SP, |
| 831 bool optimized) { | 849 bool optimized) { |
| 832 ASSERT(icdata->GetClassId() == kICDataCid); | 850 ASSERT(icdata->GetClassId() == kICDataCid); |
| 833 | 851 |
| 834 const intptr_t kCheckedArgs = 1; | 852 const intptr_t kCheckedArgs = 1; |
| 835 RawObject** args = call_base; | 853 RawObject** args = call_base; |
| 836 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 854 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
| 837 | 855 |
| 838 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 856 const intptr_t type_args_len = |
| 857 SimulatorHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_); |
| 858 const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; |
| 859 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx]); |
| 839 | 860 |
| 840 bool found = false; | 861 bool found = false; |
| 841 const intptr_t length = Smi::Value(cache->length_); | 862 const intptr_t length = Smi::Value(cache->length_); |
| 842 intptr_t i; | 863 intptr_t i; |
| 843 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 864 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
| 844 if (cache->data()[i + 0] == receiver_cid) { | 865 if (cache->data()[i + 0] == receiver_cid) { |
| 845 top[0] = cache->data()[i + kCheckedArgs]; | 866 top[0] = cache->data()[i + kCheckedArgs]; |
| 846 found = true; | 867 found = true; |
| 847 break; | 868 break; |
| 848 } | 869 } |
| 849 } | 870 } |
| 850 | 871 |
| 851 if (found) { | 872 if (found) { |
| 852 if (!optimized) { | 873 if (!optimized) { |
| 853 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 874 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
| 854 } | 875 } |
| 855 } else { | 876 } else { |
| 856 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 877 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top, |
| 857 *SP); | 878 *pc, *FP, *SP); |
| 858 } | 879 } |
| 859 | 880 |
| 860 *argdesc = icdata->ptr()->args_descriptor_; | 881 *argdesc = icdata->ptr()->args_descriptor_; |
| 861 Invoke(thread, call_base, top, pp, pc, FP, SP); | 882 Invoke(thread, call_base, top, pp, pc, FP, SP); |
| 862 } | 883 } |
| 863 | 884 |
| 864 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 885 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
| 865 RawICData* icdata, | 886 RawICData* icdata, |
| 866 RawObject** call_base, | 887 RawObject** call_base, |
| 867 RawObject** top, | 888 RawObject** top, |
| 868 RawArray** argdesc, | 889 RawArray** argdesc, |
| 869 RawObjectPool** pp, | 890 RawObjectPool** pp, |
| 870 uint32_t** pc, | 891 uint32_t** pc, |
| 871 RawObject*** FP, | 892 RawObject*** FP, |
| 872 RawObject*** SP, | 893 RawObject*** SP, |
| 873 bool optimized) { | 894 bool optimized) { |
| 874 ASSERT(icdata->GetClassId() == kICDataCid); | 895 ASSERT(icdata->GetClassId() == kICDataCid); |
| 875 | 896 |
| 876 const intptr_t kCheckedArgs = 2; | 897 const intptr_t kCheckedArgs = 2; |
| 877 RawObject** args = call_base; | 898 RawObject** args = call_base; |
| 878 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 899 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
| 879 | 900 |
| 880 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 901 const intptr_t type_args_len = |
| 881 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 902 SimulatorHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_); |
| 903 const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; |
| 904 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx]); |
| 905 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[receiver_idx + 1]); |
| 882 | 906 |
| 883 bool found = false; | 907 bool found = false; |
| 884 const intptr_t length = Smi::Value(cache->length_); | 908 const intptr_t length = Smi::Value(cache->length_); |
| 885 intptr_t i; | 909 intptr_t i; |
| 886 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 910 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
| 887 if ((cache->data()[i + 0] == receiver_cid) && | 911 if ((cache->data()[i + 0] == receiver_cid) && |
| 888 (cache->data()[i + 1] == arg0_cid)) { | 912 (cache->data()[i + 1] == arg0_cid)) { |
| 889 top[0] = cache->data()[i + kCheckedArgs]; | 913 top[0] = cache->data()[i + kCheckedArgs]; |
| 890 found = true; | 914 found = true; |
| 891 break; | 915 break; |
| 892 } | 916 } |
| 893 } | 917 } |
| 894 | 918 |
| 895 if (found) { | 919 if (found) { |
| 896 if (!optimized) { | 920 if (!optimized) { |
| 897 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 921 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
| 898 } | 922 } |
| 899 } else { | 923 } else { |
| 900 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 924 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base + receiver_idx, top, |
| 901 *SP); | 925 *pc, *FP, *SP); |
| 902 } | 926 } |
| 903 | 927 |
| 904 *argdesc = icdata->ptr()->args_descriptor_; | 928 *argdesc = icdata->ptr()->args_descriptor_; |
| 905 Invoke(thread, call_base, top, pp, pc, FP, SP); | 929 Invoke(thread, call_base, top, pp, pc, FP, SP); |
| 906 } | 930 } |
| 907 | 931 |
| 908 // Note: functions below are marked DART_NOINLINE to recover performance on | 932 // Note: functions below are marked DART_NOINLINE to recover performance on |
| 909 // ARM where inlining these functions into the interpreter loop seemed to cause | 933 // ARM where inlining these functions into the interpreter loop seemed to cause |
| 910 // some code quality issues. | 934 // some code quality issues. |
| 911 static DART_NOINLINE bool InvokeRuntime(Thread* thread, | 935 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); | 1278 fp_[1 + i] = arguments.At(i); |
| 1255 } | 1279 } |
| 1256 | 1280 |
| 1257 FP[kFunctionSlotFromFp] = code.function(); | 1281 FP[kFunctionSlotFromFp] = code.function(); |
| 1258 FP[kPcMarkerSlotFromFp] = code.raw(); | 1282 FP[kPcMarkerSlotFromFp] = code.raw(); |
| 1259 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); | 1283 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); |
| 1260 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); | 1284 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); |
| 1261 | 1285 |
| 1262 // Load argument descriptor. | 1286 // Load argument descriptor. |
| 1263 argdesc = arguments_descriptor.raw(); | 1287 argdesc = arguments_descriptor.raw(); |
| 1288 ASSERT(ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() == 0); |
| 1264 | 1289 |
| 1265 // Ready to start executing bytecode. Load entry point and corresponding | 1290 // Ready to start executing bytecode. Load entry point and corresponding |
| 1266 // object pool. | 1291 // object pool. |
| 1267 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); | 1292 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); |
| 1268 pc_ = reinterpret_cast<uword>(pc); // For the profiler. | 1293 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
| 1269 pp = code.object_pool()->ptr(); | 1294 pp = code.object_pool()->ptr(); |
| 1270 | 1295 |
| 1271 // Cache some frequently used values in the frame. | 1296 // Cache some frequently used values in the frame. |
| 1272 RawBool* true_value = Bool::True().raw(); | 1297 RawBool* true_value = Bool::True().raw(); |
| 1273 RawBool* false_value = Bool::False().raw(); | 1298 RawBool* false_value = Bool::False().raw(); |
| 1274 RawObject* null_value = Object::null(); | 1299 RawObject* null_value = Object::null(); |
| 1275 RawObject* empty_context = Object::empty_context().raw(); | 1300 RawObject* empty_context = Object::empty_context().raw(); |
| 1276 | 1301 |
| 1277 #if defined(DEBUG) | 1302 #if defined(DEBUG) |
| 1278 Function& function_h = Function::Handle(); | 1303 Function& function_h = Function::Handle(); |
| 1279 #endif | 1304 #endif |
| 1280 | 1305 |
| 1281 // Enter the dispatch loop. | 1306 // Enter the dispatch loop. |
| 1282 DISPATCH(); | 1307 DISPATCH(); |
| 1283 | 1308 |
| 1284 // Bytecode handlers (see constants_dbc.h for bytecode descriptions). | 1309 // Bytecode handlers (see constants_dbc.h for bytecode descriptions). |
| 1285 { | 1310 { |
| 1286 BYTECODE(Entry, A_B_C); | 1311 BYTECODE(Entry, A_B_C); |
| 1287 const uint8_t num_fixed_params = rA; | 1312 const uint8_t num_fixed_params = rA; |
| 1288 const uint16_t num_locals = rB; | 1313 const uint16_t num_locals = rB; |
| 1289 const uint16_t context_reg = rC; | 1314 const uint16_t context_reg = rC; |
| 1290 | 1315 |
| 1291 // Decode arguments descriptor. | 1316 // Decode arguments descriptor. |
| 1292 const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>( | 1317 const intptr_t pos_count = SimulatorHelpers::ArgDescPosCount(argdesc); |
| 1293 reinterpret_cast<uword>(argdesc->ptr()) + | |
| 1294 Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); | |
| 1295 | 1318 |
| 1296 // Check that we got the right number of positional parameters. | 1319 // Check that we got the right number of positional parameters. |
| 1297 if (pos_count != num_fixed_params) { | 1320 if (pos_count != num_fixed_params) { |
| 1298 // Mismatch can only occur if current function is a closure. | 1321 // Mismatch can only occur if current function is a closure. |
| 1299 goto ClosureNoSuchMethod; | 1322 goto ClosureNoSuchMethod; |
| 1300 } | 1323 } |
| 1301 | 1324 |
| 1302 // Initialize locals with null and set current context variable to | 1325 // Initialize locals with null and set current context variable to |
| 1303 // empty context. | 1326 // empty context. |
| 1304 { | 1327 { |
| 1305 RawObject** L = FP; | 1328 RawObject** L = FP; |
| 1306 for (intptr_t i = 0; i < num_locals; i++) { | 1329 for (intptr_t i = 0; i < num_locals; i++) { |
| 1307 L[i] = null_value; | 1330 L[i] = null_value; |
| 1308 } | 1331 } |
| 1309 L[context_reg] = empty_context; | 1332 L[context_reg] = empty_context; |
| 1310 SP = FP + num_locals - 1; | 1333 SP = FP + num_locals - 1; |
| 1311 } | 1334 } |
| 1312 | 1335 |
| 1313 DISPATCH(); | 1336 DISPATCH(); |
| 1314 } | 1337 } |
| 1315 | 1338 |
| 1316 { | 1339 { |
| 1317 BYTECODE(EntryOptimized, A_D); | 1340 BYTECODE(EntryOptimized, A_D); |
| 1318 const uint8_t num_fixed_params = rA; | 1341 const uint8_t num_fixed_params = rA; |
| 1319 const uint16_t num_registers = rD; | 1342 const uint16_t num_registers = rD; |
| 1320 | 1343 |
| 1321 // Decode arguments descriptor. | 1344 // Decode arguments descriptor. |
| 1322 const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>( | 1345 const intptr_t pos_count = SimulatorHelpers::ArgDescPosCount(argdesc); |
| 1323 reinterpret_cast<uword>(argdesc->ptr()) + | |
| 1324 Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); | |
| 1325 | 1346 |
| 1326 // Check that we got the right number of positional parameters. | 1347 // Check that we got the right number of positional parameters. |
| 1327 if (pos_count != num_fixed_params) { | 1348 if (pos_count != num_fixed_params) { |
| 1328 // Mismatch can only occur if current function is a closure. | 1349 // Mismatch can only occur if current function is a closure. |
| 1329 goto ClosureNoSuchMethod; | 1350 goto ClosureNoSuchMethod; |
| 1330 } | 1351 } |
| 1331 | 1352 |
| 1332 // Reserve space for registers used by the optimized code. | 1353 // Reserve space for registers used by the optimized code. |
| 1333 SP = FP + num_registers - 1; | 1354 SP = FP + num_registers - 1; |
| 1334 | 1355 |
| 1335 DISPATCH(); | 1356 DISPATCH(); |
| 1336 } | 1357 } |
| 1337 | 1358 |
| 1338 { | 1359 { |
| 1339 BYTECODE(EntryOptional, A_B_C); | 1360 BYTECODE(EntryOptional, A_B_C); |
| 1340 const uint16_t num_fixed_params = rA; | 1361 const uint16_t num_fixed_params = rA; |
| 1341 const uint16_t num_opt_pos_params = rB; | 1362 const uint16_t num_opt_pos_params = rB; |
| 1342 const uint16_t num_opt_named_params = rC; | 1363 const uint16_t num_opt_named_params = rC; |
| 1343 const intptr_t min_num_pos_args = num_fixed_params; | 1364 const intptr_t min_num_pos_args = num_fixed_params; |
| 1344 const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params; | 1365 const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params; |
| 1345 | 1366 |
| 1346 // Decode arguments descriptor. | 1367 // Decode arguments descriptor. |
| 1347 const intptr_t arg_count = Smi::Value(*reinterpret_cast<RawSmi**>( | 1368 const intptr_t arg_count = SimulatorHelpers::ArgDescArgCount(argdesc); |
| 1348 reinterpret_cast<uword>(argdesc->ptr()) + | 1369 const intptr_t pos_count = SimulatorHelpers::ArgDescPosCount(argdesc); |
| 1349 Array::element_offset(ArgumentsDescriptor::kCountIndex))); | |
| 1350 const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>( | |
| 1351 reinterpret_cast<uword>(argdesc->ptr()) + | |
| 1352 Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); | |
| 1353 const intptr_t named_count = (arg_count - pos_count); | 1370 const intptr_t named_count = (arg_count - pos_count); |
| 1354 | 1371 |
| 1355 // Check that got the right number of positional parameters. | 1372 // Check that got the right number of positional parameters. |
| 1356 if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) { | 1373 if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) { |
| 1357 goto ClosureNoSuchMethod; | 1374 goto ClosureNoSuchMethod; |
| 1358 } | 1375 } |
| 1359 | 1376 |
| 1360 // Copy all passed position arguments. | 1377 // Copy all passed position arguments. |
| 1361 RawObject** first_arg = FrameArguments(FP, arg_count); | 1378 RawObject** first_arg = FrameArguments(FP, arg_count); |
| 1362 memmove(FP, first_arg, pos_count * kWordSize); | 1379 memmove(FP, first_arg, pos_count * kWordSize); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 ASSERT(num_opt_pos_params != 0); | 1442 ASSERT(num_opt_pos_params != 0); |
| 1426 if (named_count != 0) { | 1443 if (named_count != 0) { |
| 1427 // Function can't have both named and optional positional parameters. | 1444 // Function can't have both named and optional positional parameters. |
| 1428 // This kind of mismatch can only occur if the current function | 1445 // This kind of mismatch can only occur if the current function |
| 1429 // is a closure. | 1446 // is a closure. |
| 1430 goto ClosureNoSuchMethod; | 1447 goto ClosureNoSuchMethod; |
| 1431 } | 1448 } |
| 1432 | 1449 |
| 1433 // Process the list of default values encoded as a sequence of | 1450 // Process the list of default values encoded as a sequence of |
| 1434 // LoadConstant instructions after EntryOpt bytecode. | 1451 // LoadConstant instructions after EntryOpt bytecode. |
| 1435 // Execute only those that correspond to parameters the were not passed. | 1452 // 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; | 1453 for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params; |
| 1437 i++) { | 1454 i++) { |
| 1438 const uint32_t load_value = pc[i]; | 1455 const uint32_t load_value = pc[i]; |
| 1439 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); | 1456 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); |
| 1440 #if defined(DEBUG) | 1457 #if defined(DEBUG) |
| 1441 const uint8_t reg = Bytecode::DecodeA(load_value); | 1458 const uint8_t reg = Bytecode::DecodeA(load_value); |
| 1442 ASSERT((num_fixed_params + i) == reg); | 1459 ASSERT((num_fixed_params + i) == reg); |
| 1443 #endif | 1460 #endif |
| 1444 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); | 1461 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); |
| 1445 } | 1462 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 BYTECODE(CheckStackAlwaysExit, A); | 1564 BYTECODE(CheckStackAlwaysExit, A); |
| 1548 { | 1565 { |
| 1549 Exit(thread, FP, SP + 1, pc); | 1566 Exit(thread, FP, SP + 1, pc); |
| 1550 NativeArguments args(thread, 0, NULL, NULL); | 1567 NativeArguments args(thread, 0, NULL, NULL); |
| 1551 INVOKE_RUNTIME(DRT_StackOverflow, args); | 1568 INVOKE_RUNTIME(DRT_StackOverflow, args); |
| 1552 } | 1569 } |
| 1553 DISPATCH(); | 1570 DISPATCH(); |
| 1554 } | 1571 } |
| 1555 | 1572 |
| 1556 { | 1573 { |
| 1574 BYTECODE(CheckFunctionTypeArgs, A_D); |
| 1575 const uint16_t declared_type_args_len = rA; |
| 1576 const uint16_t first_stack_local_index = rD; |
| 1577 |
| 1578 // Decode arguments descriptor's type args len. |
| 1579 const intptr_t type_args_len = |
| 1580 SimulatorHelpers::ArgDescTypeArgsLen(argdesc); |
| 1581 if (type_args_len > 0) { |
| 1582 // Decode arguments descriptor's argument count (excluding type args). |
| 1583 const intptr_t arg_count = SimulatorHelpers::ArgDescArgCount(argdesc); |
| 1584 // Copy passed-in type args to first local slot. |
| 1585 FP[first_stack_local_index] = *FrameArguments(FP, arg_count + 1); |
| 1586 } else { |
| 1587 FP[first_stack_local_index] = Object::null(); |
| 1588 } |
| 1589 |
| 1590 // TODO(regis): Verify that type_args_len is correct. |
| 1591 USE(declared_type_args_len); |
| 1592 |
| 1593 DISPATCH(); |
| 1594 } |
| 1595 |
| 1596 { |
| 1557 BYTECODE(DebugStep, A); | 1597 BYTECODE(DebugStep, A); |
| 1558 if (thread->isolate()->single_step()) { | 1598 if (thread->isolate()->single_step()) { |
| 1559 Exit(thread, FP, SP + 1, pc); | 1599 Exit(thread, FP, SP + 1, pc); |
| 1560 NativeArguments args(thread, 0, NULL, NULL); | 1600 NativeArguments args(thread, 0, NULL, NULL); |
| 1561 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1601 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
| 1562 } | 1602 } |
| 1563 DISPATCH(); | 1603 DISPATCH(); |
| 1564 } | 1604 } |
| 1565 | 1605 |
| 1566 { | 1606 { |
| (...skipping 2340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3907 pc_ = pc; | 3947 pc_ = pc; |
| 3908 } | 3948 } |
| 3909 | 3949 |
| 3910 buf->Longjmp(); | 3950 buf->Longjmp(); |
| 3911 UNREACHABLE(); | 3951 UNREACHABLE(); |
| 3912 } | 3952 } |
| 3913 | 3953 |
| 3914 } // namespace dart | 3954 } // namespace dart |
| 3915 | 3955 |
| 3916 #endif // defined TARGET_ARCH_DBC | 3956 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |