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 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 new_closure = new_func.ImplicitStaticClosure(); | 384 new_closure = new_func.ImplicitStaticClosure(); |
385 irc->AddBecomeMapping(old_closure, new_closure); | 385 irc->AddBecomeMapping(old_closure, new_closure); |
386 } | 386 } |
387 } | 387 } |
388 } | 388 } |
389 } | 389 } |
390 | 390 |
391 | 391 |
392 class EnumClassConflict : public ClassReasonForCancelling { | 392 class EnumClassConflict : public ClassReasonForCancelling { |
393 public: | 393 public: |
394 EnumClassConflict(const Class& from, const Class& to) | 394 EnumClassConflict(Zone* zone, const Class& from, const Class& to) |
395 : ClassReasonForCancelling(from, to) { } | 395 : ClassReasonForCancelling(zone, from, to) { } |
396 | 396 |
397 RawString* ToString() { | 397 RawString* ToString() { |
398 return String::NewFormatted( | 398 return String::NewFormatted( |
399 from_.is_enum_class() | 399 from_.is_enum_class() |
400 ? "Enum class cannot be redefined to be a non-enum class: %s" | 400 ? "Enum class cannot be redefined to be a non-enum class: %s" |
401 : "Class cannot be redefined to be a enum class: %s", | 401 : "Class cannot be redefined to be a enum class: %s", |
402 from_.ToCString()); | 402 from_.ToCString()); |
403 } | 403 } |
404 }; | 404 }; |
405 | 405 |
406 | 406 |
407 class EnsureFinalizedError : public ClassReasonForCancelling { | 407 class EnsureFinalizedError : public ClassReasonForCancelling { |
408 public: | 408 public: |
409 EnsureFinalizedError(const Class& from, const Class& to, const Error& error) | 409 EnsureFinalizedError(Zone* zone, |
410 : ClassReasonForCancelling(from, to), error_(error) { } | 410 const Class& from, |
| 411 const Class& to, |
| 412 const Error& error) |
| 413 : ClassReasonForCancelling(zone, from, to), error_(error) { } |
411 | 414 |
412 private: | 415 private: |
413 const Error& error_; | 416 const Error& error_; |
414 | 417 |
415 RawError* ToError() { return error_.raw(); } | 418 RawError* ToError() { return error_.raw(); } |
416 | 419 |
417 RawString* ToString() { | 420 RawString* ToString() { |
418 return String::New(error_.ToErrorCString()); | 421 return String::New(error_.ToErrorCString()); |
419 } | 422 } |
420 }; | 423 }; |
421 | 424 |
422 | 425 |
423 class NativeFieldsConflict : public ClassReasonForCancelling { | 426 class NativeFieldsConflict : public ClassReasonForCancelling { |
424 public: | 427 public: |
425 NativeFieldsConflict(const Class& from, const Class& to) | 428 NativeFieldsConflict(Zone* zone, const Class& from, const Class& to) |
426 : ClassReasonForCancelling(from, to) { } | 429 : ClassReasonForCancelling(zone, from, to) { } |
427 | 430 |
428 private: | 431 private: |
429 RawString* ToString() { | 432 RawString* ToString() { |
430 return String::NewFormatted( | 433 return String::NewFormatted( |
431 "Number of native fields changed in %s", from_.ToCString()); | 434 "Number of native fields changed in %s", from_.ToCString()); |
432 } | 435 } |
433 }; | 436 }; |
434 | 437 |
435 | 438 |
436 class TypeParametersChanged : public ClassReasonForCancelling { | 439 class TypeParametersChanged : public ClassReasonForCancelling { |
437 public: | 440 public: |
438 TypeParametersChanged(const Class& from, const Class& to) | 441 TypeParametersChanged(Zone* zone, const Class& from, const Class& to) |
439 : ClassReasonForCancelling(from, to) {} | 442 : ClassReasonForCancelling(zone, from, to) {} |
440 | 443 |
441 RawString* ToString() { | 444 RawString* ToString() { |
442 return String::NewFormatted( | 445 return String::NewFormatted( |
443 "Limitation: type parameters have changed for %s", from_.ToCString()); | 446 "Limitation: type parameters have changed for %s", from_.ToCString()); |
444 } | 447 } |
445 | 448 |
446 void AppendTo(JSONArray* array) { | 449 void AppendTo(JSONArray* array) { |
447 JSONObject jsobj(array); | 450 JSONObject jsobj(array); |
448 jsobj.AddProperty("type", "ReasonForCancellingReload"); | 451 jsobj.AddProperty("type", "ReasonForCancellingReload"); |
449 jsobj.AddProperty("kind", "TypeParametersChanged"); | 452 jsobj.AddProperty("kind", "TypeParametersChanged"); |
450 jsobj.AddProperty("class", to_); | 453 jsobj.AddProperty("class", to_); |
451 jsobj.AddProperty("message", | 454 jsobj.AddProperty("message", |
452 "Limitation: changing type parameters " | 455 "Limitation: changing type parameters " |
453 "does not work with hot reload."); | 456 "does not work with hot reload."); |
454 } | 457 } |
455 }; | 458 }; |
456 | 459 |
457 | 460 |
458 class PreFinalizedConflict : public ClassReasonForCancelling { | 461 class PreFinalizedConflict : public ClassReasonForCancelling { |
459 public: | 462 public: |
460 PreFinalizedConflict(const Class& from, const Class& to) | 463 PreFinalizedConflict(Zone* zone, const Class& from, const Class& to) |
461 : ClassReasonForCancelling(from, to) {} | 464 : ClassReasonForCancelling(zone, from, to) {} |
462 | 465 |
463 private: | 466 private: |
464 RawString* ToString() { | 467 RawString* ToString() { |
465 return String::NewFormatted( | 468 return String::NewFormatted( |
466 "Original class ('%s') is prefinalized and replacement class " | 469 "Original class ('%s') is prefinalized and replacement class " |
467 "('%s') is not ", | 470 "('%s') is not ", |
468 from_.ToCString(), to_.ToCString()); | 471 from_.ToCString(), to_.ToCString()); |
469 } | 472 } |
470 }; | 473 }; |
471 | 474 |
472 | 475 |
473 class InstanceSizeConflict : public ClassReasonForCancelling { | 476 class InstanceSizeConflict : public ClassReasonForCancelling { |
474 public: | 477 public: |
475 InstanceSizeConflict(const Class& from, const Class& to) | 478 InstanceSizeConflict(Zone* zone, const Class& from, const Class& to) |
476 : ClassReasonForCancelling(from, to) {} | 479 : ClassReasonForCancelling(zone, from, to) {} |
477 | 480 |
478 private: | 481 private: |
479 RawString* ToString() { | 482 RawString* ToString() { |
480 return String::NewFormatted( | 483 return String::NewFormatted( |
481 "Instance size mismatch between '%s' (%" Pd ") and replacement " | 484 "Instance size mismatch between '%s' (%" Pd ") and replacement " |
482 "'%s' ( %" Pd ")", | 485 "'%s' ( %" Pd ")", |
483 from_.ToCString(), | 486 from_.ToCString(), |
484 from_.instance_size(), | 487 from_.instance_size(), |
485 to_.ToCString(), | 488 to_.ToCString(), |
486 to_.instance_size()); | 489 to_.instance_size()); |
487 } | 490 } |
488 }; | 491 }; |
489 | 492 |
490 | 493 |
491 class UnimplementedDeferredLibrary : public ReasonForCancelling { | 494 class UnimplementedDeferredLibrary : public ReasonForCancelling { |
492 public: | 495 public: |
493 UnimplementedDeferredLibrary(const Library& from, | 496 UnimplementedDeferredLibrary(Zone* zone, |
| 497 const Library& from, |
494 const Library& to, | 498 const Library& to, |
495 const String& name) | 499 const String& name) |
496 : ReasonForCancelling(), from_(from), to_(to), name_(name) {} | 500 : ReasonForCancelling(zone), from_(from), to_(to), name_(name) {} |
497 | 501 |
498 private: | 502 private: |
499 const Library& from_; | 503 const Library& from_; |
500 const Library& to_; | 504 const Library& to_; |
501 const String& name_; | 505 const String& name_; |
502 | 506 |
503 RawString* ToString() { | 507 RawString* ToString() { |
504 const String& lib_url = String::Handle(to_.url()); | 508 const String& lib_url = String::Handle(to_.url()); |
505 from_.ToCString(); | 509 from_.ToCString(); |
506 return String::NewFormatted( | 510 return String::NewFormatted( |
507 "Reloading support for deferred loading has not yet been implemented:" | 511 "Reloading support for deferred loading has not yet been implemented:" |
508 " library '%s' has deferred import '%s'", | 512 " library '%s' has deferred import '%s'", |
509 lib_url.ToCString(), name_.ToCString()); | 513 lib_url.ToCString(), name_.ToCString()); |
510 } | 514 } |
511 }; | 515 }; |
512 | 516 |
513 | 517 |
514 // This is executed before interating over the instances. | 518 // This is executed before interating over the instances. |
515 void Class::CheckReload(const Class& replacement, | 519 void Class::CheckReload(const Class& replacement, |
516 IsolateReloadContext* context) const { | 520 IsolateReloadContext* context) const { |
517 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); | 521 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); |
518 | 522 |
519 // Class cannot change enum property. | 523 // Class cannot change enum property. |
520 if (is_enum_class() != replacement.is_enum_class()) { | 524 if (is_enum_class() != replacement.is_enum_class()) { |
521 context->AddReasonForCancelling( | 525 context->AddReasonForCancelling( |
522 new EnumClassConflict(*this, replacement)); | 526 new(context->zone()) |
| 527 EnumClassConflict(context->zone(), *this, replacement)); |
523 return; | 528 return; |
524 } | 529 } |
525 | 530 |
526 if (is_finalized()) { | 531 if (is_finalized()) { |
527 // Ensure the replacement class is also finalized. | 532 // Ensure the replacement class is also finalized. |
528 const Error& error = | 533 const Error& error = |
529 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); | 534 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); |
530 if (!error.IsNull()) { | 535 if (!error.IsNull()) { |
531 context->AddReasonForCancelling( | 536 context->AddReasonForCancelling( |
532 new EnsureFinalizedError(*this, replacement, error)); | 537 new(context->zone()) |
| 538 EnsureFinalizedError(context->zone(), *this, replacement, error)); |
533 return; // No reason to check other properties. | 539 return; // No reason to check other properties. |
534 } | 540 } |
535 TIR_Print("Finalized replacement class for %s\n", ToCString()); | 541 TIR_Print("Finalized replacement class for %s\n", ToCString()); |
536 } | 542 } |
537 | 543 |
538 // Native field count cannot change. | 544 // Native field count cannot change. |
539 if (num_native_fields() != replacement.num_native_fields()) { | 545 if (num_native_fields() != replacement.num_native_fields()) { |
540 context->AddReasonForCancelling( | 546 context->AddReasonForCancelling( |
541 new NativeFieldsConflict(*this, replacement)); | 547 new(context->zone()) |
| 548 NativeFieldsConflict(context->zone(), *this, replacement)); |
542 return; | 549 return; |
543 } | 550 } |
544 | 551 |
545 // Just checking. | 552 // Just checking. |
546 ASSERT(is_enum_class() == replacement.is_enum_class()); | 553 ASSERT(is_enum_class() == replacement.is_enum_class()); |
547 ASSERT(num_native_fields() == replacement.num_native_fields()); | 554 ASSERT(num_native_fields() == replacement.num_native_fields()); |
548 | 555 |
549 if (is_finalized()) { | 556 if (is_finalized()) { |
550 if (!CanReloadFinalized(replacement, context)) return; | 557 if (!CanReloadFinalized(replacement, context)) return; |
551 } | 558 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 bool Class::CanReloadFinalized(const Class& replacement, | 605 bool Class::CanReloadFinalized(const Class& replacement, |
599 IsolateReloadContext* context) const { | 606 IsolateReloadContext* context) const { |
600 // Make sure the declaration types matches for the two classes. | 607 // Make sure the declaration types matches for the two classes. |
601 // ex. class A<int,B> {} cannot be replace with class A<B> {}. | 608 // ex. class A<int,B> {} cannot be replace with class A<B> {}. |
602 | 609 |
603 const AbstractType& dt = AbstractType::Handle(DeclarationType()); | 610 const AbstractType& dt = AbstractType::Handle(DeclarationType()); |
604 const AbstractType& replacement_dt = | 611 const AbstractType& replacement_dt = |
605 AbstractType::Handle(replacement.DeclarationType()); | 612 AbstractType::Handle(replacement.DeclarationType()); |
606 if (!dt.Equals(replacement_dt)) { | 613 if (!dt.Equals(replacement_dt)) { |
607 context->AddReasonForCancelling( | 614 context->AddReasonForCancelling( |
608 new TypeParametersChanged(*this, replacement)); | 615 new(context->zone()) |
| 616 TypeParametersChanged(context->zone(), *this, replacement)); |
609 return false; | 617 return false; |
610 } | 618 } |
611 if (RequiresInstanceMorphing(replacement)) { | 619 if (RequiresInstanceMorphing(replacement)) { |
612 context->AddInstanceMorpher(new InstanceMorpher(*this, replacement)); | 620 context->AddInstanceMorpher( |
| 621 new(context->zone()) |
| 622 InstanceMorpher(context->zone(), *this, replacement)); |
613 } | 623 } |
614 return true; | 624 return true; |
615 } | 625 } |
616 | 626 |
617 | 627 |
618 bool Class::CanReloadPreFinalized(const Class& replacement, | 628 bool Class::CanReloadPreFinalized(const Class& replacement, |
619 IsolateReloadContext* context) const { | 629 IsolateReloadContext* context) const { |
620 // The replacement class must also prefinalized. | 630 // The replacement class must also prefinalized. |
621 if (!replacement.is_prefinalized()) { | 631 if (!replacement.is_prefinalized()) { |
622 context->AddReasonForCancelling( | 632 context->AddReasonForCancelling( |
623 new PreFinalizedConflict(*this, replacement)); | 633 new(context->zone()) |
| 634 PreFinalizedConflict(context->zone(), *this, replacement)); |
624 return false; | 635 return false; |
625 } | 636 } |
626 // Check the instance sizes are equal. | 637 // Check the instance sizes are equal. |
627 if (instance_size() != replacement.instance_size()) { | 638 if (instance_size() != replacement.instance_size()) { |
628 context->AddReasonForCancelling( | 639 context->AddReasonForCancelling( |
629 new InstanceSizeConflict(*this, replacement)); | 640 new(context->zone()) |
| 641 InstanceSizeConflict(context->zone(), *this, replacement)); |
630 return false; | 642 return false; |
631 } | 643 } |
632 return true; | 644 return true; |
633 } | 645 } |
634 | 646 |
635 | 647 |
636 void Library::CheckReload(const Library& replacement, | 648 void Library::CheckReload(const Library& replacement, |
637 IsolateReloadContext* context) const { | 649 IsolateReloadContext* context) const { |
638 // TODO(26878): If the replacement library uses deferred loading, | 650 // TODO(26878): If the replacement library uses deferred loading, |
639 // reject it. We do not yet support reloading deferred libraries. | 651 // reject it. We do not yet support reloading deferred libraries. |
640 LibraryPrefix& prefix = LibraryPrefix::Handle(); | 652 LibraryPrefix& prefix = LibraryPrefix::Handle(); |
641 LibraryPrefixIterator it(replacement); | 653 LibraryPrefixIterator it(replacement); |
642 while (it.HasNext()) { | 654 while (it.HasNext()) { |
643 prefix = it.GetNext(); | 655 prefix = it.GetNext(); |
644 if (prefix.is_deferred_load()) { | 656 if (prefix.is_deferred_load()) { |
645 const String& prefix_name = String::Handle(prefix.name()); | 657 const String& prefix_name = String::Handle(prefix.name()); |
646 context->AddReasonForCancelling( | 658 context->AddReasonForCancelling( |
647 new UnimplementedDeferredLibrary(*this, replacement, prefix_name)); | 659 new(context->zone()) |
| 660 UnimplementedDeferredLibrary(context->zone(), |
| 661 *this, replacement, prefix_name)); |
648 return; | 662 return; |
649 } | 663 } |
650 } | 664 } |
651 } | 665 } |
652 | 666 |
653 | 667 |
654 static const Function* static_call_target = NULL; | 668 static const Function* static_call_target = NULL; |
655 | 669 |
656 | 670 |
657 void ICData::Reset() const { | 671 void ICData::Reset() const { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 } | 735 } |
722 ClearAndSetStaticTarget(new_target); | 736 ClearAndSetStaticTarget(new_target); |
723 } else { | 737 } else { |
724 ClearWithSentinel(); | 738 ClearWithSentinel(); |
725 } | 739 } |
726 } | 740 } |
727 | 741 |
728 #endif // !PRODUCT | 742 #endif // !PRODUCT |
729 | 743 |
730 } // namespace dart. | 744 } // namespace dart. |
OLD | NEW |