| 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");
|
|
|