Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 7437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7448 | 7448 |
| 7449 void ICData::set_deopt_reason(intptr_t deopt_reason) const { | 7449 void ICData::set_deopt_reason(intptr_t deopt_reason) const { |
| 7450 raw_ptr()->deopt_reason_ = deopt_reason; | 7450 raw_ptr()->deopt_reason_ = deopt_reason; |
| 7451 } | 7451 } |
| 7452 | 7452 |
| 7453 void ICData::set_is_closure_call(bool value) const { | 7453 void ICData::set_is_closure_call(bool value) const { |
| 7454 raw_ptr()->is_closure_call_ = value ? 1 : 0; | 7454 raw_ptr()->is_closure_call_ = value ? 1 : 0; |
| 7455 } | 7455 } |
| 7456 | 7456 |
| 7457 | 7457 |
| 7458 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { | |
| 7459 return num_args + 1 /* target function*/ + 1 /* frequency */; | |
| 7460 } | |
| 7461 | |
| 7462 | |
| 7458 intptr_t ICData::TestEntryLength() const { | 7463 intptr_t ICData::TestEntryLength() const { |
| 7459 return num_args_tested() + 1 /* target function*/; | 7464 return TestEntryLengthFor(num_args_tested()); |
| 7460 } | 7465 } |
| 7461 | 7466 |
| 7462 | 7467 |
| 7463 intptr_t ICData::NumberOfChecks() const { | 7468 intptr_t ICData::NumberOfChecks() const { |
| 7464 // Do not count the sentinel; | 7469 // Do not count the sentinel; |
| 7465 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; | 7470 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; |
| 7466 } | 7471 } |
| 7467 | 7472 |
| 7468 | 7473 |
| 7469 void ICData::WriteSentinel() const { | 7474 void ICData::WriteSentinel() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7510 data = Array::Grow(data, new_len, Heap::kOld); | 7515 data = Array::Grow(data, new_len, Heap::kOld); |
| 7511 set_ic_data(data); | 7516 set_ic_data(data); |
| 7512 WriteSentinel(); | 7517 WriteSentinel(); |
| 7513 intptr_t data_pos = old_num * TestEntryLength(); | 7518 intptr_t data_pos = old_num * TestEntryLength(); |
| 7514 for (intptr_t i = 0; i < class_ids.length(); i++) { | 7519 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 7515 // kIllegalCid is used as terminating value, do not add it. | 7520 // kIllegalCid is used as terminating value, do not add it. |
| 7516 ASSERT(class_ids[i] != kIllegalCid); | 7521 ASSERT(class_ids[i] != kIllegalCid); |
| 7517 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); | 7522 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); |
| 7518 } | 7523 } |
| 7519 ASSERT(!target.IsNull()); | 7524 ASSERT(!target.IsNull()); |
| 7520 data.SetAt(data_pos, target); | 7525 data.SetAt(data_pos++, target); |
| 7526 data.SetAt(data_pos, Smi::Handle(Smi::New(1))); | |
| 7521 } | 7527 } |
| 7522 | 7528 |
| 7523 | 7529 |
| 7524 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 7530 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| 7525 const Function& target) const { | 7531 const Function& target) const { |
| 7526 #if defined(DEBUG) | 7532 #if defined(DEBUG) |
| 7527 GrowableArray<intptr_t> class_ids(1); | 7533 GrowableArray<intptr_t> class_ids(1); |
| 7528 class_ids.Add(receiver_class_id); | 7534 class_ids.Add(receiver_class_id); |
| 7529 ASSERT(!HasCheck(class_ids)); | 7535 ASSERT(!HasCheck(class_ids)); |
| 7530 #endif // DEBUG | 7536 #endif // DEBUG |
| 7531 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. | 7537 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. |
| 7532 ASSERT(receiver_class_id != kIllegalCid); | 7538 ASSERT(receiver_class_id != kIllegalCid); |
| 7533 ASSERT(!target.IsNull()); | 7539 ASSERT(!target.IsNull()); |
| 7534 | 7540 |
| 7535 const intptr_t old_num = NumberOfChecks(); | 7541 const intptr_t old_num = NumberOfChecks(); |
| 7536 Array& data = Array::Handle(ic_data()); | 7542 Array& data = Array::Handle(ic_data()); |
| 7537 const intptr_t new_len = data.Length() + TestEntryLength(); | 7543 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 7538 data = Array::Grow(data, new_len, Heap::kOld); | 7544 data = Array::Grow(data, new_len, Heap::kOld); |
| 7539 set_ic_data(data); | 7545 set_ic_data(data); |
| 7540 WriteSentinel(); | 7546 WriteSentinel(); |
| 7541 intptr_t data_pos = old_num * TestEntryLength(); | 7547 intptr_t data_pos = old_num * TestEntryLength(); |
| 7542 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { | 7548 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { |
|
Kevin Millikin (Google)
2012/11/13 20:59:33
This is pretty messy. How about:
if ((receiver_c
Vyacheslav Egorov (Google)
2012/12/17 12:54:16
Done.
| |
| 7543 // Instert kSmiCid in position 0. | 7549 // Insert kSmiCid in position 0. |
| 7544 const intptr_t zero_class_id = GetReceiverClassIdAt(0); | 7550 const intptr_t zero_class_id = GetReceiverClassIdAt(0); |
| 7545 ASSERT(zero_class_id != kSmiCid); // Simple duplicate entry check. | 7551 ASSERT(zero_class_id != kSmiCid); // Simple duplicate entry check. |
| 7546 const Function& zero_target = Function::Handle(GetTargetAt(0)); | 7552 const Function& zero_target = Function::Handle(GetTargetAt(0)); |
| 7553 const intptr_t count = GetCountAt(0); | |
| 7547 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); | 7554 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); |
| 7548 data.SetAt(1, target); | 7555 data.SetAt(1, target); |
| 7556 data.SetAt(2, Smi::Handle(Smi::New(1))); | |
| 7549 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); | 7557 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); |
| 7550 data.SetAt(data_pos + 1, zero_target); | 7558 data.SetAt(data_pos + 1, zero_target); |
| 7559 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); | |
| 7551 } else { | 7560 } else { |
| 7552 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); | 7561 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); |
| 7553 data.SetAt(data_pos + 1, target); | 7562 data.SetAt(data_pos + 1, target); |
| 7563 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(1))); | |
| 7554 } | 7564 } |
| 7555 } | 7565 } |
| 7556 | 7566 |
| 7557 | 7567 |
| 7558 void ICData::GetCheckAt(intptr_t index, | 7568 void ICData::GetCheckAt(intptr_t index, |
| 7559 GrowableArray<intptr_t>* class_ids, | 7569 GrowableArray<intptr_t>* class_ids, |
| 7560 Function* target) const { | 7570 Function* target, |
| 7571 intptr_t* count) const { | |
| 7561 ASSERT(index < NumberOfChecks()); | 7572 ASSERT(index < NumberOfChecks()); |
| 7562 ASSERT(class_ids != NULL); | 7573 ASSERT(class_ids != NULL); |
| 7563 ASSERT(target != NULL); | 7574 ASSERT(target != NULL); |
| 7564 class_ids->Clear(); | 7575 class_ids->Clear(); |
| 7565 const Array& data = Array::Handle(ic_data()); | 7576 const Array& data = Array::Handle(ic_data()); |
| 7566 intptr_t data_pos = index * TestEntryLength(); | 7577 intptr_t data_pos = index * TestEntryLength(); |
| 7567 Smi& smi = Smi::Handle(); | 7578 Smi& smi = Smi::Handle(); |
| 7568 for (intptr_t i = 0; i < num_args_tested(); i++) { | 7579 for (intptr_t i = 0; i < num_args_tested(); i++) { |
| 7569 smi ^= data.At(data_pos++); | 7580 smi ^= data.At(data_pos++); |
| 7570 class_ids->Add(smi.Value()); | 7581 class_ids->Add(smi.Value()); |
| 7571 } | 7582 } |
| 7572 (*target) ^= data.At(data_pos); | 7583 (*target) ^= data.At(data_pos++); |
| 7584 if (count != NULL) { | |
| 7585 smi ^= data.At(data_pos); | |
| 7586 *count = smi.Value(); | |
| 7587 } | |
| 7573 } | 7588 } |
| 7574 | 7589 |
| 7575 | 7590 |
| 7576 void ICData::GetOneClassCheckAt(intptr_t index, | 7591 void ICData::GetOneClassCheckAt(intptr_t index, |
| 7577 intptr_t* class_id, | 7592 intptr_t* class_id, |
| 7578 Function* target) const { | 7593 Function* target) const { |
| 7579 ASSERT(class_id != NULL); | 7594 ASSERT(class_id != NULL); |
| 7580 ASSERT(target != NULL); | 7595 ASSERT(target != NULL); |
| 7581 ASSERT(num_args_tested() == 1); | 7596 ASSERT(num_args_tested() == 1); |
| 7582 const Array& data = Array::Handle(ic_data()); | 7597 const Array& data = Array::Handle(ic_data()); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 7607 | 7622 |
| 7608 | 7623 |
| 7609 RawFunction* ICData::GetTargetAt(intptr_t index) const { | 7624 RawFunction* ICData::GetTargetAt(intptr_t index) const { |
| 7610 const Array& data = Array::Handle(ic_data()); | 7625 const Array& data = Array::Handle(ic_data()); |
| 7611 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); | 7626 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); |
| 7612 ASSERT(Object::Handle(data.At(data_pos)).IsFunction()); | 7627 ASSERT(Object::Handle(data.At(data_pos)).IsFunction()); |
| 7613 return reinterpret_cast<RawFunction*>(data.At(data_pos)); | 7628 return reinterpret_cast<RawFunction*>(data.At(data_pos)); |
| 7614 } | 7629 } |
| 7615 | 7630 |
| 7616 | 7631 |
| 7632 intptr_t ICData::GetCountAt(intptr_t index) const { | |
| 7633 const Array& data = Array::Handle(ic_data()); | |
| 7634 const intptr_t data_pos = index * TestEntryLength() + | |
| 7635 CountIndexFor(num_args_tested()); | |
| 7636 Smi& smi = Smi::Handle(); | |
| 7637 smi ^= data.At(data_pos); | |
| 7638 return smi.Value(); | |
| 7639 } | |
| 7640 | |
| 7641 | |
| 7617 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const { | 7642 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const { |
| 7618 const intptr_t len = NumberOfChecks(); | 7643 const intptr_t len = NumberOfChecks(); |
| 7619 for (intptr_t i = 0; i < len; i++) { | 7644 for (intptr_t i = 0; i < len; i++) { |
| 7620 if (GetReceiverClassIdAt(i) == class_id) { | 7645 if (GetReceiverClassIdAt(i) == class_id) { |
| 7621 return GetTargetAt(i); | 7646 return GetTargetAt(i); |
| 7622 } | 7647 } |
| 7623 } | 7648 } |
| 7624 return Function::null(); | 7649 return Function::null(); |
| 7625 } | 7650 } |
| 7626 | 7651 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7724 Heap::kOld); | 7749 Heap::kOld); |
| 7725 NoGCScope no_gc; | 7750 NoGCScope no_gc; |
| 7726 result ^= raw; | 7751 result ^= raw; |
| 7727 } | 7752 } |
| 7728 result.set_function(function); | 7753 result.set_function(function); |
| 7729 result.set_target_name(target_name); | 7754 result.set_target_name(target_name); |
| 7730 result.set_deopt_id(deopt_id); | 7755 result.set_deopt_id(deopt_id); |
| 7731 result.set_num_args_tested(num_args_tested); | 7756 result.set_num_args_tested(num_args_tested); |
| 7732 result.set_deopt_reason(kDeoptUnknown); | 7757 result.set_deopt_reason(kDeoptUnknown); |
| 7733 result.set_is_closure_call(false); | 7758 result.set_is_closure_call(false); |
| 7734 // Number of array elements in one test entry (num_args_tested + 1) | 7759 // Number of array elements in one test entry. |
| 7735 intptr_t len = result.TestEntryLength(); | 7760 intptr_t len = result.TestEntryLength(); |
| 7736 // IC data array must be null terminated (sentinel entry). | 7761 // IC data array must be null terminated (sentinel entry). |
| 7737 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 7762 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
| 7738 result.set_ic_data(ic_data); | 7763 result.set_ic_data(ic_data); |
| 7739 result.WriteSentinel(); | 7764 result.WriteSentinel(); |
| 7740 return result.raw(); | 7765 return result.raw(); |
| 7741 } | 7766 } |
| 7742 | 7767 |
| 7743 | 7768 |
| 7744 RawSubtypeTestCache* SubtypeTestCache::New() { | 7769 RawSubtypeTestCache* SubtypeTestCache::New() { |
| (...skipping 4243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11988 } | 12013 } |
| 11989 return result.raw(); | 12014 return result.raw(); |
| 11990 } | 12015 } |
| 11991 | 12016 |
| 11992 | 12017 |
| 11993 const char* WeakProperty::ToCString() const { | 12018 const char* WeakProperty::ToCString() const { |
| 11994 return "_WeakProperty"; | 12019 return "_WeakProperty"; |
| 11995 } | 12020 } |
| 11996 | 12021 |
| 11997 } // namespace dart | 12022 } // namespace dart |
| OLD | NEW |