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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 ASSERT(!edge_counters_array.IsNull()); | 51 ASSERT(!edge_counters_array.IsNull()); |
52 // Fill edge counters array with zeros. | 52 // Fill edge counters array with zeros. |
53 const Smi& zero = Smi::Handle(Smi::New(0)); | 53 const Smi& zero = Smi::Handle(Smi::New(0)); |
54 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { | 54 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { |
55 edge_counters_array.SetAt(i, zero); | 55 edge_counters_array.SetAt(i, zero); |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 void Code::ResetICDatas(Zone* zone) const { | 60 void Code::ResetICDatas(Zone* zone) const { |
61 // Iterate over the Code's object pool and reset all ICDatas. | 61 // Iterate over the Code's object pool and reset all ICDatas. |
62 #ifdef TARGET_ARCH_IA32 | 62 #ifdef TARGET_ARCH_IA32 |
63 // IA32 does not have an object pool, but, we can iterate over all | 63 // IA32 does not have an object pool, but, we can iterate over all |
64 // embedded objects by using the variable length data section. | 64 // embedded objects by using the variable length data section. |
65 if (!is_alive()) { | 65 if (!is_alive()) { |
66 return; | 66 return; |
67 } | 67 } |
68 const Instructions& instrs = Instructions::Handle(zone, instructions()); | 68 const Instructions& instrs = Instructions::Handle(zone, instructions()); |
69 ASSERT(!instrs.IsNull()); | 69 ASSERT(!instrs.IsNull()); |
70 uword base_address = instrs.PayloadStart(); | 70 uword base_address = instrs.PayloadStart(); |
71 Object& object = Object::Handle(zone); | 71 Object& object = Object::Handle(zone); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 const Array& my_constants = Array::Handle(constants()); | 154 const Array& my_constants = Array::Handle(constants()); |
155 ASSERT(my_constants.Length() == 0); | 155 ASSERT(my_constants.Length() == 0); |
156 } | 156 } |
157 #endif // defined(DEBUG). | 157 #endif // defined(DEBUG). |
158 // Copy old constants into new class. | 158 // Copy old constants into new class. |
159 const Array& old_constants = Array::Handle(old_cls.constants()); | 159 const Array& old_constants = Array::Handle(old_cls.constants()); |
160 if (old_constants.IsNull() || old_constants.Length() == 0) { | 160 if (old_constants.IsNull() || old_constants.Length() == 0) { |
161 return; | 161 return; |
162 } | 162 } |
163 TIR_Print("Copied %" Pd " canonical constants for class `%s`\n", | 163 TIR_Print("Copied %" Pd " canonical constants for class `%s`\n", |
164 old_constants.Length(), | 164 old_constants.Length(), ToCString()); |
165 ToCString()); | |
166 set_constants(old_constants); | 165 set_constants(old_constants); |
167 } | 166 } |
168 | 167 |
169 | 168 |
170 void Class::CopyCanonicalType(const Class& old_cls) const { | 169 void Class::CopyCanonicalType(const Class& old_cls) const { |
171 const Type& old_canonical_type = Type::Handle(old_cls.canonical_type()); | 170 const Type& old_canonical_type = Type::Handle(old_cls.canonical_type()); |
172 if (old_canonical_type.IsNull()) { | 171 if (old_canonical_type.IsNull()) { |
173 return; | 172 return; |
174 } | 173 } |
175 set_canonical_type(old_canonical_type); | 174 set_canonical_type(old_canonical_type); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 230 |
232 Array& enum_fields = Array::Handle(zone); | 231 Array& enum_fields = Array::Handle(zone); |
233 Field& field = Field::Handle(zone); | 232 Field& field = Field::Handle(zone); |
234 String& enum_ident = String::Handle(); | 233 String& enum_ident = String::Handle(); |
235 Instance& old_enum_value = Instance::Handle(zone); | 234 Instance& old_enum_value = Instance::Handle(zone); |
236 Instance& enum_value = Instance::Handle(zone); | 235 Instance& enum_value = Instance::Handle(zone); |
237 // The E.values array. | 236 // The E.values array. |
238 Instance& old_enum_values = Instance::Handle(zone); | 237 Instance& old_enum_values = Instance::Handle(zone); |
239 // The E.values array. | 238 // The E.values array. |
240 Instance& enum_values = Instance::Handle(zone); | 239 Instance& enum_values = Instance::Handle(zone); |
241 Array& enum_map_storage = Array::Handle(zone, | 240 Array& enum_map_storage = |
242 HashTables::New<UnorderedHashMap<EnumMapTraits> >(4)); | 241 Array::Handle(zone, HashTables::New<UnorderedHashMap<EnumMapTraits> >(4)); |
243 ASSERT(!enum_map_storage.IsNull()); | 242 ASSERT(!enum_map_storage.IsNull()); |
244 | 243 |
245 TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString()); | 244 TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString()); |
246 | 245 |
247 { | 246 { |
248 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); | 247 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); |
249 // Build a map of all enum name -> old enum instance. | 248 // Build a map of all enum name -> old enum instance. |
250 enum_fields = old_enum.fields(); | 249 enum_fields = old_enum.fields(); |
251 for (intptr_t i = 0; i < enum_fields.Length(); i++) { | 250 for (intptr_t i = 0; i < enum_fields.Length(); i++) { |
252 field = Field::RawCast(enum_fields.At(i)); | 251 field = Field::RawCast(enum_fields.At(i)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 enum_map_storage = enum_map.Release().raw(); | 308 enum_map_storage = enum_map.Release().raw(); |
310 } | 309 } |
311 | 310 |
312 // Map the old E.values array to the new E.values array. | 311 // Map the old E.values array to the new E.values array. |
313 ASSERT(!old_enum_values.IsNull()); | 312 ASSERT(!old_enum_values.IsNull()); |
314 ASSERT(!enum_values.IsNull()); | 313 ASSERT(!enum_values.IsNull()); |
315 reload_context->AddEnumBecomeMapping(old_enum_values, enum_values); | 314 reload_context->AddEnumBecomeMapping(old_enum_values, enum_values); |
316 | 315 |
317 if (enums_deleted && FLAG_trace_reload_verbose) { | 316 if (enums_deleted && FLAG_trace_reload_verbose) { |
318 // TODO(johnmccutchan): Add this to the reload 'notices' list. | 317 // TODO(johnmccutchan): Add this to the reload 'notices' list. |
319 VTIR_Print("The following enum values were deleted and are forever lost in " | 318 VTIR_Print( |
320 "the heap:\n"); | 319 "The following enum values were deleted and are forever lost in " |
| 320 "the heap:\n"); |
321 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); | 321 UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw()); |
322 UnorderedHashMap<EnumMapTraits>::Iterator it(&enum_map); | 322 UnorderedHashMap<EnumMapTraits>::Iterator it(&enum_map); |
323 while (it.MoveNext()) { | 323 while (it.MoveNext()) { |
324 const intptr_t entry = it.Current(); | 324 const intptr_t entry = it.Current(); |
325 enum_ident = String::RawCast(enum_map.GetKey(entry)); | 325 enum_ident = String::RawCast(enum_map.GetKey(entry)); |
326 ASSERT(!enum_ident.IsNull()); | 326 ASSERT(!enum_ident.IsNull()); |
327 } | 327 } |
328 enum_map.Release(); | 328 enum_map.Release(); |
329 } | 329 } |
330 } | 330 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 void Class::MigrateImplicitStaticClosures(IsolateReloadContext* irc, | 378 void Class::MigrateImplicitStaticClosures(IsolateReloadContext* irc, |
379 const Class& new_cls) const { | 379 const Class& new_cls) const { |
380 const Array& funcs = Array::Handle(functions()); | 380 const Array& funcs = Array::Handle(functions()); |
381 Function& old_func = Function::Handle(); | 381 Function& old_func = Function::Handle(); |
382 String& selector = String::Handle(); | 382 String& selector = String::Handle(); |
383 Function& new_func = Function::Handle(); | 383 Function& new_func = Function::Handle(); |
384 Instance& old_closure = Instance::Handle(); | 384 Instance& old_closure = Instance::Handle(); |
385 Instance& new_closure = Instance::Handle(); | 385 Instance& new_closure = Instance::Handle(); |
386 for (intptr_t i = 0; i < funcs.Length(); i++) { | 386 for (intptr_t i = 0; i < funcs.Length(); i++) { |
387 old_func ^= funcs.At(i); | 387 old_func ^= funcs.At(i); |
388 if (old_func.is_static() && | 388 if (old_func.is_static() && old_func.HasImplicitClosureFunction()) { |
389 old_func.HasImplicitClosureFunction()) { | |
390 selector = old_func.name(); | 389 selector = old_func.name(); |
391 new_func = new_cls.LookupFunction(selector); | 390 new_func = new_cls.LookupFunction(selector); |
392 if (!new_func.IsNull() && new_func.is_static()) { | 391 if (!new_func.IsNull() && new_func.is_static()) { |
393 old_func = old_func.ImplicitClosureFunction(); | 392 old_func = old_func.ImplicitClosureFunction(); |
394 old_closure = old_func.ImplicitStaticClosure(); | 393 old_closure = old_func.ImplicitStaticClosure(); |
395 new_func = new_func.ImplicitClosureFunction(); | 394 new_func = new_func.ImplicitClosureFunction(); |
396 new_closure = new_func.ImplicitStaticClosure(); | 395 new_closure = new_func.ImplicitStaticClosure(); |
397 if (old_closure.IsCanonical()) { | 396 if (old_closure.IsCanonical()) { |
398 new_closure.SetCanonical(); | 397 new_closure.SetCanonical(); |
399 } | 398 } |
400 irc->AddBecomeMapping(old_closure, new_closure); | 399 irc->AddBecomeMapping(old_closure, new_closure); |
401 } | 400 } |
402 } | 401 } |
403 } | 402 } |
404 } | 403 } |
405 | 404 |
406 | 405 |
407 class EnumClassConflict : public ClassReasonForCancelling { | 406 class EnumClassConflict : public ClassReasonForCancelling { |
408 public: | 407 public: |
409 EnumClassConflict(Zone* zone, const Class& from, const Class& to) | 408 EnumClassConflict(Zone* zone, const Class& from, const Class& to) |
410 : ClassReasonForCancelling(zone, from, to) { } | 409 : ClassReasonForCancelling(zone, from, to) {} |
411 | 410 |
412 RawString* ToString() { | 411 RawString* ToString() { |
413 return String::NewFormatted( | 412 return String::NewFormatted( |
414 from_.is_enum_class() | 413 from_.is_enum_class() |
415 ? "Enum class cannot be redefined to be a non-enum class: %s" | 414 ? "Enum class cannot be redefined to be a non-enum class: %s" |
416 : "Class cannot be redefined to be a enum class: %s", | 415 : "Class cannot be redefined to be a enum class: %s", |
417 from_.ToCString()); | 416 from_.ToCString()); |
418 } | 417 } |
419 }; | 418 }; |
420 | 419 |
421 | 420 |
422 class EnsureFinalizedError : public ClassReasonForCancelling { | 421 class EnsureFinalizedError : public ClassReasonForCancelling { |
423 public: | 422 public: |
424 EnsureFinalizedError(Zone* zone, | 423 EnsureFinalizedError(Zone* zone, |
425 const Class& from, | 424 const Class& from, |
426 const Class& to, | 425 const Class& to, |
427 const Error& error) | 426 const Error& error) |
428 : ClassReasonForCancelling(zone, from, to), error_(error) { } | 427 : ClassReasonForCancelling(zone, from, to), error_(error) {} |
429 | 428 |
430 private: | 429 private: |
431 const Error& error_; | 430 const Error& error_; |
432 | 431 |
433 RawError* ToError() { return error_.raw(); } | 432 RawError* ToError() { return error_.raw(); } |
434 | 433 |
435 RawString* ToString() { | 434 RawString* ToString() { return String::New(error_.ToErrorCString()); } |
436 return String::New(error_.ToErrorCString()); | |
437 } | |
438 }; | 435 }; |
439 | 436 |
440 | 437 |
441 class NativeFieldsConflict : public ClassReasonForCancelling { | 438 class NativeFieldsConflict : public ClassReasonForCancelling { |
442 public: | 439 public: |
443 NativeFieldsConflict(Zone* zone, const Class& from, const Class& to) | 440 NativeFieldsConflict(Zone* zone, const Class& from, const Class& to) |
444 : ClassReasonForCancelling(zone, from, to) { } | 441 : ClassReasonForCancelling(zone, from, to) {} |
445 | 442 |
446 private: | 443 private: |
447 RawString* ToString() { | 444 RawString* ToString() { |
448 return String::NewFormatted( | 445 return String::NewFormatted("Number of native fields changed in %s", |
449 "Number of native fields changed in %s", from_.ToCString()); | 446 from_.ToCString()); |
450 } | 447 } |
451 }; | 448 }; |
452 | 449 |
453 | 450 |
454 class TypeParametersChanged : public ClassReasonForCancelling { | 451 class TypeParametersChanged : public ClassReasonForCancelling { |
455 public: | 452 public: |
456 TypeParametersChanged(Zone* zone, const Class& from, const Class& to) | 453 TypeParametersChanged(Zone* zone, const Class& from, const Class& to) |
457 : ClassReasonForCancelling(zone, from, to) {} | 454 : ClassReasonForCancelling(zone, from, to) {} |
458 | 455 |
459 RawString* ToString() { | 456 RawString* ToString() { |
460 return String::NewFormatted( | 457 return String::NewFormatted( |
461 "Limitation: type parameters have changed for %s", from_.ToCString()); | 458 "Limitation: type parameters have changed for %s", from_.ToCString()); |
462 } | 459 } |
463 | 460 |
464 void AppendTo(JSONArray* array) { | 461 void AppendTo(JSONArray* array) { |
465 JSONObject jsobj(array); | 462 JSONObject jsobj(array); |
466 jsobj.AddProperty("type", "ReasonForCancellingReload"); | 463 jsobj.AddProperty("type", "ReasonForCancellingReload"); |
467 jsobj.AddProperty("kind", "TypeParametersChanged"); | 464 jsobj.AddProperty("kind", "TypeParametersChanged"); |
468 jsobj.AddProperty("class", to_); | 465 jsobj.AddProperty("class", to_); |
469 jsobj.AddProperty("message", | 466 jsobj.AddProperty("message", |
470 "Limitation: changing type parameters " | 467 "Limitation: changing type parameters " |
471 "does not work with hot reload."); | 468 "does not work with hot reload."); |
472 } | 469 } |
473 }; | 470 }; |
474 | 471 |
475 | 472 |
476 class PreFinalizedConflict : public ClassReasonForCancelling { | 473 class PreFinalizedConflict : public ClassReasonForCancelling { |
477 public: | 474 public: |
478 PreFinalizedConflict(Zone* zone, const Class& from, const Class& to) | 475 PreFinalizedConflict(Zone* zone, const Class& from, const Class& to) |
479 : ClassReasonForCancelling(zone, from, to) {} | 476 : ClassReasonForCancelling(zone, from, to) {} |
480 | 477 |
481 private: | 478 private: |
482 RawString* ToString() { | 479 RawString* ToString() { |
483 return String::NewFormatted( | 480 return String::NewFormatted( |
484 "Original class ('%s') is prefinalized and replacement class " | 481 "Original class ('%s') is prefinalized and replacement class " |
485 "('%s') is not ", | 482 "('%s') is not ", |
486 from_.ToCString(), to_.ToCString()); | 483 from_.ToCString(), to_.ToCString()); |
487 } | 484 } |
488 }; | 485 }; |
489 | 486 |
490 | 487 |
491 class InstanceSizeConflict : public ClassReasonForCancelling { | 488 class InstanceSizeConflict : public ClassReasonForCancelling { |
492 public: | 489 public: |
493 InstanceSizeConflict(Zone* zone, const Class& from, const Class& to) | 490 InstanceSizeConflict(Zone* zone, const Class& from, const Class& to) |
494 : ClassReasonForCancelling(zone, from, to) {} | 491 : ClassReasonForCancelling(zone, from, to) {} |
495 | 492 |
496 private: | 493 private: |
497 RawString* ToString() { | 494 RawString* ToString() { |
498 return String::NewFormatted( | 495 return String::NewFormatted("Instance size mismatch between '%s' (%" Pd |
499 "Instance size mismatch between '%s' (%" Pd ") and replacement " | 496 ") and replacement " |
500 "'%s' ( %" Pd ")", | 497 "'%s' ( %" Pd ")", |
501 from_.ToCString(), | 498 from_.ToCString(), from_.instance_size(), |
502 from_.instance_size(), | 499 to_.ToCString(), to_.instance_size()); |
503 to_.ToCString(), | |
504 to_.instance_size()); | |
505 } | 500 } |
506 }; | 501 }; |
507 | 502 |
508 | 503 |
509 class UnimplementedDeferredLibrary : public ReasonForCancelling { | 504 class UnimplementedDeferredLibrary : public ReasonForCancelling { |
510 public: | 505 public: |
511 UnimplementedDeferredLibrary(Zone* zone, | 506 UnimplementedDeferredLibrary(Zone* zone, |
512 const Library& from, | 507 const Library& from, |
513 const Library& to, | 508 const Library& to, |
514 const String& name) | 509 const String& name) |
(...skipping 15 matching lines...) Expand all Loading... |
530 }; | 525 }; |
531 | 526 |
532 | 527 |
533 // This is executed before interating over the instances. | 528 // This is executed before interating over the instances. |
534 void Class::CheckReload(const Class& replacement, | 529 void Class::CheckReload(const Class& replacement, |
535 IsolateReloadContext* context) const { | 530 IsolateReloadContext* context) const { |
536 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); | 531 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); |
537 | 532 |
538 // Class cannot change enum property. | 533 // Class cannot change enum property. |
539 if (is_enum_class() != replacement.is_enum_class()) { | 534 if (is_enum_class() != replacement.is_enum_class()) { |
540 context->AddReasonForCancelling( | 535 context->AddReasonForCancelling(new (context->zone()) EnumClassConflict( |
541 new(context->zone()) | 536 context->zone(), *this, replacement)); |
542 EnumClassConflict(context->zone(), *this, replacement)); | |
543 return; | 537 return; |
544 } | 538 } |
545 | 539 |
546 if (is_finalized()) { | 540 if (is_finalized()) { |
547 // Ensure the replacement class is also finalized. | 541 // Ensure the replacement class is also finalized. |
548 const Error& error = | 542 const Error& error = |
549 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); | 543 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); |
550 if (!error.IsNull()) { | 544 if (!error.IsNull()) { |
551 context->AddReasonForCancelling( | 545 context->AddReasonForCancelling( |
552 new(context->zone()) | 546 new (context->zone()) |
553 EnsureFinalizedError(context->zone(), *this, replacement, error)); | 547 EnsureFinalizedError(context->zone(), *this, replacement, error)); |
554 return; // No reason to check other properties. | 548 return; // No reason to check other properties. |
555 } | 549 } |
556 ASSERT(replacement.is_finalized()); | 550 ASSERT(replacement.is_finalized()); |
557 TIR_Print("Finalized replacement class for %s\n", ToCString()); | 551 TIR_Print("Finalized replacement class for %s\n", ToCString()); |
558 } | 552 } |
559 | 553 |
560 // Native field count cannot change. | 554 // Native field count cannot change. |
561 if (num_native_fields() != replacement.num_native_fields()) { | 555 if (num_native_fields() != replacement.num_native_fields()) { |
562 context->AddReasonForCancelling( | 556 context->AddReasonForCancelling(new (context->zone()) NativeFieldsConflict( |
563 new(context->zone()) | 557 context->zone(), *this, replacement)); |
564 NativeFieldsConflict(context->zone(), *this, replacement)); | 558 return; |
565 return; | |
566 } | 559 } |
567 | 560 |
568 // Just checking. | 561 // Just checking. |
569 ASSERT(is_enum_class() == replacement.is_enum_class()); | 562 ASSERT(is_enum_class() == replacement.is_enum_class()); |
570 ASSERT(num_native_fields() == replacement.num_native_fields()); | 563 ASSERT(num_native_fields() == replacement.num_native_fields()); |
571 | 564 |
572 if (is_finalized()) { | 565 if (is_finalized()) { |
573 if (!CanReloadFinalized(replacement, context)) return; | 566 if (!CanReloadFinalized(replacement, context)) return; |
574 } | 567 } |
575 if (is_prefinalized()) { | 568 if (is_prefinalized()) { |
576 if (!CanReloadPreFinalized(replacement, context)) return; | 569 if (!CanReloadPreFinalized(replacement, context)) return; |
577 } | 570 } |
578 ASSERT(is_finalized() == replacement.is_finalized()); | 571 ASSERT(is_finalized() == replacement.is_finalized()); |
579 TIR_Print("Class `%s` can be reloaded (%" Pd " and %" Pd ")\n", | 572 TIR_Print("Class `%s` can be reloaded (%" Pd " and %" Pd ")\n", ToCString(), |
580 ToCString(), id(), replacement.id()); | 573 id(), replacement.id()); |
581 } | 574 } |
582 | 575 |
583 | 576 |
584 | |
585 bool Class::RequiresInstanceMorphing(const Class& replacement) const { | 577 bool Class::RequiresInstanceMorphing(const Class& replacement) const { |
586 // Get the field maps for both classes. These field maps walk the class | 578 // Get the field maps for both classes. These field maps walk the class |
587 // hierarchy. | 579 // hierarchy. |
588 const Array& fields = Array::Handle(OffsetToFieldMap()); | 580 const Array& fields = Array::Handle(OffsetToFieldMap()); |
589 const Array& replacement_fields | 581 const Array& replacement_fields = |
590 = Array::Handle(replacement.OffsetToFieldMap()); | 582 Array::Handle(replacement.OffsetToFieldMap()); |
591 | 583 |
592 // Check that the size of the instance is the same. | 584 // Check that the size of the instance is the same. |
593 if (fields.Length() != replacement_fields.Length()) return true; | 585 if (fields.Length() != replacement_fields.Length()) return true; |
594 | 586 |
595 // Check that we have the same next field offset. This check is not | 587 // Check that we have the same next field offset. This check is not |
596 // redundant with the one above because the instance OffsetToFieldMap | 588 // redundant with the one above because the instance OffsetToFieldMap |
597 // array length is based on the instance size (which may be aligned up). | 589 // array length is based on the instance size (which may be aligned up). |
598 if (next_field_offset() != replacement.next_field_offset()) return true; | 590 if (next_field_offset() != replacement.next_field_offset()) return true; |
599 | 591 |
600 // Verify that field names / offsets match across the entire hierarchy. | 592 // Verify that field names / offsets match across the entire hierarchy. |
(...skipping 19 matching lines...) Expand all Loading... |
620 | 612 |
621 bool Class::CanReloadFinalized(const Class& replacement, | 613 bool Class::CanReloadFinalized(const Class& replacement, |
622 IsolateReloadContext* context) const { | 614 IsolateReloadContext* context) const { |
623 // Make sure the declaration types matches for the two classes. | 615 // Make sure the declaration types matches for the two classes. |
624 // ex. class A<int,B> {} cannot be replace with class A<B> {}. | 616 // ex. class A<int,B> {} cannot be replace with class A<B> {}. |
625 | 617 |
626 const AbstractType& dt = AbstractType::Handle(DeclarationType()); | 618 const AbstractType& dt = AbstractType::Handle(DeclarationType()); |
627 const AbstractType& replacement_dt = | 619 const AbstractType& replacement_dt = |
628 AbstractType::Handle(replacement.DeclarationType()); | 620 AbstractType::Handle(replacement.DeclarationType()); |
629 if (!dt.Equals(replacement_dt)) { | 621 if (!dt.Equals(replacement_dt)) { |
630 context->AddReasonForCancelling( | 622 context->AddReasonForCancelling(new (context->zone()) TypeParametersChanged( |
631 new(context->zone()) | 623 context->zone(), *this, replacement)); |
632 TypeParametersChanged(context->zone(), *this, replacement)); | |
633 return false; | 624 return false; |
634 } | 625 } |
635 if (RequiresInstanceMorphing(replacement)) { | 626 if (RequiresInstanceMorphing(replacement)) { |
636 context->AddInstanceMorpher( | 627 context->AddInstanceMorpher(new (context->zone()) InstanceMorpher( |
637 new(context->zone()) | 628 context->zone(), *this, replacement)); |
638 InstanceMorpher(context->zone(), *this, replacement)); | |
639 } | 629 } |
640 return true; | 630 return true; |
641 } | 631 } |
642 | 632 |
643 | 633 |
644 bool Class::CanReloadPreFinalized(const Class& replacement, | 634 bool Class::CanReloadPreFinalized(const Class& replacement, |
645 IsolateReloadContext* context) const { | 635 IsolateReloadContext* context) const { |
646 // The replacement class must also prefinalized. | 636 // The replacement class must also prefinalized. |
647 if (!replacement.is_prefinalized()) { | 637 if (!replacement.is_prefinalized()) { |
648 context->AddReasonForCancelling( | 638 context->AddReasonForCancelling(new (context->zone()) PreFinalizedConflict( |
649 new(context->zone()) | 639 context->zone(), *this, replacement)); |
650 PreFinalizedConflict(context->zone(), *this, replacement)); | 640 return false; |
651 return false; | |
652 } | 641 } |
653 // Check the instance sizes are equal. | 642 // Check the instance sizes are equal. |
654 if (instance_size() != replacement.instance_size()) { | 643 if (instance_size() != replacement.instance_size()) { |
655 context->AddReasonForCancelling( | 644 context->AddReasonForCancelling(new (context->zone()) InstanceSizeConflict( |
656 new(context->zone()) | 645 context->zone(), *this, replacement)); |
657 InstanceSizeConflict(context->zone(), *this, replacement)); | 646 return false; |
658 return false; | |
659 } | 647 } |
660 return true; | 648 return true; |
661 } | 649 } |
662 | 650 |
663 | 651 |
664 void Library::CheckReload(const Library& replacement, | 652 void Library::CheckReload(const Library& replacement, |
665 IsolateReloadContext* context) const { | 653 IsolateReloadContext* context) const { |
666 // TODO(26878): If the replacement library uses deferred loading, | 654 // TODO(26878): If the replacement library uses deferred loading, |
667 // reject it. We do not yet support reloading deferred libraries. | 655 // reject it. We do not yet support reloading deferred libraries. |
668 LibraryPrefix& prefix = LibraryPrefix::Handle(); | 656 LibraryPrefix& prefix = LibraryPrefix::Handle(); |
669 LibraryPrefixIterator it(replacement); | 657 LibraryPrefixIterator it(replacement); |
670 while (it.HasNext()) { | 658 while (it.HasNext()) { |
671 prefix = it.GetNext(); | 659 prefix = it.GetNext(); |
672 if (prefix.is_deferred_load()) { | 660 if (prefix.is_deferred_load()) { |
673 const String& prefix_name = String::Handle(prefix.name()); | 661 const String& prefix_name = String::Handle(prefix.name()); |
674 context->AddReasonForCancelling( | 662 context->AddReasonForCancelling( |
675 new(context->zone()) | 663 new (context->zone()) UnimplementedDeferredLibrary( |
676 UnimplementedDeferredLibrary(context->zone(), | 664 context->zone(), *this, replacement, prefix_name)); |
677 *this, replacement, prefix_name)); | |
678 return; | 665 return; |
679 } | 666 } |
680 } | 667 } |
681 } | 668 } |
682 | 669 |
683 | 670 |
684 static const Function* static_call_target = NULL; | 671 static const Function* static_call_target = NULL; |
685 | 672 |
686 | 673 |
687 void ICData::Reset(Zone* zone) const { | 674 void ICData::Reset(Zone* zone) const { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 cls = cls.SuperClass(); | 721 cls = cls.SuperClass(); |
735 } | 722 } |
736 } else { | 723 } else { |
737 // This can be incorrect if the call site was an unqualified invocation. | 724 // This can be incorrect if the call site was an unqualified invocation. |
738 const Class& cls = Class::Handle(zone, old_target.Owner()); | 725 const Class& cls = Class::Handle(zone, old_target.Owner()); |
739 new_target = cls.LookupStaticFunction(selector); | 726 new_target = cls.LookupStaticFunction(selector); |
740 } | 727 } |
741 | 728 |
742 const Array& args_desc_array = Array::Handle(zone, arguments_descriptor()); | 729 const Array& args_desc_array = Array::Handle(zone, arguments_descriptor()); |
743 ArgumentsDescriptor args_desc(args_desc_array); | 730 ArgumentsDescriptor args_desc(args_desc_array); |
744 if (new_target.IsNull() || | 731 if (new_target.IsNull() || !new_target.AreValidArguments(args_desc, NULL)) { |
745 !new_target.AreValidArguments(args_desc, NULL)) { | |
746 // TODO(rmacnak): Patch to a NSME stub. | 732 // TODO(rmacnak): Patch to a NSME stub. |
747 VTIR_Print("Cannot rebind static call to %s from %s\n", | 733 VTIR_Print("Cannot rebind static call to %s from %s\n", |
748 old_target.ToCString(), | 734 old_target.ToCString(), |
749 Object::Handle(zone, Owner()).ToCString()); | 735 Object::Handle(zone, Owner()).ToCString()); |
750 return; | 736 return; |
751 } | 737 } |
752 ClearAndSetStaticTarget(new_target); | 738 ClearAndSetStaticTarget(new_target); |
753 } else { | 739 } else { |
754 intptr_t num_args = NumArgsTested(); | 740 intptr_t num_args = NumArgsTested(); |
755 if (num_args == 2) { | 741 if (num_args == 2) { |
756 ClearWithSentinel(); | 742 ClearWithSentinel(); |
757 } else { | 743 } else { |
758 const Array& data_array = | 744 const Array& data_array = |
759 Array::Handle(zone, CachedEmptyICDataArray(num_args)); | 745 Array::Handle(zone, CachedEmptyICDataArray(num_args)); |
760 set_ic_data_array(data_array); | 746 set_ic_data_array(data_array); |
761 } | 747 } |
762 } | 748 } |
763 } | 749 } |
764 | 750 |
765 #endif // !PRODUCT | 751 #endif // !PRODUCT |
766 | 752 |
767 } // namespace dart. | 753 } // namespace dart. |
OLD | NEW |