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