| 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/hash_table.h" | 7 #include "vm/hash_table.h" |
| 8 #include "vm/isolate_reload.h" | 8 #include "vm/isolate_reload.h" |
| 9 #include "vm/log.h" | 9 #include "vm/log.h" |
| 10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 Thread* thread = Thread::Current(); | 225 Thread* thread = Thread::Current(); |
| 226 Zone* zone = thread->zone(); | 226 Zone* zone = thread->zone(); |
| 227 IsolateReloadContext* reload_context = Isolate::Current()->reload_context(); | 227 IsolateReloadContext* reload_context = Isolate::Current()->reload_context(); |
| 228 ASSERT(reload_context != NULL); | 228 ASSERT(reload_context != NULL); |
| 229 | 229 |
| 230 Array& enum_fields = Array::Handle(zone); | 230 Array& enum_fields = Array::Handle(zone); |
| 231 Field& field = Field::Handle(zone); | 231 Field& field = Field::Handle(zone); |
| 232 String& enum_ident = String::Handle(); | 232 String& enum_ident = String::Handle(); |
| 233 Instance& old_enum_value = Instance::Handle(zone); | 233 Instance& old_enum_value = Instance::Handle(zone); |
| 234 Instance& enum_value = Instance::Handle(zone); | 234 Instance& enum_value = Instance::Handle(zone); |
| 235 | 235 // The E.values array. |
| 236 Instance& old_enum_values = Instance::Handle(zone); |
| 237 // The E.values array. |
| 238 Instance& enum_values = Instance::Handle(zone); |
| 236 Array& enum_map_storage = Array::Handle(zone, | 239 Array& enum_map_storage = Array::Handle(zone, |
| 237 HashTables::New<UnorderedHashMap<EnumMapTraits> >(4)); | 240 HashTables::New<UnorderedHashMap<EnumMapTraits> >(4)); |
| 238 ASSERT(!enum_map_storage.IsNull()); | 241 ASSERT(!enum_map_storage.IsNull()); |
| 239 | 242 |
| 240 TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString()); | 243 TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString()); |
| 241 | 244 |
| 242 { | 245 { |
| 243 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); | 246 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); |
| 244 // Build a map of all enum name -> old enum instance. | 247 // Build a map of all enum name -> old enum instance. |
| 245 enum_fields = old_enum.fields(); | 248 enum_fields = old_enum.fields(); |
| 246 for (intptr_t i = 0; i < enum_fields.Length(); i++) { | 249 for (intptr_t i = 0; i < enum_fields.Length(); i++) { |
| 247 field = Field::RawCast(enum_fields.At(i)); | 250 field = Field::RawCast(enum_fields.At(i)); |
| 248 enum_ident = field.name(); | 251 enum_ident = field.name(); |
| 249 if (!field.is_static()) { | 252 if (!field.is_static()) { |
| 250 // Enum instances are only held in static fields. | 253 // Enum instances are only held in static fields. |
| 251 continue; | 254 continue; |
| 252 } | 255 } |
| 253 if (enum_ident.Equals(Symbols::Values())) { | 256 if (enum_ident.Equals(Symbols::Values())) { |
| 257 old_enum_values = field.StaticValue(); |
| 254 // Non-enum instance. | 258 // Non-enum instance. |
| 255 continue; | 259 continue; |
| 256 } | 260 } |
| 257 old_enum_value = field.StaticValue(); | 261 old_enum_value = field.StaticValue(); |
| 258 ASSERT(!old_enum_value.IsNull()); | 262 ASSERT(!old_enum_value.IsNull()); |
| 259 VTIR_Print("Element %s being added to mapping\n", enum_ident.ToCString()); | 263 VTIR_Print("Element %s being added to mapping\n", enum_ident.ToCString()); |
| 260 bool update = enum_map.UpdateOrInsert(enum_ident, old_enum_value); | 264 bool update = enum_map.UpdateOrInsert(enum_ident, old_enum_value); |
| 261 VTIR_Print("Element %s added to mapping\n", enum_ident.ToCString()); | 265 VTIR_Print("Element %s added to mapping\n", enum_ident.ToCString()); |
| 262 ASSERT(!update); | 266 ASSERT(!update); |
| 263 } | 267 } |
| 264 // The storage given to the map may have been reallocated, remember the new | 268 // The storage given to the map may have been reallocated, remember the new |
| 265 // address. | 269 // address. |
| 266 enum_map_storage = enum_map.Release().raw(); | 270 enum_map_storage = enum_map.Release().raw(); |
| 267 } | 271 } |
| 268 | 272 |
| 269 bool enums_deleted = false; | 273 bool enums_deleted = false; |
| 270 { | 274 { |
| 271 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); | 275 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); |
| 272 // Add a become mapping from the old instances to the new instances. | 276 // Add a become mapping from the old instances to the new instances. |
| 273 enum_fields = fields(); | 277 enum_fields = fields(); |
| 274 for (intptr_t i = 0; i < enum_fields.Length(); i++) { | 278 for (intptr_t i = 0; i < enum_fields.Length(); i++) { |
| 275 field = Field::RawCast(enum_fields.At(i)); | 279 field = Field::RawCast(enum_fields.At(i)); |
| 276 enum_ident = field.name(); | 280 enum_ident = field.name(); |
| 277 if (!field.is_static()) { | 281 if (!field.is_static()) { |
| 278 // Enum instances are only held in static fields. | 282 // Enum instances are only held in static fields. |
| 279 continue; | 283 continue; |
| 280 } | 284 } |
| 281 if (enum_ident.Equals(Symbols::Values())) { | 285 if (enum_ident.Equals(Symbols::Values())) { |
| 286 enum_values = field.StaticValue(); |
| 282 // Non-enum instance. | 287 // Non-enum instance. |
| 283 continue; | 288 continue; |
| 284 } | 289 } |
| 285 enum_value = field.StaticValue(); | 290 enum_value = field.StaticValue(); |
| 286 ASSERT(!enum_value.IsNull()); | 291 ASSERT(!enum_value.IsNull()); |
| 287 old_enum_value ^= enum_map.GetOrNull(enum_ident); | 292 old_enum_value ^= enum_map.GetOrNull(enum_ident); |
| 288 if (old_enum_value.IsNull()) { | 293 if (old_enum_value.IsNull()) { |
| 289 VTIR_Print("New element %s was not found in mapping\n", | 294 VTIR_Print("New element %s was not found in mapping\n", |
| 290 enum_ident.ToCString()); | 295 enum_ident.ToCString()); |
| 291 } else { | 296 } else { |
| 292 VTIR_Print("Adding element `%s` to become mapping\n", | 297 VTIR_Print("Adding element `%s` to become mapping\n", |
| 293 enum_ident.ToCString()); | 298 enum_ident.ToCString()); |
| 294 bool removed = enum_map.Remove(enum_ident); | 299 bool removed = enum_map.Remove(enum_ident); |
| 295 ASSERT(removed); | 300 ASSERT(removed); |
| 296 reload_context->AddEnumBecomeMapping(old_enum_value, enum_value); | 301 reload_context->AddEnumBecomeMapping(old_enum_value, enum_value); |
| 297 } | 302 } |
| 298 } | 303 } |
| 299 enums_deleted = enum_map.NumOccupied() > 0; | 304 enums_deleted = enum_map.NumOccupied() > 0; |
| 300 // The storage given to the map may have been reallocated, remember the new | 305 // The storage given to the map may have been reallocated, remember the new |
| 301 // address. | 306 // address. |
| 302 enum_map_storage = enum_map.Release().raw(); | 307 enum_map_storage = enum_map.Release().raw(); |
| 303 } | 308 } |
| 304 | 309 |
| 310 // Map the old E.values array to the new E.values array. |
| 311 ASSERT(!old_enum_values.IsNull()); |
| 312 ASSERT(!enum_values.IsNull()); |
| 313 reload_context->AddEnumBecomeMapping(old_enum_values, enum_values); |
| 314 |
| 305 if (enums_deleted && FLAG_trace_reload_verbose) { | 315 if (enums_deleted && FLAG_trace_reload_verbose) { |
| 306 // TODO(johnmccutchan): Add this to the reload 'notices' list. | 316 // TODO(johnmccutchan): Add this to the reload 'notices' list. |
| 307 VTIR_Print("The following enum values were deleted and are forever lost in " | 317 VTIR_Print("The following enum values were deleted and are forever lost in " |
| 308 "the heap:\n"); | 318 "the heap:\n"); |
| 309 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); | 319 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); |
| 310 UnorderedHashMap<EnumMapTraits>::Iterator it(&enum_map); | 320 UnorderedHashMap<EnumMapTraits>::Iterator it(&enum_map); |
| 311 while (it.MoveNext()) { | 321 while (it.MoveNext()) { |
| 312 const intptr_t entry = it.Current(); | 322 const intptr_t entry = it.Current(); |
| 313 enum_ident = String::RawCast(enum_map.GetKey(entry)); | 323 enum_ident = String::RawCast(enum_map.GetKey(entry)); |
| 314 ASSERT(!enum_ident.IsNull()); | 324 ASSERT(!enum_ident.IsNull()); |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 } | 705 } |
| 696 ClearAndSetStaticTarget(new_target); | 706 ClearAndSetStaticTarget(new_target); |
| 697 } else { | 707 } else { |
| 698 ClearWithSentinel(); | 708 ClearWithSentinel(); |
| 699 } | 709 } |
| 700 } | 710 } |
| 701 | 711 |
| 702 #endif // !PRODUCT | 712 #endif // !PRODUCT |
| 703 | 713 |
| 704 } // namespace dart. | 714 } // namespace dart. |
| OLD | NEW |