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 |