Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: runtime/vm/object.cc

Issue 11275290: Count per check hits in ICData. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698