Index: runtime/vm/object_reload.cc |
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc |
index 2a49fc2915d1ec9a3caff26d5b2beeca19cbf85f..ba5098a05b62c66449661e430a21bd44d7834d95 100644 |
--- a/runtime/vm/object_reload.cc |
+++ b/runtime/vm/object_reload.cc |
@@ -56,38 +56,48 @@ void Function::ZeroEdgeCounters() const { |
} |
-static void ClearICs(const Function& function, const Code& code) { |
- if (function.ic_data_array() == Array::null()) { |
- return; // Already reset in an earlier round. |
- } |
- |
- Thread* thread = Thread::Current(); |
- Zone* zone = thread->zone(); |
- |
- ZoneGrowableArray<const ICData*>* ic_data_array = |
- new(zone) ZoneGrowableArray<const ICData*>(); |
- function.RestoreICDataMap(ic_data_array, false /* clone ic-data */); |
- if (ic_data_array->length() == 0) { |
+void Code::ResetICDatas() const { |
+ // Iterate over the Code's object pool and reset all ICDatas. |
+#ifdef TARGET_ARCH_IA32 |
+ // IA32 does not have an object pool, but, we can iterate over all |
+ // embedded objects by using the variable length data section. |
+ if (!is_alive()) { |
return; |
} |
- const PcDescriptors& descriptors = |
- PcDescriptors::Handle(code.pc_descriptors()); |
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall | |
- RawPcDescriptors::kUnoptStaticCall); |
- while (iter.MoveNext()) { |
- const ICData* ic_data = (*ic_data_array)[iter.DeoptId()]; |
- if (ic_data == NULL) { |
+ const Instructions& instrs = Instructions::Handle(instructions()); |
+ ASSERT(!instrs.IsNull()); |
+ uword base_address = instrs.EntryPoint(); |
+ Object& object = Object::Handle(); |
+ intptr_t offsets_length = pointer_offsets_length(); |
+ const int32_t* offsets = raw_ptr()->data(); |
+ for (intptr_t i = 0; i < offsets_length; i++) { |
+ int32_t offset = offsets[i]; |
+ RawObject** object_ptr = |
+ reinterpret_cast<RawObject**>(base_address + offset); |
+ RawObject* raw_object = *object_ptr; |
+ if (!raw_object->IsHeapObject()) { |
continue; |
} |
- bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall; |
- ic_data->Reset(is_static_call); |
+ object = raw_object; |
+ if (object.IsICData()) { |
+ ICData::Cast(object).Reset(); |
+ } |
} |
-} |
- |
- |
-void Function::FillICDataWithSentinels(const Code& code) const { |
- ASSERT(code.raw() == CurrentCode()); |
- ClearICs(*this, code); |
+#else |
+ const ObjectPool& pool = ObjectPool::Handle(object_pool()); |
+ Object& object = Object::Handle(); |
+ ASSERT(!pool.IsNull()); |
+ for (intptr_t i = 0; i < pool.Length(); i++) { |
+ ObjectPool::EntryType entry_type = pool.InfoAt(i); |
+ if (entry_type != ObjectPool::kTaggedObject) { |
+ continue; |
+ } |
+ object = pool.ObjectAt(i); |
+ if (object.IsICData()) { |
+ ICData::Cast(object).Reset(); |
+ } |
+ } |
+#endif |
} |
@@ -513,10 +523,8 @@ bool Library::CanReload(const Library& replacement) const { |
static const Function* static_call_target = NULL; |
-void ICData::Reset(bool is_static_call) const { |
- // TODO(johnmccutchan): ICData should know whether or not it's for a |
- // static call. |
- if (is_static_call) { |
+void ICData::Reset() const { |
+ if (is_static_call()) { |
const Function& old_target = Function::Handle(GetTargetAt(0)); |
if (old_target.IsNull()) { |
FATAL("old_target is NULL.\n"); |