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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 115 |
116 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { | 116 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { |
117 return obj->IsHeapObject() ? obj->GetClassId() | 117 return obj->IsHeapObject() ? obj->GetClassId() |
118 : static_cast<intptr_t>(kSmiCid); | 118 : static_cast<intptr_t>(kSmiCid); |
119 } | 119 } |
120 | 120 |
121 DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) { | 121 DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) { |
122 f->ptr()->usage_counter_++; | 122 f->ptr()->usage_counter_++; |
123 } | 123 } |
124 | 124 |
| 125 DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries, |
| 126 intptr_t offset, |
| 127 intptr_t args_tested) { |
| 128 const intptr_t count_offset = ICData::CountIndexFor(args_tested); |
| 129 const intptr_t raw_smi_old = |
| 130 reinterpret_cast<intptr_t>(entries[offset + count_offset]); |
| 131 const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); |
| 132 *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = |
| 133 raw_smi_new; |
| 134 } |
| 135 |
125 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, | 136 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, |
126 RawObject* rhs) { | 137 RawObject* rhs) { |
127 if (lhs == rhs) { | 138 if (lhs == rhs) { |
128 return true; | 139 return true; |
129 } | 140 } |
130 | 141 |
131 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { | 142 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { |
132 const intptr_t lhs_cid = lhs->GetClassId(); | 143 const intptr_t lhs_cid = lhs->GetClassId(); |
133 const intptr_t rhs_cid = rhs->GetClassId(); | 144 const intptr_t rhs_cid = rhs->GetClassId(); |
134 if (lhs_cid == rhs_cid) { | 145 if (lhs_cid == rhs_cid) { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 | 592 |
582 | 593 |
583 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, | 594 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, |
584 RawICData* icdata, | 595 RawICData* icdata, |
585 RawObject** call_base, | 596 RawObject** call_base, |
586 RawObject** top, | 597 RawObject** top, |
587 RawArray** argdesc, | 598 RawArray** argdesc, |
588 RawObjectPool** pp, | 599 RawObjectPool** pp, |
589 uint32_t** pc, | 600 uint32_t** pc, |
590 RawObject*** FP, | 601 RawObject*** FP, |
591 RawObject*** SP) { | 602 RawObject*** SP, |
| 603 bool optimized) { |
592 ASSERT(icdata->GetClassId() == kICDataCid); | 604 ASSERT(icdata->GetClassId() == kICDataCid); |
593 | 605 |
594 const intptr_t kCheckedArgs = 1; | 606 const intptr_t kCheckedArgs = 1; |
595 RawObject** args = call_base; | 607 RawObject** args = call_base; |
596 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 608 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
597 | 609 |
598 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 610 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
599 | 611 |
600 bool found = false; | 612 bool found = false; |
601 const intptr_t length = Smi::Value(cache->length_); | 613 const intptr_t length = Smi::Value(cache->length_); |
602 for (intptr_t i = 0; | 614 intptr_t i; |
| 615 for (i = 0; |
603 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 616 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
604 if (cache->data()[i + 0] == receiver_cid) { | 617 if (cache->data()[i + 0] == receiver_cid) { |
605 top[0] = cache->data()[i + kCheckedArgs]; | 618 top[0] = cache->data()[i + kCheckedArgs]; |
606 found = true; | 619 found = true; |
607 break; | 620 break; |
608 } | 621 } |
609 } | 622 } |
610 | 623 |
611 if (!found) { | 624 if (found) { |
| 625 if (!optimized) { |
| 626 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
| 627 } |
| 628 } else { |
612 InlineCacheMiss( | 629 InlineCacheMiss( |
613 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 630 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); |
614 } | 631 } |
615 | 632 |
616 *argdesc = icdata->ptr()->args_descriptor_; | 633 *argdesc = icdata->ptr()->args_descriptor_; |
617 Invoke(thread, call_base, top, pp, pc, FP, SP); | 634 Invoke(thread, call_base, top, pp, pc, FP, SP); |
618 } | 635 } |
619 | 636 |
620 | 637 |
621 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 638 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
622 RawICData* icdata, | 639 RawICData* icdata, |
623 RawObject** call_base, | 640 RawObject** call_base, |
624 RawObject** top, | 641 RawObject** top, |
625 RawArray** argdesc, | 642 RawArray** argdesc, |
626 RawObjectPool** pp, | 643 RawObjectPool** pp, |
627 uint32_t** pc, | 644 uint32_t** pc, |
628 RawObject*** FP, | 645 RawObject*** FP, |
629 RawObject*** SP) { | 646 RawObject*** SP, |
| 647 bool optimized) { |
630 ASSERT(icdata->GetClassId() == kICDataCid); | 648 ASSERT(icdata->GetClassId() == kICDataCid); |
631 | 649 |
632 const intptr_t kCheckedArgs = 2; | 650 const intptr_t kCheckedArgs = 2; |
633 RawObject** args = call_base; | 651 RawObject** args = call_base; |
634 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 652 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
635 | 653 |
636 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 654 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
637 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 655 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); |
638 | 656 |
639 bool found = false; | 657 bool found = false; |
640 const intptr_t length = Smi::Value(cache->length_); | 658 const intptr_t length = Smi::Value(cache->length_); |
641 for (intptr_t i = 0; | 659 intptr_t i; |
| 660 for (i = 0; |
642 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 661 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
643 if ((cache->data()[i + 0] == receiver_cid) && | 662 if ((cache->data()[i + 0] == receiver_cid) && |
644 (cache->data()[i + 1] == arg0_cid)) { | 663 (cache->data()[i + 1] == arg0_cid)) { |
645 top[0] = cache->data()[i + kCheckedArgs]; | 664 top[0] = cache->data()[i + kCheckedArgs]; |
646 found = true; | 665 found = true; |
647 break; | 666 break; |
648 } | 667 } |
649 } | 668 } |
650 | 669 |
651 if (!found) { | 670 if (found) { |
| 671 if (!optimized) { |
| 672 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
| 673 } |
| 674 } else { |
652 InlineCacheMiss( | 675 InlineCacheMiss( |
653 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 676 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); |
654 } | 677 } |
655 | 678 |
656 *argdesc = icdata->ptr()->args_descriptor_; | 679 *argdesc = icdata->ptr()->args_descriptor_; |
657 Invoke(thread, call_base, top, pp, pc, FP, SP); | 680 Invoke(thread, call_base, top, pp, pc, FP, SP); |
658 } | 681 } |
659 | 682 |
660 | 683 |
661 // Note: functions below are marked DART_NOINLINE to recover performance on | 684 // Note: functions below are marked DART_NOINLINE to recover performance on |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 | 778 |
756 #define DECLARE_A_X int32_t rD; USE(rD) | 779 #define DECLARE_A_X int32_t rD; USE(rD) |
757 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); | 780 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); |
758 | 781 |
759 | 782 |
760 #define SMI_FASTPATH_ICDATA_INC \ | 783 #define SMI_FASTPATH_ICDATA_INC \ |
761 do { \ | 784 do { \ |
762 ASSERT(Bytecode::IsCallOpcode(*pc)); \ | 785 ASSERT(Bytecode::IsCallOpcode(*pc)); \ |
763 const uint16_t kidx = Bytecode::DecodeD(*pc); \ | 786 const uint16_t kidx = Bytecode::DecodeD(*pc); \ |
764 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ | 787 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ |
765 RawObject** data = icdata->ptr()->ic_data_->ptr()->data(); \ | 788 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ |
766 const intptr_t count_offset = ICData::CountIndexFor(2); \ | 789 SimulatorHelpers::IncrementICUsageCount(entries, 0, 2); \ |
767 const intptr_t raw_smi_old = \ | |
768 reinterpret_cast<intptr_t>(data[count_offset]); \ | |
769 const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); \ | |
770 *reinterpret_cast<intptr_t*>(&data[count_offset]) = raw_smi_new; \ | |
771 } while (0); \ | 790 } while (0); \ |
772 | 791 |
773 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the | 792 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the |
774 // given result type and the given behavior specified as a function | 793 // given result type and the given behavior specified as a function |
775 // that takes left and right operands and result slot and returns | 794 // that takes left and right operands and result slot and returns |
776 // true if fast-path succeeds. | 795 // true if fast-path succeeds. |
777 #define SMI_FASTPATH_TOS(ResultT, Func) \ | 796 #define SMI_FASTPATH_TOS(ResultT, Func) \ |
778 { \ | 797 { \ |
779 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ | 798 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ |
780 const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \ | 799 const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \ |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 NativeArguments args(thread, 0, NULL, NULL); | 1401 NativeArguments args(thread, 0, NULL, NULL); |
1383 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1402 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1384 } | 1403 } |
1385 | 1404 |
1386 // Invoke target function. | 1405 // Invoke target function. |
1387 { | 1406 { |
1388 const uint16_t argc = rA; | 1407 const uint16_t argc = rA; |
1389 // Lookup the funciton in the ICData. | 1408 // Lookup the funciton in the ICData. |
1390 RawObject* ic_data_obj = SP[0]; | 1409 RawObject* ic_data_obj = SP[0]; |
1391 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); | 1410 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); |
1392 RawArray* cache = ic_data->ptr()->ic_data_->ptr(); | 1411 RawObject** data = ic_data->ptr()->ic_data_->ptr()->data(); |
1393 SP[0] = cache->data()[ICData::TargetIndexFor( | 1412 SimulatorHelpers::IncrementICUsageCount(data, 0, 0); |
| 1413 SP[0] = data[ICData::TargetIndexFor( |
1394 ic_data->ptr()->state_bits_ & 0x3)]; | 1414 ic_data->ptr()->state_bits_ & 0x3)]; |
1395 RawObject** call_base = SP - argc; | 1415 RawObject** call_base = SP - argc; |
1396 RawObject** call_top = SP; // *SP contains function | 1416 RawObject** call_top = SP; // *SP contains function |
1397 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); | 1417 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); |
1398 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); | 1418 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); |
1399 } | 1419 } |
1400 | 1420 |
1401 DISPATCH(); | 1421 DISPATCH(); |
1402 } | 1422 } |
1403 | 1423 |
(...skipping 20 matching lines...) Expand all Loading... |
1424 { | 1444 { |
1425 const uint16_t argc = rA; | 1445 const uint16_t argc = rA; |
1426 const uint16_t kidx = rD; | 1446 const uint16_t kidx = rD; |
1427 | 1447 |
1428 RawObject** call_base = SP - argc + 1; | 1448 RawObject** call_base = SP - argc + 1; |
1429 RawObject** call_top = SP + 1; | 1449 RawObject** call_top = SP + 1; |
1430 | 1450 |
1431 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1451 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1432 SimulatorHelpers::IncrementUsageCounter( | 1452 SimulatorHelpers::IncrementUsageCounter( |
1433 RAW_CAST(Function, icdata->ptr()->owner_)); | 1453 RAW_CAST(Function, icdata->ptr()->owner_)); |
1434 InstanceCall1( | 1454 InstanceCall1(thread, icdata, call_base, call_top, |
1435 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1455 &argdesc, &pp, &pc, &FP, &SP, |
| 1456 false /* optimized */); |
1436 } | 1457 } |
1437 | 1458 |
1438 DISPATCH(); | 1459 DISPATCH(); |
1439 } | 1460 } |
1440 | 1461 |
1441 { | 1462 { |
1442 BYTECODE(InstanceCall2, A_D); | 1463 BYTECODE(InstanceCall2, A_D); |
1443 if (thread->isolate()->single_step()) { | 1464 if (thread->isolate()->single_step()) { |
1444 Exit(thread, FP, SP + 1, pc); | 1465 Exit(thread, FP, SP + 1, pc); |
1445 NativeArguments args(thread, 0, NULL, NULL); | 1466 NativeArguments args(thread, 0, NULL, NULL); |
1446 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1467 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1447 } | 1468 } |
1448 | 1469 |
1449 { | 1470 { |
1450 const uint16_t argc = rA; | 1471 const uint16_t argc = rA; |
1451 const uint16_t kidx = rD; | 1472 const uint16_t kidx = rD; |
1452 | 1473 |
1453 RawObject** call_base = SP - argc + 1; | 1474 RawObject** call_base = SP - argc + 1; |
1454 RawObject** call_top = SP + 1; | 1475 RawObject** call_top = SP + 1; |
1455 | 1476 |
1456 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1477 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1457 SimulatorHelpers::IncrementUsageCounter( | 1478 SimulatorHelpers::IncrementUsageCounter( |
1458 RAW_CAST(Function, icdata->ptr()->owner_)); | 1479 RAW_CAST(Function, icdata->ptr()->owner_)); |
1459 InstanceCall2( | 1480 InstanceCall2(thread, icdata, call_base, call_top, |
1460 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1481 &argdesc, &pp, &pc, &FP, &SP, |
| 1482 false /* optimized */); |
1461 } | 1483 } |
1462 | 1484 |
1463 DISPATCH(); | 1485 DISPATCH(); |
1464 } | 1486 } |
1465 | 1487 |
1466 { | 1488 { |
1467 BYTECODE(InstanceCall1Opt, A_D); | 1489 BYTECODE(InstanceCall1Opt, A_D); |
1468 | 1490 |
1469 { | 1491 { |
1470 const uint16_t argc = rA; | 1492 const uint16_t argc = rA; |
1471 const uint16_t kidx = rD; | 1493 const uint16_t kidx = rD; |
1472 | 1494 |
1473 RawObject** call_base = SP - argc + 1; | 1495 RawObject** call_base = SP - argc + 1; |
1474 RawObject** call_top = SP + 1; | 1496 RawObject** call_top = SP + 1; |
1475 | 1497 |
1476 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1498 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1477 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1499 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1478 InstanceCall1( | 1500 InstanceCall1(thread, icdata, call_base, call_top, |
1479 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1501 &argdesc, &pp, &pc, &FP, &SP, |
| 1502 true /* optimized */); |
1480 } | 1503 } |
1481 | 1504 |
1482 DISPATCH(); | 1505 DISPATCH(); |
1483 } | 1506 } |
1484 | 1507 |
1485 { | 1508 { |
1486 BYTECODE(InstanceCall2Opt, A_D); | 1509 BYTECODE(InstanceCall2Opt, A_D); |
1487 | 1510 |
1488 { | 1511 { |
1489 const uint16_t argc = rA; | 1512 const uint16_t argc = rA; |
1490 const uint16_t kidx = rD; | 1513 const uint16_t kidx = rD; |
1491 | 1514 |
1492 RawObject** call_base = SP - argc + 1; | 1515 RawObject** call_base = SP - argc + 1; |
1493 RawObject** call_top = SP + 1; | 1516 RawObject** call_top = SP + 1; |
1494 | 1517 |
1495 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1518 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1496 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1519 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1497 InstanceCall2( | 1520 InstanceCall2(thread, icdata, call_base, call_top, |
1498 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1521 &argdesc, &pp, &pc, &FP, &SP, |
| 1522 true /* optimized */); |
1499 } | 1523 } |
1500 | 1524 |
1501 DISPATCH(); | 1525 DISPATCH(); |
1502 } | 1526 } |
1503 | 1527 |
1504 { | 1528 { |
1505 BYTECODE(NativeBootstrapCall, 0); | 1529 BYTECODE(NativeBootstrapCall, 0); |
1506 RawFunction* function = FrameFunction(FP); | 1530 RawFunction* function = FrameFunction(FP); |
1507 RawObject** incoming_args = | 1531 RawObject** incoming_args = |
1508 (function->ptr()->num_optional_parameters_ == 0) | 1532 (function->ptr()->num_optional_parameters_ == 0) |
(...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3002 pc_ = pc; | 3026 pc_ = pc; |
3003 special_[kExceptionSpecialIndex] = raw_exception; | 3027 special_[kExceptionSpecialIndex] = raw_exception; |
3004 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 3028 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
3005 buf->Longjmp(); | 3029 buf->Longjmp(); |
3006 UNREACHABLE(); | 3030 UNREACHABLE(); |
3007 } | 3031 } |
3008 | 3032 |
3009 } // namespace dart | 3033 } // namespace dart |
3010 | 3034 |
3011 #endif // defined TARGET_ARCH_DBC | 3035 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |