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/isolate_reload.h" | 5 #include "vm/isolate_reload.h" |
6 | 6 |
7 #include "vm/become.h" | 7 #include "vm/become.h" |
8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
11 #include "vm/hash_table.h" | 11 #include "vm/hash_table.h" |
12 #include "vm/isolate.h" | 12 #include "vm/isolate.h" |
| 13 #include "vm/kernel_reader.h" |
13 #include "vm/log.h" | 14 #include "vm/log.h" |
14 #include "vm/object.h" | 15 #include "vm/object.h" |
15 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
16 #include "vm/parser.h" | 17 #include "vm/parser.h" |
17 #include "vm/runtime_entry.h" | 18 #include "vm/runtime_entry.h" |
18 #include "vm/safepoint.h" | 19 #include "vm/safepoint.h" |
19 #include "vm/service_event.h" | 20 #include "vm/service_event.h" |
20 #include "vm/stack_frame.h" | 21 #include "vm/stack_frame.h" |
21 #include "vm/thread.h" | 22 #include "vm/thread.h" |
22 #include "vm/timeline.h" | 23 #include "vm/timeline.h" |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 | 479 |
479 private: | 480 private: |
480 const Error& error_; | 481 const Error& error_; |
481 | 482 |
482 RawError* ToError() { return error_.raw(); } | 483 RawError* ToError() { return error_.raw(); } |
483 RawString* ToString() { | 484 RawString* ToString() { |
484 return String::NewFormatted("%s", error_.ToErrorCString()); | 485 return String::NewFormatted("%s", error_.ToErrorCString()); |
485 } | 486 } |
486 }; | 487 }; |
487 | 488 |
| 489 #if !defined(DART_PRECOMPILED_RUNTIME) |
488 static intptr_t CommonSuffixLength(const char* a, const char* b) { | 490 static intptr_t CommonSuffixLength(const char* a, const char* b) { |
489 const intptr_t a_length = strlen(a); | 491 const intptr_t a_length = strlen(a); |
490 const intptr_t b_length = strlen(b); | 492 const intptr_t b_length = strlen(b); |
491 intptr_t a_cursor = a_length; | 493 intptr_t a_cursor = a_length; |
492 intptr_t b_cursor = b_length; | 494 intptr_t b_cursor = b_length; |
493 | 495 |
494 while ((a_cursor >= 0) && (b_cursor >= 0)) { | 496 while ((a_cursor >= 0) && (b_cursor >= 0)) { |
495 if (a[a_cursor] != b[b_cursor]) { | 497 if (a[a_cursor] != b[b_cursor]) { |
496 break; | 498 break; |
497 } | 499 } |
(...skipping 28 matching lines...) Expand all Loading... |
526 const char* root_library_url_c = root_lib_url.ToCString(); | 528 const char* root_library_url_c = root_lib_url.ToCString(); |
527 const intptr_t common_suffix_length = | 529 const intptr_t common_suffix_length = |
528 CommonSuffixLength(root_library_url_c, old_root_library_url_c); | 530 CommonSuffixLength(root_library_url_c, old_root_library_url_c); |
529 root_url_prefix_ = String::SubString( | 531 root_url_prefix_ = String::SubString( |
530 root_lib_url, 0, root_lib_url.Length() - common_suffix_length + 1); | 532 root_lib_url, 0, root_lib_url.Length() - common_suffix_length + 1); |
531 old_root_url_prefix_ = | 533 old_root_url_prefix_ = |
532 String::SubString(old_root_lib_url, 0, | 534 String::SubString(old_root_lib_url, 0, |
533 old_root_lib_url.Length() - common_suffix_length + 1); | 535 old_root_lib_url.Length() - common_suffix_length + 1); |
534 } | 536 } |
535 | 537 |
536 // Check to see which libraries have been modified. | 538 Object& result = Object::Handle(thread->zone()); |
537 modified_libs_ = FindModifiedLibraries(force_reload); | 539 kernel::Program* kernel_program = NULL; |
| 540 String& packages_url = String::Handle(); |
| 541 if (packages_url_ != NULL) { |
| 542 packages_url = String::New(packages_url_); |
| 543 } |
| 544 if (isolate()->use_dart_frontend()) { |
| 545 // Load the kernel program and figure out the modified libraries. |
| 546 const GrowableObjectArray& libs = |
| 547 GrowableObjectArray::Handle(object_store()->libraries()); |
| 548 intptr_t num_libs = libs.Length(); |
| 549 modified_libs_ = new (Z) BitVector(Z, num_libs); |
| 550 TIR_Print("---- ENTERING TAG HANDLER\n"); |
| 551 { |
| 552 TransitionVMToNative transition(thread); |
| 553 Api::Scope api_scope(thread); |
| 554 Dart_Handle retval = (I->library_tag_handler())( |
| 555 Dart_kKernelTag, Api::NewHandle(thread, packages_url.raw()), |
| 556 Api::NewHandle(thread, root_lib_url.raw())); |
| 557 if (Dart_IsError(retval)) { |
| 558 // Compilation of the new sources failed, abort reload and report |
| 559 // error. |
| 560 result = Api::UnwrapHandle(retval); |
| 561 } else { |
| 562 uint64_t data; |
| 563 intptr_t data_len = 0; |
| 564 Dart_TypedData_Type data_type; |
| 565 ASSERT(Dart_IsTypedData(retval)); |
| 566 Dart_Handle val = Dart_TypedDataAcquireData( |
| 567 retval, &data_type, reinterpret_cast<void**>(&data), &data_len); |
| 568 ASSERT(!Dart_IsError(val)); |
| 569 ASSERT(data_type == Dart_TypedData_kUint64); |
| 570 ASSERT(data_len == 1); |
| 571 kernel_program = reinterpret_cast<kernel::Program*>(data); |
| 572 Dart_TypedDataReleaseData(retval); |
| 573 kernel::KernelReader reader(kernel_program); |
| 574 reader.FindModifiedLibraries(I, modified_libs_, force_reload); |
| 575 } |
| 576 } |
| 577 if (result.IsError()) { |
| 578 TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n"); |
| 579 AddReasonForCancelling(new Aborted(zone_, ApiError::Cast(result))); |
| 580 ReportReasonsForCancelling(); |
| 581 CommonFinalizeTail(); |
| 582 return; |
| 583 } |
| 584 TIR_Print("---- EXITED TAG HANDLER\n"); |
| 585 } else { |
| 586 // Check to see which libraries have been modified. |
| 587 modified_libs_ = FindModifiedLibraries(force_reload); |
| 588 } |
538 if (!modified_libs_->Contains(old_root_lib.index())) { | 589 if (!modified_libs_->Contains(old_root_lib.index())) { |
539 ASSERT(modified_libs_->IsEmpty()); | 590 ASSERT(modified_libs_->IsEmpty()); |
540 reload_skipped_ = true; | 591 reload_skipped_ = true; |
541 ReportOnJSON(js_); | 592 ReportOnJSON(js_); |
542 TIR_Print("---- SKIPPING RELOAD (No libraries were modified)\n"); | 593 TIR_Print("---- SKIPPING RELOAD (No libraries were modified)\n"); |
543 return; | 594 return; |
544 } | 595 } |
545 | 596 |
546 TIR_Print("---- STARTING RELOAD\n"); | 597 TIR_Print("---- STARTING RELOAD\n"); |
547 | 598 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 // and we are temporarily back in control. | 633 // and we are temporarily back in control. |
583 // This is where we validate the reload and commit or reject. | 634 // This is where we validate the reload and commit or reject. |
584 // 5) Dart_FinalizeLoading invokes Dart code related to deferred libraries. | 635 // 5) Dart_FinalizeLoading invokes Dart code related to deferred libraries. |
585 // 6) The tag handler returns and we move on. | 636 // 6) The tag handler returns and we move on. |
586 // | 637 // |
587 // Even after a successful reload the Dart code invoked in (5) can result | 638 // Even after a successful reload the Dart code invoked in (5) can result |
588 // in an Unwind error or an UnhandledException error. This error will be | 639 // in an Unwind error or an UnhandledException error. This error will be |
589 // returned by the tag handler. The tag handler can return other errors, | 640 // returned by the tag handler. The tag handler can return other errors, |
590 // for example, top level parse errors. We want to capture these errors while | 641 // for example, top level parse errors. We want to capture these errors while |
591 // propagating the UnwindError or an UnhandledException error. | 642 // propagating the UnwindError or an UnhandledException error. |
592 Object& result = Object::Handle(thread->zone()); | |
593 | 643 |
594 String& packages_url = String::Handle(); | 644 if (isolate()->use_dart_frontend()) { |
595 if (packages_url_ != NULL) { | 645 // Read the kernel program. |
596 packages_url = String::New(packages_url_); | 646 kernel::KernelReader reader(kernel_program); |
597 } | 647 const Object& tmp = reader.ReadProgram(); |
598 | 648 if (!tmp.IsError()) { |
599 TIR_Print("---- ENTERING TAG HANDLER\n"); | 649 Library& lib = Library::Handle(thread->zone()); |
600 { | 650 lib ^= tmp.raw(); |
| 651 isolate()->object_store()->set_root_library(lib); |
| 652 FinalizeLoading(); |
| 653 result = Object::null(); |
| 654 } else { |
| 655 result = tmp.raw(); |
| 656 } |
| 657 } else { |
| 658 TIR_Print("---- ENTERING TAG HANDLER\n"); |
601 TransitionVMToNative transition(thread); | 659 TransitionVMToNative transition(thread); |
602 Api::Scope api_scope(thread); | 660 Api::Scope api_scope(thread); |
603 | 661 |
604 Dart_Handle retval = (I->library_tag_handler())( | 662 Dart_Handle retval = (I->library_tag_handler())( |
605 Dart_kScriptTag, Api::NewHandle(thread, packages_url.raw()), | 663 Dart_kScriptTag, Api::NewHandle(thread, packages_url.raw()), |
606 Api::NewHandle(thread, root_lib_url.raw())); | 664 Api::NewHandle(thread, root_lib_url.raw())); |
607 result = Api::UnwrapHandle(retval); | 665 result = Api::UnwrapHandle(retval); |
| 666 TIR_Print("---- EXITED TAG HANDLER\n"); |
608 } | 667 } |
609 // | 668 // |
610 // WEIRD CONTROL FLOW ENDS. | 669 // WEIRD CONTROL FLOW ENDS. |
611 TIR_Print("---- EXITED TAG HANDLER\n"); | |
612 | 670 |
613 // Re-enable the background compiler. Do this before propagating any errors. | 671 // Re-enable the background compiler. Do this before propagating any errors. |
614 BackgroundCompiler::Enable(); | 672 BackgroundCompiler::Enable(); |
615 | 673 |
616 if (result.IsUnwindError()) { | 674 if (result.IsUnwindError()) { |
617 if (thread->top_exit_frame_info() == 0) { | 675 if (thread->top_exit_frame_info() == 0) { |
618 // We can only propagate errors when there are Dart frames on the stack. | 676 // We can only propagate errors when there are Dart frames on the stack. |
619 // In this case there are no Dart frames on the stack and we set the | 677 // In this case there are no Dart frames on the stack and we set the |
620 // thread's sticky error. This error will be returned to the message | 678 // thread's sticky error. This error will be returned to the message |
621 // handler. | 679 // handler. |
622 thread->set_sticky_error(Error::Cast(result)); | 680 thread->set_sticky_error(Error::Cast(result)); |
623 } else { | 681 } else { |
624 // If the tag handler returns with an UnwindError error, propagate it and | 682 // If the tag handler returns with an UnwindError error, propagate it and |
625 // give up. | 683 // give up. |
626 Exceptions::PropagateError(Error::Cast(result)); | 684 Exceptions::PropagateError(Error::Cast(result)); |
627 UNREACHABLE(); | 685 UNREACHABLE(); |
628 } | 686 } |
629 } | 687 } |
630 | 688 |
631 // Other errors (e.g. a parse error) are captured by the reload system. | 689 // Other errors (e.g. a parse error) are captured by the reload system. |
632 if (result.IsError()) { | 690 if (result.IsError()) { |
633 FinalizeFailedLoad(Error::Cast(result)); | 691 FinalizeFailedLoad(Error::Cast(result)); |
634 } | 692 } |
635 } | 693 } |
| 694 #else |
| 695 // NOTE: This function returns *after* FinalizeLoading is called. |
| 696 void IsolateReloadContext::Reload(bool force_reload, |
| 697 const char* root_script_url, |
| 698 const char* packages_url_) {} |
| 699 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
636 | 700 |
637 void IsolateReloadContext::RegisterClass(const Class& new_cls) { | 701 void IsolateReloadContext::RegisterClass(const Class& new_cls) { |
638 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); | 702 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); |
639 if (old_cls.IsNull()) { | 703 if (old_cls.IsNull()) { |
640 I->class_table()->Register(new_cls); | 704 I->class_table()->Register(new_cls); |
641 | 705 |
642 if (FLAG_identity_reload) { | 706 if (FLAG_identity_reload) { |
643 TIR_Print("Could not find replacement class for %s\n", | 707 TIR_Print("Could not find replacement class for %s\n", |
644 new_cls.ToCString()); | 708 new_cls.ToCString()); |
645 UNREACHABLE(); | 709 UNREACHABLE(); |
(...skipping 10 matching lines...) Expand all Loading... |
656 new_cls.CopyCanonicalConstants(old_cls); | 720 new_cls.CopyCanonicalConstants(old_cls); |
657 } | 721 } |
658 new_cls.CopyCanonicalType(old_cls); | 722 new_cls.CopyCanonicalType(old_cls); |
659 AddBecomeMapping(old_cls, new_cls); | 723 AddBecomeMapping(old_cls, new_cls); |
660 AddClassMapping(new_cls, old_cls); | 724 AddClassMapping(new_cls, old_cls); |
661 } | 725 } |
662 | 726 |
663 // FinalizeLoading will be called *before* Reload() returns but will not be | 727 // FinalizeLoading will be called *before* Reload() returns but will not be |
664 // called if the embedder fails to load sources. | 728 // called if the embedder fails to load sources. |
665 void IsolateReloadContext::FinalizeLoading() { | 729 void IsolateReloadContext::FinalizeLoading() { |
666 if (reload_skipped_) { | 730 if (reload_skipped_ || reload_finalized_) { |
667 return; | 731 return; |
668 } | 732 } |
669 ASSERT(!reload_finalized_); | |
670 BuildLibraryMapping(); | 733 BuildLibraryMapping(); |
671 TIR_Print("---- LOAD SUCCEEDED\n"); | 734 TIR_Print("---- LOAD SUCCEEDED\n"); |
672 if (ValidateReload()) { | 735 if (ValidateReload()) { |
673 Commit(); | 736 Commit(); |
674 PostCommit(); | 737 PostCommit(); |
675 isolate()->set_last_reload_timestamp(reload_timestamp_); | 738 isolate()->set_last_reload_timestamp(reload_timestamp_); |
676 } else { | 739 } else { |
677 ReportReasonsForCancelling(); | 740 ReportReasonsForCancelling(); |
678 Rollback(); | 741 Rollback(); |
679 } | 742 } |
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1825 ASSERT(!super_cls.IsNull()); | 1888 ASSERT(!super_cls.IsNull()); |
1826 super_cls.AddDirectSubclass(cls); | 1889 super_cls.AddDirectSubclass(cls); |
1827 } | 1890 } |
1828 } | 1891 } |
1829 } | 1892 } |
1830 } | 1893 } |
1831 | 1894 |
1832 #endif // !PRODUCT | 1895 #endif // !PRODUCT |
1833 | 1896 |
1834 } // namespace dart | 1897 } // namespace dart |
OLD | NEW |