Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1965823002: Initial isolate reload support (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "include/dart_native_api.h" 8 #include "include/dart_native_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/text_buffer.h" 10 #include "platform/text_buffer.h"
11 #include "vm/class_finalizer.h" 11 #include "vm/class_finalizer.h"
12 #include "vm/code_observers.h" 12 #include "vm/code_observers.h"
13 #include "vm/compiler.h" 13 #include "vm/compiler.h"
14 #include "vm/compiler_stats.h" 14 #include "vm/compiler_stats.h"
15 #include "vm/dart_api_message.h" 15 #include "vm/dart_api_message.h"
16 #include "vm/dart_api_state.h" 16 #include "vm/dart_api_state.h"
17 #include "vm/dart_entry.h" 17 #include "vm/dart_entry.h"
18 #include "vm/debugger.h" 18 #include "vm/debugger.h"
19 #include "vm/deopt_instructions.h" 19 #include "vm/deopt_instructions.h"
20 #include "vm/flags.h" 20 #include "vm/flags.h"
21 #include "vm/heap.h" 21 #include "vm/heap.h"
22 #include "vm/isolate_reload.h"
22 #include "vm/lockers.h" 23 #include "vm/lockers.h"
23 #include "vm/log.h" 24 #include "vm/log.h"
24 #include "vm/message_handler.h" 25 #include "vm/message_handler.h"
25 #include "vm/object_id_ring.h" 26 #include "vm/object_id_ring.h"
26 #include "vm/object_store.h" 27 #include "vm/object_store.h"
27 #include "vm/object.h" 28 #include "vm/object.h"
28 #include "vm/os_thread.h" 29 #include "vm/os_thread.h"
29 #include "vm/port.h" 30 #include "vm/port.h"
30 #include "vm/profiler.h" 31 #include "vm/profiler.h"
31 #include "vm/reusable_handles.h" 32 #include "vm/reusable_handles.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 thread->DeferOOBMessageInterrupts(); 128 thread->DeferOOBMessageInterrupts();
128 } 129 }
129 130
130 131
131 NoOOBMessageScope::~NoOOBMessageScope() { 132 NoOOBMessageScope::~NoOOBMessageScope() {
132 thread()->RestoreOOBMessageInterrupts(); 133 thread()->RestoreOOBMessageInterrupts();
133 } 134 }
134 135
135 136
136 137
138 NoReloadScope::NoReloadScope(Isolate* isolate, Thread* thread)
139 : StackResource(thread),
140 isolate_(isolate) {
141 ASSERT(isolate_ != NULL);
142 isolate_->no_reload_scope_depth_++;
143 ASSERT(isolate_->no_reload_scope_depth_ >= 0);
144 }
145
146
147 NoReloadScope::~NoReloadScope() {
148 isolate_->no_reload_scope_depth_--;
149 ASSERT(isolate_->no_reload_scope_depth_ >= 0);
150 }
151
152
137 void Isolate::RegisterClass(const Class& cls) { 153 void Isolate::RegisterClass(const Class& cls) {
154 NOT_IN_PRODUCT(
155 if (IsReloading()) {
156 reload_context()->RegisterClass(cls);
157 return;
158 }
159 )
138 class_table()->Register(cls); 160 class_table()->Register(cls);
139 } 161 }
140 162
141 163
142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { 164 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) {
143 class_table()->RegisterAt(index, cls); 165 class_table()->RegisterAt(index, cls);
144 } 166 }
145 167
146 168
147 void Isolate::ValidateClassTable() { 169 void Isolate::ValidateClassTable() {
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 return MessageHandler::kShutdown; 639 return MessageHandler::kShutdown;
618 } 640 }
619 } 641 }
620 } 642 }
621 return MessageHandler::kError; 643 return MessageHandler::kError;
622 } 644 }
623 645
624 646
625 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( 647 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
626 const Error& result) { 648 const Error& result) {
649 NOT_IN_PRODUCT(
650 if (I->IsReloading()) {
651 I->ReportReloadError(result);
652 return kOK;
653 }
654 )
627 // Generate the error and stacktrace strings for the error message. 655 // Generate the error and stacktrace strings for the error message.
628 String& exc_str = String::Handle(T->zone()); 656 String& exc_str = String::Handle(T->zone());
629 String& stacktrace_str = String::Handle(T->zone()); 657 String& stacktrace_str = String::Handle(T->zone());
630 if (result.IsUnhandledException()) { 658 if (result.IsUnhandledException()) {
631 Zone* zone = T->zone(); 659 Zone* zone = T->zone();
632 const UnhandledException& uhe = UnhandledException::Cast(result); 660 const UnhandledException& uhe = UnhandledException::Cast(result);
633 const Instance& exception = Instance::Handle(zone, uhe.exception()); 661 const Instance& exception = Instance::Handle(zone, uhe.exception());
634 Object& tmp = Object::Handle(zone); 662 Object& tmp = Object::Handle(zone);
635 tmp = DartLibraryCalls::ToString(exception); 663 tmp = DartLibraryCalls::ToString(exception);
636 if (!tmp.IsString()) { 664 if (!tmp.IsString()) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 is_service_isolate_(false), 806 is_service_isolate_(false),
779 stacktrace_(NULL), 807 stacktrace_(NULL),
780 stack_frame_index_(-1), 808 stack_frame_index_(-1),
781 last_allocationprofile_accumulator_reset_timestamp_(0), 809 last_allocationprofile_accumulator_reset_timestamp_(0),
782 last_allocationprofile_gc_timestamp_(0), 810 last_allocationprofile_gc_timestamp_(0),
783 object_id_ring_(NULL), 811 object_id_ring_(NULL),
784 tag_table_(GrowableObjectArray::null()), 812 tag_table_(GrowableObjectArray::null()),
785 deoptimized_code_array_(GrowableObjectArray::null()), 813 deoptimized_code_array_(GrowableObjectArray::null()),
786 sticky_error_(Error::null()), 814 sticky_error_(Error::null()),
787 background_compiler_(NULL), 815 background_compiler_(NULL),
816 background_compiler_disabled_count_(0),
rmacnak 2016/05/13 17:59:34 depth
Cutch 2016/05/17 18:03:51 Done.
788 pending_service_extension_calls_(GrowableObjectArray::null()), 817 pending_service_extension_calls_(GrowableObjectArray::null()),
789 registered_service_extension_handlers_(GrowableObjectArray::null()), 818 registered_service_extension_handlers_(GrowableObjectArray::null()),
790 metrics_list_head_(NULL), 819 metrics_list_head_(NULL),
791 compilation_allowed_(true), 820 compilation_allowed_(true),
792 all_classes_finalized_(false), 821 all_classes_finalized_(false),
793 next_(NULL), 822 next_(NULL),
794 pause_loop_monitor_(NULL), 823 pause_loop_monitor_(NULL),
795 field_invalidation_gen_(kInvalidGen), 824 field_invalidation_gen_(kInvalidGen),
796 loading_invalidation_gen_(kInvalidGen), 825 loading_invalidation_gen_(kInvalidGen),
797 top_level_parsing_count_(0), 826 top_level_parsing_count_(0),
798 field_list_mutex_(new Mutex()), 827 field_list_mutex_(new Mutex()),
799 boxed_field_list_(GrowableObjectArray::null()), 828 boxed_field_list_(GrowableObjectArray::null()),
800 disabling_field_list_(GrowableObjectArray::null()), 829 disabling_field_list_(GrowableObjectArray::null()),
801 spawn_count_monitor_(new Monitor()), 830 spawn_count_monitor_(new Monitor()),
802 spawn_count_(0) { 831 spawn_count_(0),
832 has_attempted_reload_(false),
833 no_reload_scope_depth_(0),
834 reload_context_(NULL) {
803 NOT_IN_PRODUCT(FlagsCopyFrom(api_flags)); 835 NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
804 // TODO(asiva): A Thread is not available here, need to figure out 836 // TODO(asiva): A Thread is not available here, need to figure out
805 // how the vm_tag (kEmbedderTagId) can be set, these tags need to 837 // how the vm_tag (kEmbedderTagId) can be set, these tags need to
806 // move to the OSThread structure. 838 // move to the OSThread structure.
807 set_user_tag(UserTags::kDefaultUserTag); 839 set_user_tag(UserTags::kDefaultUserTag);
808 } 840 }
809 841
810 #undef REUSABLE_HANDLE_SCOPE_INIT 842 #undef REUSABLE_HANDLE_SCOPE_INIT
811 #undef REUSABLE_HANDLE_INITIALIZERS 843 #undef REUSABLE_HANDLE_INITIALIZERS
812 844
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 // as 'load in progres'. Set the status to 'loaded'. 1041 // as 'load in progres'. Set the status to 'loaded'.
1010 if (lib.LoadInProgress()) { 1042 if (lib.LoadInProgress()) {
1011 lib.SetLoaded(); 1043 lib.SetLoaded();
1012 } 1044 }
1013 lib.InitExportedNamesCache(); 1045 lib.InitExportedNamesCache();
1014 } 1046 }
1015 TokenStream::CloseSharedTokenList(this); 1047 TokenStream::CloseSharedTokenList(this);
1016 } 1048 }
1017 1049
1018 1050
1051 bool Isolate::CanReload() const {
1052 #ifndef PRODUCT
1053 return (!ServiceIsolate::IsServiceIsolateDescendant(this) &&
1054 is_runnable() && !IsReloading() && no_reload_scope_depth_ == 0);
1055 #else
1056 return false;
1057 #endif
1058 }
1059
1060
1061 #ifndef PRODUCT
1062 void Isolate::ReportReloadError(const Error& error) {
1063 ASSERT(IsReloading());
1064 reload_context_->AbortReload(error);
1065 delete reload_context_;
1066 reload_context_ = NULL;
1067 }
1068
1069
1070 void Isolate::OnStackReload() {
1071 UNREACHABLE();
1072 }
1073
1074
1075 void Isolate::ReloadSources(bool test_mode) {
1076 ASSERT(!IsReloading());
1077 has_attempted_reload_ = true;
1078 reload_context_ = new IsolateReloadContext(this, test_mode);
1079 reload_context_->StartReload();
1080 }
1081
1082 #endif
1083
1084
1085 void Isolate::DoneFinalizing() {
1086 NOT_IN_PRODUCT(
1087 if (IsReloading()) {
1088 reload_context_->FinishReload();
1089 if (reload_context_->has_error() && reload_context_->test_mode()) {
1090 // If the reload has an error and we are in test mode keep the reload
1091 // context on the isolate so that it can be used by unit tests.
1092 return;
1093 }
1094 if (!reload_context_->has_error()) {
1095 reload_context_->ReportSuccess();
1096 }
1097 delete reload_context_;
1098 reload_context_ = NULL;
1099 }
1100 )
1101 }
1102
1103
1104
1019 bool Isolate::MakeRunnable() { 1105 bool Isolate::MakeRunnable() {
1020 ASSERT(Isolate::Current() == NULL); 1106 ASSERT(Isolate::Current() == NULL);
1021 1107
1022 MutexLocker ml(mutex_); 1108 MutexLocker ml(mutex_);
1023 // Check if we are in a valid state to make the isolate runnable. 1109 // Check if we are in a valid state to make the isolate runnable.
1024 if (is_runnable() == true) { 1110 if (is_runnable() == true) {
1025 return false; // Already runnable. 1111 return false; // Already runnable.
1026 } 1112 }
1027 // Set the isolate as runnable and if we are being spawned schedule 1113 // Set the isolate as runnable and if we are being spawned schedule
1028 // isolate on thread pool for execution. 1114 // isolate on thread pool for execution.
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 // 'disabling_field_list_' access via mutator and background compilation 1769 // 'disabling_field_list_' access via mutator and background compilation
1684 // threads is guarded with a monitor. This means that we can visit it only 1770 // threads is guarded with a monitor. This means that we can visit it only
1685 // when at safepoint or the field_list_mutex_ lock has been taken. 1771 // when at safepoint or the field_list_mutex_ lock has been taken.
1686 visitor->VisitPointer(reinterpret_cast<RawObject**>(&disabling_field_list_)); 1772 visitor->VisitPointer(reinterpret_cast<RawObject**>(&disabling_field_list_));
1687 1773
1688 // Visit objects in the debugger. 1774 // Visit objects in the debugger.
1689 if (FLAG_support_debugger) { 1775 if (FLAG_support_debugger) {
1690 debugger()->VisitObjectPointers(visitor); 1776 debugger()->VisitObjectPointers(visitor);
1691 } 1777 }
1692 1778
1779 NOT_IN_PRODUCT(
1780 // Visit objects that are being used for isolate reload.
1781 if (reload_context() != NULL) {
1782 reload_context()->VisitObjectPointers(visitor);
1783 }
1784 )
1785
1693 // Visit objects that are being used for deoptimization. 1786 // Visit objects that are being used for deoptimization.
1694 if (deopt_context() != NULL) { 1787 if (deopt_context() != NULL) {
1695 deopt_context()->VisitObjectPointers(visitor); 1788 deopt_context()->VisitObjectPointers(visitor);
1696 } 1789 }
1697 1790
1698 // Visit objects in all threads (e.g., Dart stack, handles in zones). 1791 // Visit objects in all threads (e.g., Dart stack, handles in zones).
1699 thread_registry()->VisitObjectPointers(visitor, validate_frames); 1792 thread_registry()->VisitObjectPointers(visitor, validate_frames);
1700 } 1793 }
1701 1794
1702 1795
1703 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { 1796 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
1704 if (api_state() != NULL) { 1797 if (api_state() != NULL) {
1705 api_state()->VisitWeakHandles(visitor); 1798 api_state()->VisitWeakHandles(visitor);
1706 } 1799 }
1707 } 1800 }
1708 1801
1709 1802
1710 void Isolate::PrepareForGC() { 1803 void Isolate::PrepareForGC() {
1711 thread_registry()->PrepareForGC(); 1804 thread_registry()->PrepareForGC();
1712 } 1805 }
1713 1806
1714 1807
1808 RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) {
1809 RawClass* raw_class = NULL;
1810 #ifndef PRODUCT
1811 if (IsReloading()) {
1812 raw_class = reload_context()->GetClassForHeapWalkAt(cid);
1813 } else {
1814 raw_class = class_table()->At(cid);
1815 }
1816 #else
1817 raw_class = class_table()->At(cid);
1818 #endif // !PRODUCT
1819 ASSERT(raw_class != NULL);
1820 ASSERT(raw_class->ptr()->id_ == cid);
1821 return raw_class;
1822 }
1823
1824
1715 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { 1825 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
1716 switch (pi) { 1826 switch (pi) {
1717 case kPauseOnAllExceptions: 1827 case kPauseOnAllExceptions:
1718 return "All"; 1828 return "All";
1719 case kNoPauseOnExceptions: 1829 case kNoPauseOnExceptions:
1720 return "None"; 1830 return "None";
1721 case kPauseOnUnhandledExceptions: 1831 case kPauseOnUnhandledExceptions:
1722 return "Unhandled"; 1832 return "Unhandled";
1723 default: 1833 default:
1724 UNIMPLEMENTED(); 1834 UNIMPLEMENTED();
(...skipping 23 matching lines...) Expand all
1748 jsobj.AddPropertyTimeMillis("startTime", start_time_millis); 1858 jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
1749 { 1859 {
1750 JSONObject jsheap(&jsobj, "_heaps"); 1860 JSONObject jsheap(&jsobj, "_heaps");
1751 heap()->PrintToJSONObject(Heap::kNew, &jsheap); 1861 heap()->PrintToJSONObject(Heap::kNew, &jsheap);
1752 heap()->PrintToJSONObject(Heap::kOld, &jsheap); 1862 heap()->PrintToJSONObject(Heap::kOld, &jsheap);
1753 } 1863 }
1754 1864
1755 jsobj.AddProperty("runnable", is_runnable()); 1865 jsobj.AddProperty("runnable", is_runnable());
1756 jsobj.AddProperty("livePorts", message_handler()->live_ports()); 1866 jsobj.AddProperty("livePorts", message_handler()->live_ports());
1757 jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit()); 1867 jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit());
1868 jsobj.AddProperty("_isReloading", IsReloading());
1758 1869
1759 if (debugger() != NULL) { 1870 if (debugger() != NULL) {
1760 if (!is_runnable()) { 1871 if (!is_runnable()) {
1761 // Isolate is not yet runnable. 1872 // Isolate is not yet runnable.
1762 ASSERT(debugger()->PauseEvent() == NULL); 1873 ASSERT(debugger()->PauseEvent() == NULL);
1763 ServiceEvent pause_event(this, ServiceEvent::kNone); 1874 ServiceEvent pause_event(this, ServiceEvent::kNone);
1764 jsobj.AddProperty("pauseEvent", &pause_event); 1875 jsobj.AddProperty("pauseEvent", &pause_event);
1765 } else if (message_handler()->is_paused_on_start() || 1876 } else if (message_handler()->is_paused_on_start() ||
1766 message_handler()->should_pause_on_start()) { 1877 message_handler()->should_pause_on_start()) {
1767 ASSERT(debugger()->PauseEvent() == NULL); 1878 ASSERT(debugger()->PauseEvent() == NULL);
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 if (pause_loop_monitor_ == NULL) { 2292 if (pause_loop_monitor_ == NULL) {
2182 pause_loop_monitor_ = new Monitor(); 2293 pause_loop_monitor_ = new Monitor();
2183 } 2294 }
2184 Dart_EnterScope(); 2295 Dart_EnterScope();
2185 MonitorLocker ml(pause_loop_monitor_); 2296 MonitorLocker ml(pause_loop_monitor_);
2186 2297
2187 Dart_MessageNotifyCallback saved_notify_callback = 2298 Dart_MessageNotifyCallback saved_notify_callback =
2188 message_notify_callback(); 2299 message_notify_callback();
2189 set_message_notify_callback(Isolate::WakePauseEventHandler); 2300 set_message_notify_callback(Isolate::WakePauseEventHandler);
2190 2301
2302 const bool had_isolate_reload_context = reload_context() != NULL;
2303 const int64_t start_time_micros =
2304 !had_isolate_reload_context ? 0 : reload_context()->start_time_micros();
2191 bool resume = false; 2305 bool resume = false;
2192 while (true) { 2306 while (true) {
2193 // Handle all available vm service messages, up to a resume 2307 // Handle all available vm service messages, up to a resume
2194 // request. 2308 // request.
2195 while (!resume && Dart_HasServiceMessages()) { 2309 while (!resume && Dart_HasServiceMessages()) {
2196 ml.Exit(); 2310 ml.Exit();
2197 resume = Dart_HandleServiceMessages(); 2311 resume = Dart_HandleServiceMessages();
2198 ml.Enter(); 2312 ml.Enter();
2199 } 2313 }
2200 if (resume) { 2314 if (resume) {
2201 break; 2315 break;
2202 } 2316 }
2203 2317
2318 if (had_isolate_reload_context && (reload_context() == NULL)) {
2319 const int64_t reload_time_micros =
2320 OS::GetCurrentMonotonicMicros() - start_time_micros;
2321 double reload_millis =
2322 MicrosecondsToMilliseconds(reload_time_micros);
2323 OS::Print("Reloading has finished! (%.2f ms)\n", reload_millis);
rmacnak 2016/05/13 17:59:34 if FLAG_trace_reload
Cutch 2016/05/17 18:03:52 Done.
2324 break;
2325 }
2326
2204 // Wait for more service messages. 2327 // Wait for more service messages.
2205 Monitor::WaitResult res = ml.Wait(); 2328 Monitor::WaitResult res = ml.Wait();
2206 ASSERT(res == Monitor::kNotified); 2329 ASSERT(res == Monitor::kNotified);
2207 } 2330 }
2208 set_message_notify_callback(saved_notify_callback); 2331 set_message_notify_callback(saved_notify_callback);
2209 Dart_ExitScope(); 2332 Dart_ExitScope();
2210 } 2333 }
2211 2334
2212 2335
2213 void Isolate::VisitIsolates(IsolateVisitor* visitor) { 2336 void Isolate::VisitIsolates(IsolateVisitor* visitor) {
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 void IsolateSpawnState::DecrementSpawnCount() { 2840 void IsolateSpawnState::DecrementSpawnCount() {
2718 ASSERT(spawn_count_monitor_ != NULL); 2841 ASSERT(spawn_count_monitor_ != NULL);
2719 ASSERT(spawn_count_ != NULL); 2842 ASSERT(spawn_count_ != NULL);
2720 MonitorLocker ml(spawn_count_monitor_); 2843 MonitorLocker ml(spawn_count_monitor_);
2721 ASSERT(*spawn_count_ > 0); 2844 ASSERT(*spawn_count_ > 0);
2722 *spawn_count_ = *spawn_count_ - 1; 2845 *spawn_count_ = *spawn_count_ - 1;
2723 ml.Notify(); 2846 ml.Notify();
2724 } 2847 }
2725 2848
2726 } // namespace dart 2849 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698