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 for (intptr_t i = 0; |
603 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 615 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
604 if (cache->data()[i + 0] == receiver_cid) { | 616 if (cache->data()[i + 0] == receiver_cid) { |
605 top[0] = cache->data()[i + kCheckedArgs]; | 617 top[0] = cache->data()[i + kCheckedArgs]; |
606 found = true; | 618 found = true; |
619 if (!optimized) { | |
620 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | |
zra
2016/07/28 22:03:53
Should this be incremented after handling an inlin
rmacnak
2016/07/28 22:22:04
No, the runtime call that adds the new entry gives
| |
621 } | |
607 break; | 622 break; |
608 } | 623 } |
609 } | 624 } |
610 | 625 |
611 if (!found) { | 626 if (!found) { |
612 InlineCacheMiss( | 627 InlineCacheMiss( |
613 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 628 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); |
614 } | 629 } |
615 | 630 |
616 *argdesc = icdata->ptr()->args_descriptor_; | 631 *argdesc = icdata->ptr()->args_descriptor_; |
617 Invoke(thread, call_base, top, pp, pc, FP, SP); | 632 Invoke(thread, call_base, top, pp, pc, FP, SP); |
618 } | 633 } |
619 | 634 |
620 | 635 |
621 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 636 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
622 RawICData* icdata, | 637 RawICData* icdata, |
623 RawObject** call_base, | 638 RawObject** call_base, |
624 RawObject** top, | 639 RawObject** top, |
625 RawArray** argdesc, | 640 RawArray** argdesc, |
626 RawObjectPool** pp, | 641 RawObjectPool** pp, |
627 uint32_t** pc, | 642 uint32_t** pc, |
628 RawObject*** FP, | 643 RawObject*** FP, |
629 RawObject*** SP) { | 644 RawObject*** SP, |
645 bool optimized) { | |
630 ASSERT(icdata->GetClassId() == kICDataCid); | 646 ASSERT(icdata->GetClassId() == kICDataCid); |
631 | 647 |
632 const intptr_t kCheckedArgs = 2; | 648 const intptr_t kCheckedArgs = 2; |
633 RawObject** args = call_base; | 649 RawObject** args = call_base; |
634 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 650 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
635 | 651 |
636 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 652 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
637 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 653 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); |
638 | 654 |
639 bool found = false; | 655 bool found = false; |
640 const intptr_t length = Smi::Value(cache->length_); | 656 const intptr_t length = Smi::Value(cache->length_); |
641 for (intptr_t i = 0; | 657 for (intptr_t i = 0; |
642 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | 658 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
643 if ((cache->data()[i + 0] == receiver_cid) && | 659 if ((cache->data()[i + 0] == receiver_cid) && |
644 (cache->data()[i + 1] == arg0_cid)) { | 660 (cache->data()[i + 1] == arg0_cid)) { |
645 top[0] = cache->data()[i + kCheckedArgs]; | 661 top[0] = cache->data()[i + kCheckedArgs]; |
646 found = true; | 662 found = true; |
663 if (!optimized) { | |
zra
2016/07/28 22:03:53
ditto.
| |
664 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | |
665 } | |
647 break; | 666 break; |
648 } | 667 } |
649 } | 668 } |
650 | 669 |
651 if (!found) { | 670 if (!found) { |
652 InlineCacheMiss( | 671 InlineCacheMiss( |
653 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 672 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); |
654 } | 673 } |
655 | 674 |
656 *argdesc = icdata->ptr()->args_descriptor_; | 675 *argdesc = icdata->ptr()->args_descriptor_; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
755 | 774 |
756 #define DECLARE_A_X int32_t rD; USE(rD) | 775 #define DECLARE_A_X int32_t rD; USE(rD) |
757 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); | 776 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); |
758 | 777 |
759 | 778 |
760 #define SMI_FASTPATH_ICDATA_INC \ | 779 #define SMI_FASTPATH_ICDATA_INC \ |
761 do { \ | 780 do { \ |
762 ASSERT(Bytecode::IsCallOpcode(*pc)); \ | 781 ASSERT(Bytecode::IsCallOpcode(*pc)); \ |
763 const uint16_t kidx = Bytecode::DecodeD(*pc); \ | 782 const uint16_t kidx = Bytecode::DecodeD(*pc); \ |
764 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ | 783 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ |
765 RawObject** data = icdata->ptr()->ic_data_->ptr()->data(); \ | 784 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ |
766 const intptr_t count_offset = ICData::CountIndexFor(2); \ | 785 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); \ | 786 } while (0); \ |
772 | 787 |
773 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the | 788 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the |
774 // given result type and the given behavior specified as a function | 789 // given result type and the given behavior specified as a function |
775 // that takes left and right operands and result slot and returns | 790 // that takes left and right operands and result slot and returns |
776 // true if fast-path succeeds. | 791 // true if fast-path succeeds. |
777 #define SMI_FASTPATH_TOS(ResultT, Func) \ | 792 #define SMI_FASTPATH_TOS(ResultT, Func) \ |
778 { \ | 793 { \ |
779 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ | 794 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ |
780 const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \ | 795 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); | 1397 NativeArguments args(thread, 0, NULL, NULL); |
1383 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1398 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1384 } | 1399 } |
1385 | 1400 |
1386 // Invoke target function. | 1401 // Invoke target function. |
1387 { | 1402 { |
1388 const uint16_t argc = rA; | 1403 const uint16_t argc = rA; |
1389 // Lookup the funciton in the ICData. | 1404 // Lookup the funciton in the ICData. |
1390 RawObject* ic_data_obj = SP[0]; | 1405 RawObject* ic_data_obj = SP[0]; |
1391 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); | 1406 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); |
1392 RawArray* cache = ic_data->ptr()->ic_data_->ptr(); | 1407 RawObject** data = ic_data->ptr()->ic_data_->ptr()->data(); |
1393 SP[0] = cache->data()[ICData::TargetIndexFor( | 1408 SimulatorHelpers::IncrementICUsageCount(data, 0, 0); |
1409 SP[0] = data[ICData::TargetIndexFor( | |
1394 ic_data->ptr()->state_bits_ & 0x3)]; | 1410 ic_data->ptr()->state_bits_ & 0x3)]; |
1395 RawObject** call_base = SP - argc; | 1411 RawObject** call_base = SP - argc; |
1396 RawObject** call_top = SP; // *SP contains function | 1412 RawObject** call_top = SP; // *SP contains function |
1397 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); | 1413 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); |
1398 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); | 1414 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); |
1399 } | 1415 } |
1400 | 1416 |
1401 DISPATCH(); | 1417 DISPATCH(); |
1402 } | 1418 } |
1403 | 1419 |
(...skipping 20 matching lines...) Expand all Loading... | |
1424 { | 1440 { |
1425 const uint16_t argc = rA; | 1441 const uint16_t argc = rA; |
1426 const uint16_t kidx = rD; | 1442 const uint16_t kidx = rD; |
1427 | 1443 |
1428 RawObject** call_base = SP - argc + 1; | 1444 RawObject** call_base = SP - argc + 1; |
1429 RawObject** call_top = SP + 1; | 1445 RawObject** call_top = SP + 1; |
1430 | 1446 |
1431 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1447 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1432 SimulatorHelpers::IncrementUsageCounter( | 1448 SimulatorHelpers::IncrementUsageCounter( |
1433 RAW_CAST(Function, icdata->ptr()->owner_)); | 1449 RAW_CAST(Function, icdata->ptr()->owner_)); |
1434 InstanceCall1( | 1450 InstanceCall1(thread, icdata, call_base, call_top, |
1435 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1451 &argdesc, &pp, &pc, &FP, &SP, |
1452 false /* optimized */); | |
1436 } | 1453 } |
1437 | 1454 |
1438 DISPATCH(); | 1455 DISPATCH(); |
1439 } | 1456 } |
1440 | 1457 |
1441 { | 1458 { |
1442 BYTECODE(InstanceCall2, A_D); | 1459 BYTECODE(InstanceCall2, A_D); |
1443 if (thread->isolate()->single_step()) { | 1460 if (thread->isolate()->single_step()) { |
1444 Exit(thread, FP, SP + 1, pc); | 1461 Exit(thread, FP, SP + 1, pc); |
1445 NativeArguments args(thread, 0, NULL, NULL); | 1462 NativeArguments args(thread, 0, NULL, NULL); |
1446 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1463 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1447 } | 1464 } |
1448 | 1465 |
1449 { | 1466 { |
1450 const uint16_t argc = rA; | 1467 const uint16_t argc = rA; |
1451 const uint16_t kidx = rD; | 1468 const uint16_t kidx = rD; |
1452 | 1469 |
1453 RawObject** call_base = SP - argc + 1; | 1470 RawObject** call_base = SP - argc + 1; |
1454 RawObject** call_top = SP + 1; | 1471 RawObject** call_top = SP + 1; |
1455 | 1472 |
1456 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1473 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1457 SimulatorHelpers::IncrementUsageCounter( | 1474 SimulatorHelpers::IncrementUsageCounter( |
1458 RAW_CAST(Function, icdata->ptr()->owner_)); | 1475 RAW_CAST(Function, icdata->ptr()->owner_)); |
1459 InstanceCall2( | 1476 InstanceCall2(thread, icdata, call_base, call_top, |
1460 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1477 &argdesc, &pp, &pc, &FP, &SP, |
1478 false /* optimized */); | |
1461 } | 1479 } |
1462 | 1480 |
1463 DISPATCH(); | 1481 DISPATCH(); |
1464 } | 1482 } |
1465 | 1483 |
1466 { | 1484 { |
1467 BYTECODE(InstanceCall1Opt, A_D); | 1485 BYTECODE(InstanceCall1Opt, A_D); |
1468 | 1486 |
1469 { | 1487 { |
1470 const uint16_t argc = rA; | 1488 const uint16_t argc = rA; |
1471 const uint16_t kidx = rD; | 1489 const uint16_t kidx = rD; |
1472 | 1490 |
1473 RawObject** call_base = SP - argc + 1; | 1491 RawObject** call_base = SP - argc + 1; |
1474 RawObject** call_top = SP + 1; | 1492 RawObject** call_top = SP + 1; |
1475 | 1493 |
1476 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1494 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1477 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1495 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1478 InstanceCall1( | 1496 InstanceCall1(thread, icdata, call_base, call_top, |
1479 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1497 &argdesc, &pp, &pc, &FP, &SP, |
1498 true /* optimized */); | |
1480 } | 1499 } |
1481 | 1500 |
1482 DISPATCH(); | 1501 DISPATCH(); |
1483 } | 1502 } |
1484 | 1503 |
1485 { | 1504 { |
1486 BYTECODE(InstanceCall2Opt, A_D); | 1505 BYTECODE(InstanceCall2Opt, A_D); |
1487 | 1506 |
1488 { | 1507 { |
1489 const uint16_t argc = rA; | 1508 const uint16_t argc = rA; |
1490 const uint16_t kidx = rD; | 1509 const uint16_t kidx = rD; |
1491 | 1510 |
1492 RawObject** call_base = SP - argc + 1; | 1511 RawObject** call_base = SP - argc + 1; |
1493 RawObject** call_top = SP + 1; | 1512 RawObject** call_top = SP + 1; |
1494 | 1513 |
1495 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1514 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1496 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1515 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1497 InstanceCall2( | 1516 InstanceCall2(thread, icdata, call_base, call_top, |
1498 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1517 &argdesc, &pp, &pc, &FP, &SP, |
1518 true /* optimized */); | |
1499 } | 1519 } |
1500 | 1520 |
1501 DISPATCH(); | 1521 DISPATCH(); |
1502 } | 1522 } |
1503 | 1523 |
1504 { | 1524 { |
1505 BYTECODE(NativeBootstrapCall, 0); | 1525 BYTECODE(NativeBootstrapCall, 0); |
1506 RawFunction* function = FrameFunction(FP); | 1526 RawFunction* function = FrameFunction(FP); |
1507 RawObject** incoming_args = | 1527 RawObject** incoming_args = |
1508 (function->ptr()->num_optional_parameters_ == 0) | 1528 (function->ptr()->num_optional_parameters_ == 0) |
(...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3002 pc_ = pc; | 3022 pc_ = pc; |
3003 special_[kExceptionSpecialIndex] = raw_exception; | 3023 special_[kExceptionSpecialIndex] = raw_exception; |
3004 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 3024 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
3005 buf->Longjmp(); | 3025 buf->Longjmp(); |
3006 UNREACHABLE(); | 3026 UNREACHABLE(); |
3007 } | 3027 } |
3008 | 3028 |
3009 } // namespace dart | 3029 } // namespace dart |
3010 | 3030 |
3011 #endif // defined TARGET_ARCH_DBC | 3031 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |