Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 216addc9ece72b403b39254677a592db098c0410..0a69557a1cdf9ca65aa0e3a6407121ae71347703 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -7455,8 +7455,13 @@ void ICData::set_is_closure_call(bool value) const { |
| } |
| +intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { |
| + return num_args + 1 /* target function*/ + 1 /* frequency */; |
| +} |
| + |
| + |
| intptr_t ICData::TestEntryLength() const { |
| - return num_args_tested() + 1 /* target function*/; |
| + return TestEntryLengthFor(num_args_tested()); |
| } |
| @@ -7517,7 +7522,8 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
| data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); |
| } |
| ASSERT(!target.IsNull()); |
| - data.SetAt(data_pos, target); |
| + data.SetAt(data_pos++, target); |
| + data.SetAt(data_pos, Smi::Handle(Smi::New(1))); |
| } |
| @@ -7540,24 +7546,29 @@ void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| WriteSentinel(); |
| intptr_t data_pos = old_num * TestEntryLength(); |
| 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.
|
| - // Instert kSmiCid in position 0. |
| + // Insert kSmiCid in position 0. |
| const intptr_t zero_class_id = GetReceiverClassIdAt(0); |
| ASSERT(zero_class_id != kSmiCid); // Simple duplicate entry check. |
| const Function& zero_target = Function::Handle(GetTargetAt(0)); |
| + const intptr_t count = GetCountAt(0); |
| data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); |
| data.SetAt(1, target); |
| + data.SetAt(2, Smi::Handle(Smi::New(1))); |
| data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); |
| data.SetAt(data_pos + 1, zero_target); |
| + data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); |
| } else { |
| data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); |
| data.SetAt(data_pos + 1, target); |
| + data.SetAt(data_pos + 2, Smi::Handle(Smi::New(1))); |
| } |
| } |
| void ICData::GetCheckAt(intptr_t index, |
| GrowableArray<intptr_t>* class_ids, |
| - Function* target) const { |
| + Function* target, |
| + intptr_t* count) const { |
| ASSERT(index < NumberOfChecks()); |
| ASSERT(class_ids != NULL); |
| ASSERT(target != NULL); |
| @@ -7569,7 +7580,11 @@ void ICData::GetCheckAt(intptr_t index, |
| smi ^= data.At(data_pos++); |
| class_ids->Add(smi.Value()); |
| } |
| - (*target) ^= data.At(data_pos); |
| + (*target) ^= data.At(data_pos++); |
| + if (count != NULL) { |
| + smi ^= data.At(data_pos); |
| + *count = smi.Value(); |
| + } |
| } |
| @@ -7614,6 +7629,16 @@ RawFunction* ICData::GetTargetAt(intptr_t index) const { |
| } |
| +intptr_t ICData::GetCountAt(intptr_t index) const { |
| + const Array& data = Array::Handle(ic_data()); |
| + const intptr_t data_pos = index * TestEntryLength() + |
| + CountIndexFor(num_args_tested()); |
| + Smi& smi = Smi::Handle(); |
| + smi ^= data.At(data_pos); |
| + return smi.Value(); |
| +} |
| + |
| + |
| RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id) const { |
| const intptr_t len = NumberOfChecks(); |
| for (intptr_t i = 0; i < len; i++) { |
| @@ -7731,7 +7756,7 @@ RawICData* ICData::New(const Function& function, |
| result.set_num_args_tested(num_args_tested); |
| result.set_deopt_reason(kDeoptUnknown); |
| result.set_is_closure_call(false); |
| - // Number of array elements in one test entry (num_args_tested + 1) |
| + // Number of array elements in one test entry. |
| intptr_t len = result.TestEntryLength(); |
| // IC data array must be null terminated (sentinel entry). |
| const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |