| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 "vm/isolate_reload.h" | 7 #include "vm/isolate_reload.h" |
| 8 #include "vm/log.h" | 8 #include "vm/log.h" |
| 9 #include "vm/resolver.h" | 9 #include "vm/resolver.h" |
| 10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 Array::Handle(Array::RawCast(saved_ic_data.At(0))); | 49 Array::Handle(Array::RawCast(saved_ic_data.At(0))); |
| 50 ASSERT(!edge_counters_array.IsNull()); | 50 ASSERT(!edge_counters_array.IsNull()); |
| 51 // Fill edge counters array with zeros. | 51 // Fill edge counters array with zeros. |
| 52 const Smi& zero = Smi::Handle(Smi::New(0)); | 52 const Smi& zero = Smi::Handle(Smi::New(0)); |
| 53 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { | 53 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { |
| 54 edge_counters_array.SetAt(i, zero); | 54 edge_counters_array.SetAt(i, zero); |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 void Code::ResetICDatas(const Function& function) const { | 59 static void ClearICs(const Function& function, const Code& code) { |
| 60 // Iterate over the Code's object pool and reset all ICDatas. | 60 if (function.ic_data_array() == Array::null()) { |
| 61 #ifdef TARGET_ARCH_IA32 | 61 return; // Already reset in an earlier round. |
| 62 // IA32 does not have an object pool, but, we can iterate over all | 62 } |
| 63 // embedded objects by using the variable length data section. | 63 |
| 64 if (!is_alive()) { | 64 Thread* thread = Thread::Current(); |
| 65 Zone* zone = thread->zone(); |
| 66 |
| 67 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 68 new(zone) ZoneGrowableArray<const ICData*>(); |
| 69 function.RestoreICDataMap(ic_data_array, false /* clone ic-data */); |
| 70 if (ic_data_array->length() == 0) { |
| 65 return; | 71 return; |
| 66 } | 72 } |
| 67 const Instructions& instrs = Instructions::Handle(instructions()); | 73 const PcDescriptors& descriptors = |
| 68 ASSERT(!instrs.IsNull()); | 74 PcDescriptors::Handle(code.pc_descriptors()); |
| 69 uword base_address = instrs.EntryPoint(); | 75 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall | |
| 70 Object& object = Object::Handle(); | 76 RawPcDescriptors::kUnoptStaticCall); |
| 71 intptr_t offsets_length = pointer_offsets_length(); | 77 while (iter.MoveNext()) { |
| 72 const int32_t* offsets = raw_ptr()->data(); | 78 const ICData* ic_data = (*ic_data_array)[iter.DeoptId()]; |
| 73 for (intptr_t i = 0; i < offsets_length; i++) { | 79 if (ic_data == NULL) { |
| 74 int32_t offset = offsets[i]; | |
| 75 RawObject** object_ptr = | |
| 76 reinterpret_cast<RawObject**>(base_address + offset); | |
| 77 RawObject* raw_object = *object_ptr; | |
| 78 if (!raw_object->IsHeapObject()) { | |
| 79 continue; | 80 continue; |
| 80 } | 81 } |
| 81 object = raw_object; | 82 bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall; |
| 82 if (object.IsICData()) { | 83 ic_data->Reset(is_static_call); |
| 83 ICData::Cast(object).Reset(); | |
| 84 } | |
| 85 } | 84 } |
| 86 #else | |
| 87 const ObjectPool& pool = ObjectPool::Handle(object_pool()); | |
| 88 Object& object = Object::Handle(); | |
| 89 ASSERT(!pool.IsNull()); | |
| 90 for (intptr_t i = 0; i < pool.Length(); i++) { | |
| 91 ObjectPool::EntryType entry_type = pool.InfoAt(i); | |
| 92 if (entry_type != ObjectPool::kTaggedObject) { | |
| 93 continue; | |
| 94 } | |
| 95 object = pool.ObjectAt(i); | |
| 96 if (object.IsICData()) { | |
| 97 ICData::Cast(object).Reset(); | |
| 98 } | |
| 99 } | |
| 100 #endif | |
| 101 } | 85 } |
| 102 | 86 |
| 103 | 87 |
| 88 void Function::FillICDataWithSentinels(const Code& code) const { |
| 89 ASSERT(code.raw() == CurrentCode()); |
| 90 ClearICs(*this, code); |
| 91 } |
| 92 |
| 93 |
| 104 void Class::CopyStaticFieldValues(const Class& old_cls) const { | 94 void Class::CopyStaticFieldValues(const Class& old_cls) const { |
| 105 // We only update values for non-enum classes. | 95 // We only update values for non-enum classes. |
| 106 const bool update_values = !is_enum_class(); | 96 const bool update_values = !is_enum_class(); |
| 107 | 97 |
| 108 IsolateReloadContext* reload_context = Isolate::Current()->reload_context(); | 98 IsolateReloadContext* reload_context = Isolate::Current()->reload_context(); |
| 109 ASSERT(reload_context != NULL); | 99 ASSERT(reload_context != NULL); |
| 110 | 100 |
| 111 const Array& old_field_list = Array::Handle(old_cls.fields()); | 101 const Array& old_field_list = Array::Handle(old_cls.fields()); |
| 112 Field& old_field = Field::Handle(); | 102 Field& old_field = Field::Handle(); |
| 113 String& old_name = String::Handle(); | 103 String& old_name = String::Handle(); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 } | 506 } |
| 517 | 507 |
| 518 | 508 |
| 519 bool Library::CanReload(const Library& replacement) const { | 509 bool Library::CanReload(const Library& replacement) const { |
| 520 return true; | 510 return true; |
| 521 } | 511 } |
| 522 | 512 |
| 523 | 513 |
| 524 static const Function* static_call_target = NULL; | 514 static const Function* static_call_target = NULL; |
| 525 | 515 |
| 526 void ICData::Reset() const { | 516 void ICData::Reset(bool is_static_call) const { |
| 527 if (is_static_call()) { | 517 // TODO(johnmccutchan): ICData should know whether or not it's for a |
| 518 // static call. |
| 519 if (is_static_call) { |
| 528 const Function& old_target = Function::Handle(GetTargetAt(0)); | 520 const Function& old_target = Function::Handle(GetTargetAt(0)); |
| 529 if (old_target.IsNull()) { | 521 if (old_target.IsNull()) { |
| 530 FATAL("old_target is NULL.\n"); | 522 FATAL("old_target is NULL.\n"); |
| 531 } | 523 } |
| 532 static_call_target = &old_target; | 524 static_call_target = &old_target; |
| 533 if (!old_target.is_static()) { | 525 if (!old_target.is_static()) { |
| 534 // TODO(johnmccutchan): Improve this. | 526 // TODO(johnmccutchan): Improve this. |
| 535 TIR_Print("Cannot rebind super-call to %s from %s\n", | 527 TIR_Print("Cannot rebind super-call to %s from %s\n", |
| 536 old_target.ToCString(), | 528 old_target.ToCString(), |
| 537 Object::Handle(Owner()).ToCString()); | 529 Object::Handle(Owner()).ToCString()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 550 } | 542 } |
| 551 ClearAndSetStaticTarget(new_target); | 543 ClearAndSetStaticTarget(new_target); |
| 552 } else { | 544 } else { |
| 553 ClearWithSentinel(); | 545 ClearWithSentinel(); |
| 554 } | 546 } |
| 555 } | 547 } |
| 556 | 548 |
| 557 #endif // !PRODUCT | 549 #endif // !PRODUCT |
| 558 | 550 |
| 559 } // namespace dart. | 551 } // namespace dart. |
| OLD | NEW |