Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 96ba18a8d3db47e286b932813eb75246d75200d3..02084f8249123ad68c42339ec894d52fda7a33da 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -6920,49 +6920,51 @@ int32_t Function::SourceFingerprint() const { |
void Function::SaveICDataMap( |
- const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data) const { |
- // Compute number of ICData objectsto save. |
- intptr_t count = 0; |
+ const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, |
+ const Array& edge_counters_array) const { |
+ // Compute number of ICData objects to save. |
+ // Store edge counter array in the first slot. |
+ intptr_t count = 1; |
for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
if (deopt_id_to_ic_data[i] != NULL) { |
count++; |
} |
} |
- if (count == 0) { |
- set_ic_data_array(Object::empty_array()); |
- } else { |
- const Array& a = Array::Handle(Array::New(count, Heap::kOld)); |
- INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); |
- count = 0; |
- for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
- if (deopt_id_to_ic_data[i] != NULL) { |
- a.SetAt(count++, *deopt_id_to_ic_data[i]); |
- } |
+ const Array& array = Array::Handle(Array::New(count, Heap::kOld)); |
+ INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); |
+ count = 1; |
+ for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
+ if (deopt_id_to_ic_data[i] != NULL) { |
+ array.SetAt(count++, *deopt_id_to_ic_data[i]); |
} |
- set_ic_data_array(a); |
} |
+ array.SetAt(0, edge_counters_array); |
+ set_ic_data_array(array); |
} |
void Function::RestoreICDataMap( |
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const { |
+ ASSERT(deopt_id_to_ic_data->is_empty()); |
Zone* zone = Thread::Current()->zone(); |
- const Array& saved_icd = Array::Handle(zone, ic_data_array()); |
- if (saved_icd.IsNull() || (saved_icd.Length() == 0)) { |
- deopt_id_to_ic_data->Clear(); |
+ const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); |
+ if (saved_ic_data.IsNull()) { |
return; |
} |
- ICData& icd = ICData::Handle(); |
- icd ^= saved_icd.At(saved_icd.Length() - 1); |
- const intptr_t len = icd.deopt_id() + 1; |
- deopt_id_to_ic_data->SetLength(len); |
- for (intptr_t i = 0; i < len; i++) { |
- (*deopt_id_to_ic_data)[i] = NULL; |
- } |
- for (intptr_t i = 0; i < saved_icd.Length(); i++) { |
- ICData& icd = ICData::ZoneHandle(zone); |
- icd ^= saved_icd.At(i); |
- (*deopt_id_to_ic_data)[icd.deopt_id()] = &icd; |
+ const intptr_t saved_length = saved_ic_data.Length(); |
+ ASSERT(saved_length > 0); |
+ if (saved_length > 1) { |
+ const intptr_t restored_length = ICData::Cast(Object::Handle( |
+ zone, saved_ic_data.At(saved_length - 1))).deopt_id() + 1; |
+ deopt_id_to_ic_data->SetLength(restored_length); |
+ for (intptr_t i = 0; i < restored_length; i++) { |
+ (*deopt_id_to_ic_data)[i] = NULL; |
+ } |
+ for (intptr_t i = 1; i < saved_length; i++) { |
+ ICData& ic_data = ICData::ZoneHandle(zone); |
+ ic_data ^= saved_ic_data.At(i); |
+ (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data; |
+ } |
} |
} |
@@ -6984,12 +6986,12 @@ void Function::ClearICDataArray() const { |
void Function::SetDeoptReasonForAll(intptr_t deopt_id, |
ICData::DeoptReasonId reason) { |
- const Array& icd_array = Array::Handle(ic_data_array()); |
- ICData& icd = ICData::Handle(); |
- for (intptr_t i = 0; i < icd_array.Length(); i++) { |
- icd ^= icd_array.At(i); |
- if (icd.deopt_id() == deopt_id) { |
- icd.AddDeoptReason(reason); |
+ const Array& array = Array::Handle(ic_data_array()); |
+ ICData& ic_data = ICData::Handle(); |
+ for (intptr_t i = 1; i < array.Length(); i++) { |
+ ic_data ^= array.At(i); |
+ if (ic_data.deopt_id() == deopt_id) { |
+ ic_data.AddDeoptReason(reason); |
} |
} |
} |