Chromium Code Reviews| 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/isolate_reload.h" | 5 #include "vm/isolate_reload.h" |
| 6 | 6 |
| 7 #include "vm/become.h" | 7 #include "vm/become.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 #define TIMELINE_SCOPE(name) \ | 44 #define TIMELINE_SCOPE(name) \ |
| 45 TimelineDurationScope tds##name(Thread::Current(), \ | 45 TimelineDurationScope tds##name(Thread::Current(), \ |
| 46 Timeline::GetIsolateStream(), \ | 46 Timeline::GetIsolateStream(), \ |
| 47 #name) | 47 #name) |
| 48 | 48 |
| 49 | 49 |
| 50 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) | 50 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) |
| 51 : from_(Class::Handle(zone, from.raw())), | 51 : from_(Class::Handle(zone, from.raw())), |
| 52 to_(Class::Handle(zone, to.raw())), | 52 to_(Class::Handle(zone, to.raw())), |
| 53 mapping_(zone, 0) { | 53 mapping_(zone, 0) { |
| 54 ComputeMapping(); | |
| 55 before_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); | 54 before_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); |
| 56 after_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); | 55 after_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); |
| 56 new_fields_ = new(zone) ZoneGrowableArray<const Field*>(zone, 0); | |
| 57 ASSERT(from_.id() == to_.id()); | 57 ASSERT(from_.id() == to_.id()); |
| 58 cid_ = from_.id(); | 58 cid_ = from_.id(); |
| 59 ComputeMapping(); | |
| 59 } | 60 } |
| 60 | 61 |
| 61 | 62 |
| 62 void InstanceMorpher::AddObject(RawObject* object) const { | 63 void InstanceMorpher::AddObject(RawObject* object) const { |
| 63 ASSERT(object->GetClassId() == cid()); | 64 ASSERT(object->GetClassId() == cid()); |
| 64 const Instance& instance = Instance::Cast(Object::Handle(object)); | 65 const Instance& instance = Instance::Cast(Object::Handle(object)); |
| 65 before_->Add(&instance); | 66 before_->Add(&instance); |
| 66 } | 67 } |
| 67 | 68 |
| 68 | 69 |
| 69 void InstanceMorpher::ComputeMapping() { | 70 void InstanceMorpher::ComputeMapping() { |
| 70 if (from_.NumTypeArguments()) { | 71 if (from_.NumTypeArguments()) { |
| 71 // Add copying of the optional type argument field. | 72 // Add copying of the optional type argument field. |
| 72 intptr_t from_offset = from_.type_arguments_field_offset(); | 73 intptr_t from_offset = from_.type_arguments_field_offset(); |
| 73 ASSERT(from_offset != Class::kNoTypeArguments); | 74 ASSERT(from_offset != Class::kNoTypeArguments); |
| 74 intptr_t to_offset = to_.type_arguments_field_offset(); | 75 intptr_t to_offset = to_.type_arguments_field_offset(); |
| 75 ASSERT(to_offset != Class::kNoTypeArguments); | 76 ASSERT(to_offset != Class::kNoTypeArguments); |
| 76 mapping_.Add(from_offset); | 77 mapping_.Add(from_offset); |
| 77 mapping_.Add(to_offset); | 78 mapping_.Add(to_offset); |
| 78 } | 79 } |
| 79 | 80 |
| 80 // Add copying of the instance fields if matching by name. | 81 // Add copying of the instance fields if matching by name. |
| 81 // Note: currently the type of the fields are ignored. | 82 // Note: currently the type of the fields are ignored. |
| 82 const Array& from_fields = Array::Handle(from_.OffsetToFieldMap()); | 83 const Array& from_fields = Array::Handle(from_.OffsetToFieldMap()); |
| 83 const Array& to_fields = Array::Handle(to_.OffsetToFieldMap()); | 84 const Array& to_fields = Array::Handle(to_.OffsetToFieldMap()); |
| 84 Field& from_field = Field::Handle(); | 85 Field& from_field = Field::Handle(); |
| 85 Field& to_field = Field::Handle(); | 86 Field& to_field = Field::Handle(); |
| 86 String& from_name = String::Handle(); | 87 String& from_name = String::Handle(); |
| 87 String& to_name = String::Handle(); | 88 String& to_name = String::Handle(); |
| 88 for (intptr_t i = 0; i < from_fields.Length(); i++) { | 89 |
| 89 if (from_fields.At(i) == Field::null()) continue; // Ignore non-fields. | 90 // Scan across all the fields in the new class definition. |
| 90 from_field = Field::RawCast(from_fields.At(i)); | 91 for (intptr_t i = 0; i < to_fields.Length(); i++) { |
| 91 ASSERT(from_field.is_instance()); | 92 if (to_fields.At(i) == Field::null()) { |
| 92 from_name = from_field.name(); | 93 continue; // Ignore non-fields. |
| 93 // We now have to find where this field is in the to class. | 94 } |
| 94 for (intptr_t j = 0; j < to_fields.Length(); j++) { | 95 |
| 95 if (to_fields.At(j) == Field::null()) continue; // Ignore non-fields. | 96 // Grab the field's name. |
| 96 to_field = Field::RawCast(to_fields.At(j)); | 97 to_field = Field::RawCast(to_fields.At(i)); |
| 97 ASSERT(to_field.is_instance()); | 98 ASSERT(to_field.is_instance()); |
| 98 to_name = to_field.name(); | 99 to_name = to_field.name(); |
| 100 | |
| 101 // Did this field not exist in the old class definition? | |
| 102 bool new_field = true; | |
| 103 | |
| 104 // Find this field in the old class. | |
| 105 for (intptr_t j = 0; j < from_fields.Length(); j++) { | |
| 106 if (from_fields.At(j) == Field::null()) { | |
| 107 continue; // Ignore non-fields. | |
| 108 } | |
| 109 from_field = Field::RawCast(from_fields.At(j)); | |
| 110 ASSERT(from_field.is_instance()); | |
| 111 from_name = from_field.name(); | |
| 99 if (from_name.Equals(to_name)) { | 112 if (from_name.Equals(to_name)) { |
| 100 // Success | 113 // Success |
| 101 mapping_.Add(from_field.Offset()); | 114 mapping_.Add(from_field.Offset()); |
| 102 mapping_.Add(to_field.Offset()); | 115 mapping_.Add(to_field.Offset()); |
| 116 // Field did exist in old class deifnition. | |
| 117 new_field = false; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 if (new_field) { | |
| 122 if (to_field.has_initializer()) { | |
| 123 // This is a new field with an initializer. | |
| 124 const Field& field = Field::Handle(to_field.raw()); | |
| 125 new_fields_->Add(&field); | |
| 103 } | 126 } |
| 104 } | 127 } |
| 105 } | 128 } |
| 106 } | 129 } |
| 107 | 130 |
| 108 | 131 |
| 109 RawInstance* InstanceMorpher::Morph(const Instance& instance) const { | 132 RawInstance* InstanceMorpher::Morph(const Instance& instance) const { |
| 110 const Instance& result = Instance::Handle(Instance::New(to_)); | 133 const Instance& result = Instance::Handle(Instance::New(to_)); |
| 111 // Morph the context from instance to result using mapping_. | 134 // Morph the context from instance to result using mapping_. |
| 112 for (intptr_t i = 0; i < mapping_.length(); i +=2) { | 135 for (intptr_t i = 0; i < mapping_.length(); i +=2) { |
| 113 intptr_t from_offset = mapping_.At(i); | 136 intptr_t from_offset = mapping_.At(i); |
| 114 intptr_t to_offset = mapping_.At(i+1); | 137 intptr_t to_offset = mapping_.At(i+1); |
| 115 const Object& value = | 138 const Object& value = |
| 116 Object::Handle(instance.RawGetFieldAtOffset(from_offset)); | 139 Object::Handle(instance.RawGetFieldAtOffset(from_offset)); |
| 117 result.RawSetFieldAtOffset(to_offset, value); | 140 result.RawSetFieldAtOffset(to_offset, value); |
| 118 } | 141 } |
| 119 // Convert the instance into a filler object. | 142 // Convert the instance into a filler object. |
| 120 Become::MakeDummyObject(instance); | 143 Become::MakeDummyObject(instance); |
| 121 return result.raw(); | 144 return result.raw(); |
| 122 } | 145 } |
| 123 | 146 |
| 124 | 147 |
| 148 void InstanceMorpher::RunNewFieldInitializers() const { | |
| 149 if ((new_fields_->length() == 0) || (after_->length() == 0)) { | |
| 150 return; | |
| 151 } | |
| 152 | |
| 153 TIR_Print("Running new field initializers for class: %s\n", to_.ToCString()); | |
| 154 String& initializing_expression = String::Handle(); | |
| 155 Function& eval_func = Function::Handle(); | |
| 156 Object& result = Object::Handle(); | |
| 157 // For each new field. | |
| 158 for (intptr_t i = 0; i < new_fields_->length(); i++) { | |
| 159 // Create a function that returns the expression. | |
| 160 const Field* field = new_fields_->At(i); | |
| 161 // Extract the initializing expression. | |
| 162 initializing_expression = field->InitializingExpression(); | |
| 163 TIR_Print("New `%s` has initializing expression `%s`\n", | |
| 164 field->ToCString(), | |
| 165 initializing_expression.ToCString()); | |
| 166 eval_func ^= Function::EvaluateHelper(to_, | |
|
rmacnak
2016/11/09 00:36:32
to_ -> field.owner to get the right scope
Check f
Cutch
2016/11/09 23:20:58
Done.
| |
| 167 initializing_expression, | |
| 168 Array::empty_array(), | |
| 169 true); | |
| 170 for (intptr_t j = 0; j < after_->length(); j++) { | |
| 171 const Instance* instance = after_->At(j); | |
| 172 TIR_Print("Initializing instance %" Pd " / %" Pd "\n", | |
| 173 j + 1, after_->length()); | |
| 174 /// Run the function and assign the field. | |
| 175 result = DartEntry::InvokeFunction(eval_func, Array::empty_array()); | |
|
rmacnak
2016/11/09 00:36:32
fail stop
if (result.IsError()) return result.raw
Cutch
2016/11/09 23:20:58
going with:
log error to standard error
leave fie
| |
| 176 instance->RawSetFieldAtOffset(field->Offset(), result); | |
| 177 } | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 | |
| 125 void InstanceMorpher::CreateMorphedCopies() const { | 182 void InstanceMorpher::CreateMorphedCopies() const { |
| 126 for (intptr_t i = 0; i < before()->length(); i++) { | 183 for (intptr_t i = 0; i < before()->length(); i++) { |
| 127 const Instance& copy = Instance::Handle(Morph(*before()->At(i))); | 184 const Instance& copy = Instance::Handle(Morph(*before()->At(i))); |
| 128 after()->Add(©); | 185 after()->Add(©); |
| 129 } | 186 } |
| 130 } | 187 } |
| 131 | 188 |
| 132 | 189 |
| 133 void InstanceMorpher::DumpFormatFor(const Class& cls) const { | 190 void InstanceMorpher::DumpFormatFor(const Class& cls) const { |
| 134 THR_Print("%s\n", cls.ToCString()); | 191 THR_Print("%s\n", cls.ToCString()); |
| (...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 } | 1334 } |
| 1278 ASSERT(index == count); | 1335 ASSERT(index == count); |
| 1279 } | 1336 } |
| 1280 | 1337 |
| 1281 // This is important: The saved class table (describing before objects) | 1338 // This is important: The saved class table (describing before objects) |
| 1282 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt. | 1339 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt. |
| 1283 // Instance will from now be described by the isolate's class table. | 1340 // Instance will from now be described by the isolate's class table. |
| 1284 free(saved_class_table_); | 1341 free(saved_class_table_); |
| 1285 saved_class_table_ = NULL; | 1342 saved_class_table_ = NULL; |
| 1286 Become::ElementsForwardIdentity(before, after); | 1343 Become::ElementsForwardIdentity(before, after); |
| 1344 | |
| 1345 // Run new field initializers on all instances. | |
| 1346 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { | |
| 1347 instance_morphers_.At(i)->RunNewFieldInitializers(); | |
|
rmacnak
2016/11/09 00:36:32
fail stop
Cutch
2016/11/09 23:20:58
Acknowledged.
| |
| 1348 } | |
| 1287 } | 1349 } |
| 1288 | 1350 |
| 1289 | 1351 |
| 1290 bool IsolateReloadContext::ValidateReload() { | 1352 bool IsolateReloadContext::ValidateReload() { |
| 1291 TIMELINE_SCOPE(ValidateReload); | 1353 TIMELINE_SCOPE(ValidateReload); |
| 1292 if (reload_aborted()) return false; | 1354 if (reload_aborted()) return false; |
| 1293 | 1355 |
| 1294 TIR_Print("---- VALIDATING RELOAD\n"); | 1356 TIR_Print("---- VALIDATING RELOAD\n"); |
| 1295 | 1357 |
| 1296 // Validate libraries. | 1358 // Validate libraries. |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1681 ASSERT(!super_cls.IsNull()); | 1743 ASSERT(!super_cls.IsNull()); |
| 1682 super_cls.AddDirectSubclass(cls); | 1744 super_cls.AddDirectSubclass(cls); |
| 1683 } | 1745 } |
| 1684 } | 1746 } |
| 1685 } | 1747 } |
| 1686 } | 1748 } |
| 1687 | 1749 |
| 1688 #endif // !PRODUCT | 1750 #endif // !PRODUCT |
| 1689 | 1751 |
| 1690 } // namespace dart | 1752 } // namespace dart |
| OLD | NEW |