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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 ASSERT(owner.raw() == this->raw()); | 358 ASSERT(owner.raw() == this->raw()); |
359 field.set_owner(patch); | 359 field.set_owner(patch); |
360 } | 360 } |
361 field.ForceDynamicGuardedCidAndLength(); | 361 field.ForceDynamicGuardedCidAndLength(); |
362 } | 362 } |
363 } | 363 } |
364 | 364 |
365 | 365 |
366 class EnumClassConflict : public ClassReasonForCancelling { | 366 class EnumClassConflict : public ClassReasonForCancelling { |
367 public: | 367 public: |
368 EnumClassConflict(const Class& from, const Class& to) | 368 EnumClassConflict(Zone* zone, const Class& from, const Class& to) |
369 : ClassReasonForCancelling(from, to) { } | 369 : ClassReasonForCancelling(zone, from, to) { } |
370 | 370 |
371 RawString* ToString() { | 371 RawString* ToString() { |
372 return String::NewFormatted( | 372 return String::NewFormatted( |
373 from_.is_enum_class() | 373 from_.is_enum_class() |
374 ? "Enum class cannot be redefined to be a non-enum class: %s" | 374 ? "Enum class cannot be redefined to be a non-enum class: %s" |
375 : "Class cannot be redefined to be a enum class: %s", | 375 : "Class cannot be redefined to be a enum class: %s", |
376 from_.ToCString()); | 376 from_.ToCString()); |
377 } | 377 } |
378 }; | 378 }; |
379 | 379 |
380 | 380 |
381 class EnsureFinalizedError : public ClassReasonForCancelling { | 381 class EnsureFinalizedError : public ClassReasonForCancelling { |
382 public: | 382 public: |
383 EnsureFinalizedError(const Class& from, const Class& to, const Error& error) | 383 EnsureFinalizedError(Zone* zone, |
384 : ClassReasonForCancelling(from, to), error_(error) { } | 384 const Class& from, |
| 385 const Class& to, |
| 386 const Error& error) |
| 387 : ClassReasonForCancelling(zone, from, to), error_(error) { } |
385 | 388 |
386 private: | 389 private: |
387 const Error& error_; | 390 const Error& error_; |
388 | 391 |
389 RawError* ToError() { return error_.raw(); } | 392 RawError* ToError() { return error_.raw(); } |
390 | 393 |
391 RawString* ToString() { | 394 RawString* ToString() { |
392 return String::New(error_.ToErrorCString()); | 395 return String::New(error_.ToErrorCString()); |
393 } | 396 } |
394 }; | 397 }; |
395 | 398 |
396 | 399 |
397 class NativeFieldsConflict : public ClassReasonForCancelling { | 400 class NativeFieldsConflict : public ClassReasonForCancelling { |
398 public: | 401 public: |
399 NativeFieldsConflict(const Class& from, const Class& to) | 402 NativeFieldsConflict(Zone* zone, const Class& from, const Class& to) |
400 : ClassReasonForCancelling(from, to) { } | 403 : ClassReasonForCancelling(zone, from, to) { } |
401 | 404 |
402 private: | 405 private: |
403 RawString* ToString() { | 406 RawString* ToString() { |
404 return String::NewFormatted( | 407 return String::NewFormatted( |
405 "Number of native fields changed in %s", from_.ToCString()); | 408 "Number of native fields changed in %s", from_.ToCString()); |
406 } | 409 } |
407 }; | 410 }; |
408 | 411 |
409 | 412 |
410 class TypeParametersChanged : public ClassReasonForCancelling { | 413 class TypeParametersChanged : public ClassReasonForCancelling { |
411 public: | 414 public: |
412 TypeParametersChanged(const Class& from, const Class& to) | 415 TypeParametersChanged(Zone* zone, const Class& from, const Class& to) |
413 : ClassReasonForCancelling(from, to) {} | 416 : ClassReasonForCancelling(zone, from, to) {} |
414 | 417 |
415 RawString* ToString() { | 418 RawString* ToString() { |
416 return String::NewFormatted( | 419 return String::NewFormatted( |
417 "Limitation: type parameters have changed for %s", from_.ToCString()); | 420 "Limitation: type parameters have changed for %s", from_.ToCString()); |
418 } | 421 } |
419 | 422 |
420 void AppendTo(JSONArray* array) { | 423 void AppendTo(JSONArray* array) { |
421 JSONObject jsobj(array); | 424 JSONObject jsobj(array); |
422 jsobj.AddProperty("type", "ReasonForCancellingReload"); | 425 jsobj.AddProperty("type", "ReasonForCancellingReload"); |
423 jsobj.AddProperty("kind", "TypeParametersChanged"); | 426 jsobj.AddProperty("kind", "TypeParametersChanged"); |
424 jsobj.AddProperty("class", to_); | 427 jsobj.AddProperty("class", to_); |
425 jsobj.AddProperty("message", | 428 jsobj.AddProperty("message", |
426 "Limitation: changing type parameters " | 429 "Limitation: changing type parameters " |
427 "does not work with hot reload."); | 430 "does not work with hot reload."); |
428 } | 431 } |
429 }; | 432 }; |
430 | 433 |
431 | 434 |
432 class PreFinalizedConflict : public ClassReasonForCancelling { | 435 class PreFinalizedConflict : public ClassReasonForCancelling { |
433 public: | 436 public: |
434 PreFinalizedConflict(const Class& from, const Class& to) | 437 PreFinalizedConflict(Zone* zone, const Class& from, const Class& to) |
435 : ClassReasonForCancelling(from, to) {} | 438 : ClassReasonForCancelling(zone, from, to) {} |
436 | 439 |
437 private: | 440 private: |
438 RawString* ToString() { | 441 RawString* ToString() { |
439 return String::NewFormatted( | 442 return String::NewFormatted( |
440 "Original class ('%s') is prefinalized and replacement class " | 443 "Original class ('%s') is prefinalized and replacement class " |
441 "('%s') is not ", | 444 "('%s') is not ", |
442 from_.ToCString(), to_.ToCString()); | 445 from_.ToCString(), to_.ToCString()); |
443 } | 446 } |
444 }; | 447 }; |
445 | 448 |
446 | 449 |
447 class InstanceSizeConflict : public ClassReasonForCancelling { | 450 class InstanceSizeConflict : public ClassReasonForCancelling { |
448 public: | 451 public: |
449 InstanceSizeConflict(const Class& from, const Class& to) | 452 InstanceSizeConflict(Zone* zone, const Class& from, const Class& to) |
450 : ClassReasonForCancelling(from, to) {} | 453 : ClassReasonForCancelling(zone, from, to) {} |
451 | 454 |
452 private: | 455 private: |
453 RawString* ToString() { | 456 RawString* ToString() { |
454 return String::NewFormatted( | 457 return String::NewFormatted( |
455 "Instance size mismatch between '%s' (%" Pd ") and replacement " | 458 "Instance size mismatch between '%s' (%" Pd ") and replacement " |
456 "'%s' ( %" Pd ")", | 459 "'%s' ( %" Pd ")", |
457 from_.ToCString(), | 460 from_.ToCString(), |
458 from_.instance_size(), | 461 from_.instance_size(), |
459 to_.ToCString(), | 462 to_.ToCString(), |
460 to_.instance_size()); | 463 to_.instance_size()); |
461 } | 464 } |
462 }; | 465 }; |
463 | 466 |
464 | 467 |
465 class UnimplementedDeferredLibrary : public ReasonForCancelling { | 468 class UnimplementedDeferredLibrary : public ReasonForCancelling { |
466 public: | 469 public: |
467 UnimplementedDeferredLibrary(const Library& from, | 470 UnimplementedDeferredLibrary(Zone* zone, |
| 471 const Library& from, |
468 const Library& to, | 472 const Library& to, |
469 const String& name) | 473 const String& name) |
470 : ReasonForCancelling(), from_(from), to_(to), name_(name) {} | 474 : ReasonForCancelling(zone), from_(from), to_(to), name_(name) {} |
471 | 475 |
472 private: | 476 private: |
473 const Library& from_; | 477 const Library& from_; |
474 const Library& to_; | 478 const Library& to_; |
475 const String& name_; | 479 const String& name_; |
476 | 480 |
477 RawString* ToString() { | 481 RawString* ToString() { |
478 const String& lib_url = String::Handle(to_.url()); | 482 const String& lib_url = String::Handle(to_.url()); |
479 from_.ToCString(); | 483 from_.ToCString(); |
480 return String::NewFormatted( | 484 return String::NewFormatted( |
481 "Reloading support for deferred loading has not yet been implemented:" | 485 "Reloading support for deferred loading has not yet been implemented:" |
482 " library '%s' has deferred import '%s'", | 486 " library '%s' has deferred import '%s'", |
483 lib_url.ToCString(), name_.ToCString()); | 487 lib_url.ToCString(), name_.ToCString()); |
484 } | 488 } |
485 }; | 489 }; |
486 | 490 |
487 | 491 |
488 // This is executed before interating over the instances. | 492 // This is executed before interating over the instances. |
489 void Class::CheckReload(const Class& replacement, | 493 void Class::CheckReload(const Class& replacement, |
490 IsolateReloadContext* context) const { | 494 IsolateReloadContext* context) const { |
491 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); | 495 ASSERT(IsolateReloadContext::IsSameClass(*this, replacement)); |
492 | 496 |
493 // Class cannot change enum property. | 497 // Class cannot change enum property. |
494 if (is_enum_class() != replacement.is_enum_class()) { | 498 if (is_enum_class() != replacement.is_enum_class()) { |
495 context->AddReasonForCancelling( | 499 context->AddReasonForCancelling( |
496 new EnumClassConflict(*this, replacement)); | 500 new(context->zone()) |
| 501 EnumClassConflict(context->zone(), *this, replacement)); |
497 return; | 502 return; |
498 } | 503 } |
499 | 504 |
500 if (is_finalized()) { | 505 if (is_finalized()) { |
501 // Ensure the replacement class is also finalized. | 506 // Ensure the replacement class is also finalized. |
502 const Error& error = | 507 const Error& error = |
503 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); | 508 Error::Handle(replacement.EnsureIsFinalized(Thread::Current())); |
504 if (!error.IsNull()) { | 509 if (!error.IsNull()) { |
505 context->AddReasonForCancelling( | 510 context->AddReasonForCancelling( |
506 new EnsureFinalizedError(*this, replacement, error)); | 511 new(context->zone()) |
| 512 EnsureFinalizedError(context->zone(), *this, replacement, error)); |
507 return; // No reason to check other properties. | 513 return; // No reason to check other properties. |
508 } | 514 } |
509 TIR_Print("Finalized replacement class for %s\n", ToCString()); | 515 TIR_Print("Finalized replacement class for %s\n", ToCString()); |
510 } | 516 } |
511 | 517 |
512 // Native field count cannot change. | 518 // Native field count cannot change. |
513 if (num_native_fields() != replacement.num_native_fields()) { | 519 if (num_native_fields() != replacement.num_native_fields()) { |
514 context->AddReasonForCancelling( | 520 context->AddReasonForCancelling( |
515 new NativeFieldsConflict(*this, replacement)); | 521 new(context->zone()) |
| 522 NativeFieldsConflict(context->zone(), *this, replacement)); |
516 return; | 523 return; |
517 } | 524 } |
518 | 525 |
519 // Just checking. | 526 // Just checking. |
520 ASSERT(is_enum_class() == replacement.is_enum_class()); | 527 ASSERT(is_enum_class() == replacement.is_enum_class()); |
521 ASSERT(num_native_fields() == replacement.num_native_fields()); | 528 ASSERT(num_native_fields() == replacement.num_native_fields()); |
522 | 529 |
523 if (is_finalized()) { | 530 if (is_finalized()) { |
524 if (!CanReloadFinalized(replacement, context)) return; | 531 if (!CanReloadFinalized(replacement, context)) return; |
525 } | 532 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 bool Class::CanReloadFinalized(const Class& replacement, | 579 bool Class::CanReloadFinalized(const Class& replacement, |
573 IsolateReloadContext* context) const { | 580 IsolateReloadContext* context) const { |
574 // Make sure the declaration types matches for the two classes. | 581 // Make sure the declaration types matches for the two classes. |
575 // ex. class A<int,B> {} cannot be replace with class A<B> {}. | 582 // ex. class A<int,B> {} cannot be replace with class A<B> {}. |
576 | 583 |
577 const AbstractType& dt = AbstractType::Handle(DeclarationType()); | 584 const AbstractType& dt = AbstractType::Handle(DeclarationType()); |
578 const AbstractType& replacement_dt = | 585 const AbstractType& replacement_dt = |
579 AbstractType::Handle(replacement.DeclarationType()); | 586 AbstractType::Handle(replacement.DeclarationType()); |
580 if (!dt.Equals(replacement_dt)) { | 587 if (!dt.Equals(replacement_dt)) { |
581 context->AddReasonForCancelling( | 588 context->AddReasonForCancelling( |
582 new TypeParametersChanged(*this, replacement)); | 589 new(context->zone()) |
| 590 TypeParametersChanged(context->zone(), *this, replacement)); |
583 return false; | 591 return false; |
584 } | 592 } |
585 if (RequiresInstanceMorphing(replacement)) { | 593 if (RequiresInstanceMorphing(replacement)) { |
586 context->AddInstanceMorpher(new InstanceMorpher(*this, replacement)); | 594 context->AddInstanceMorpher( |
| 595 new(context->zone()) |
| 596 InstanceMorpher(context->zone(), *this, replacement)); |
587 } | 597 } |
588 return true; | 598 return true; |
589 } | 599 } |
590 | 600 |
591 | 601 |
592 bool Class::CanReloadPreFinalized(const Class& replacement, | 602 bool Class::CanReloadPreFinalized(const Class& replacement, |
593 IsolateReloadContext* context) const { | 603 IsolateReloadContext* context) const { |
594 // The replacement class must also prefinalized. | 604 // The replacement class must also prefinalized. |
595 if (!replacement.is_prefinalized()) { | 605 if (!replacement.is_prefinalized()) { |
596 context->AddReasonForCancelling( | 606 context->AddReasonForCancelling( |
597 new PreFinalizedConflict(*this, replacement)); | 607 new(context->zone()) |
| 608 PreFinalizedConflict(context->zone(), *this, replacement)); |
598 return false; | 609 return false; |
599 } | 610 } |
600 // Check the instance sizes are equal. | 611 // Check the instance sizes are equal. |
601 if (instance_size() != replacement.instance_size()) { | 612 if (instance_size() != replacement.instance_size()) { |
602 context->AddReasonForCancelling( | 613 context->AddReasonForCancelling( |
603 new InstanceSizeConflict(*this, replacement)); | 614 new(context->zone()) |
| 615 InstanceSizeConflict(context->zone(), *this, replacement)); |
604 return false; | 616 return false; |
605 } | 617 } |
606 return true; | 618 return true; |
607 } | 619 } |
608 | 620 |
609 | 621 |
610 void Library::CheckReload(const Library& replacement, | 622 void Library::CheckReload(const Library& replacement, |
611 IsolateReloadContext* context) const { | 623 IsolateReloadContext* context) const { |
612 // TODO(26878): If the replacement library uses deferred loading, | 624 // TODO(26878): If the replacement library uses deferred loading, |
613 // reject it. We do not yet support reloading deferred libraries. | 625 // reject it. We do not yet support reloading deferred libraries. |
614 LibraryPrefix& prefix = LibraryPrefix::Handle(); | 626 LibraryPrefix& prefix = LibraryPrefix::Handle(); |
615 LibraryPrefixIterator it(replacement); | 627 LibraryPrefixIterator it(replacement); |
616 while (it.HasNext()) { | 628 while (it.HasNext()) { |
617 prefix = it.GetNext(); | 629 prefix = it.GetNext(); |
618 if (prefix.is_deferred_load()) { | 630 if (prefix.is_deferred_load()) { |
619 const String& prefix_name = String::Handle(prefix.name()); | 631 const String& prefix_name = String::Handle(prefix.name()); |
620 context->AddReasonForCancelling( | 632 context->AddReasonForCancelling( |
621 new UnimplementedDeferredLibrary(*this, replacement, prefix_name)); | 633 new(context->zone()) |
| 634 UnimplementedDeferredLibrary(context->zone(), |
| 635 *this, replacement, prefix_name)); |
622 return; | 636 return; |
623 } | 637 } |
624 } | 638 } |
625 } | 639 } |
626 | 640 |
627 | 641 |
628 static const Function* static_call_target = NULL; | 642 static const Function* static_call_target = NULL; |
629 | 643 |
630 | 644 |
631 void ICData::Reset() const { | 645 void ICData::Reset() const { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 } | 709 } |
696 ClearAndSetStaticTarget(new_target); | 710 ClearAndSetStaticTarget(new_target); |
697 } else { | 711 } else { |
698 ClearWithSentinel(); | 712 ClearWithSentinel(); |
699 } | 713 } |
700 } | 714 } |
701 | 715 |
702 #endif // !PRODUCT | 716 #endif // !PRODUCT |
703 | 717 |
704 } // namespace dart. | 718 } // namespace dart. |
OLD | NEW |