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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/isolate.cc
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 2f219e6273d9be3a48e3c26f0ff91497fe676011..11f5536f6bf76b99f18a0955f57d382b2082b129 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -19,6 +19,7 @@
#include "vm/deopt_instructions.h"
#include "vm/flags.h"
#include "vm/heap.h"
+#include "vm/isolate_reload.h"
#include "vm/lockers.h"
#include "vm/log.h"
#include "vm/message_handler.h"
@@ -52,6 +53,7 @@ namespace dart {
DECLARE_FLAG(bool, print_metrics);
DECLARE_FLAG(bool, timing);
DECLARE_FLAG(bool, trace_service);
+DECLARE_FLAG(bool, trace_reload);
DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
NOT_IN_PRODUCT(
@@ -134,7 +136,28 @@ NoOOBMessageScope::~NoOOBMessageScope() {
+NoReloadScope::NoReloadScope(Isolate* isolate, Thread* thread)
+ : StackResource(thread),
+ isolate_(isolate) {
+ ASSERT(isolate_ != NULL);
+ isolate_->no_reload_scope_depth_++;
+ ASSERT(isolate_->no_reload_scope_depth_ >= 0);
+}
+
+
+NoReloadScope::~NoReloadScope() {
+ isolate_->no_reload_scope_depth_--;
+ ASSERT(isolate_->no_reload_scope_depth_ >= 0);
+}
+
+
void Isolate::RegisterClass(const Class& cls) {
+ NOT_IN_PRODUCT(
+ if (IsReloading()) {
+ reload_context()->RegisterClass(cls);
+ return;
+ }
+ )
class_table()->Register(cls);
}
@@ -624,6 +647,12 @@ static MessageHandler::MessageStatus StoreError(Thread* thread,
MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
const Error& result) {
+ NOT_IN_PRODUCT(
+ if (I->IsReloading()) {
+ I->ReportReloadError(result);
+ return kOK;
+ }
+ )
// Generate the error and stacktrace strings for the error message.
String& exc_str = String::Handle(T->zone());
String& stacktrace_str = String::Handle(T->zone());
@@ -785,6 +814,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
deoptimized_code_array_(GrowableObjectArray::null()),
sticky_error_(Error::null()),
background_compiler_(NULL),
+ background_compiler_disabled_depth_(0),
pending_service_extension_calls_(GrowableObjectArray::null()),
registered_service_extension_handlers_(GrowableObjectArray::null()),
metrics_list_head_(NULL),
@@ -799,7 +829,10 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
boxed_field_list_(GrowableObjectArray::null()),
disabling_field_list_(GrowableObjectArray::null()),
spawn_count_monitor_(new Monitor()),
- spawn_count_(0) {
+ spawn_count_(0),
+ has_attempted_reload_(false),
+ no_reload_scope_depth_(0),
+ reload_context_(NULL) {
NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
// TODO(asiva): A Thread is not available here, need to figure out
// how the vm_tag (kEmbedderTagId) can be set, these tags need to
@@ -1016,6 +1049,60 @@ void Isolate::DoneLoading() {
}
+bool Isolate::CanReload() const {
+#ifndef PRODUCT
+ return (!ServiceIsolate::IsServiceIsolateDescendant(this) &&
+ is_runnable() && !IsReloading() && no_reload_scope_depth_ == 0);
+#else
+ return false;
+#endif
+}
+
+
+#ifndef PRODUCT
+void Isolate::ReportReloadError(const Error& error) {
+ ASSERT(IsReloading());
+ reload_context_->AbortReload(error);
+ delete reload_context_;
+ reload_context_ = NULL;
+}
+
+
+void Isolate::OnStackReload() {
+ UNREACHABLE();
+}
+
+
+void Isolate::ReloadSources(bool test_mode) {
+ ASSERT(!IsReloading());
+ has_attempted_reload_ = true;
+ reload_context_ = new IsolateReloadContext(this, test_mode);
+ reload_context_->StartReload();
+}
+
+#endif
+
+
+void Isolate::DoneFinalizing() {
+ NOT_IN_PRODUCT(
+ if (IsReloading()) {
+ reload_context_->FinishReload();
+ if (reload_context_->has_error() && reload_context_->test_mode()) {
+ // If the reload has an error and we are in test mode keep the reload
+ // context on the isolate so that it can be used by unit tests.
+ return;
+ }
+ if (!reload_context_->has_error()) {
+ reload_context_->ReportSuccess();
+ }
+ delete reload_context_;
+ reload_context_ = NULL;
+ }
+ )
+}
+
+
+
bool Isolate::MakeRunnable() {
ASSERT(Isolate::Current() == NULL);
@@ -1690,6 +1777,13 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
debugger()->VisitObjectPointers(visitor);
}
+ NOT_IN_PRODUCT(
+ // Visit objects that are being used for isolate reload.
+ if (reload_context() != NULL) {
+ reload_context()->VisitObjectPointers(visitor);
+ }
+ )
+
// Visit objects that are being used for deoptimization.
if (deopt_context() != NULL) {
deopt_context()->VisitObjectPointers(visitor);
@@ -1712,6 +1806,23 @@ void Isolate::PrepareForGC() {
}
+RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) {
+ RawClass* raw_class = NULL;
+#ifndef PRODUCT
+ if (IsReloading()) {
+ raw_class = reload_context()->GetClassForHeapWalkAt(cid);
+ } else {
+ raw_class = class_table()->At(cid);
+ }
+#else
+ raw_class = class_table()->At(cid);
+#endif // !PRODUCT
+ ASSERT(raw_class != NULL);
+ ASSERT(raw_class->ptr()->id_ == cid);
+ return raw_class;
+}
+
+
static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
switch (pi) {
case kPauseOnAllExceptions:
@@ -1755,6 +1866,7 @@ void Isolate::PrintJSON(JSONStream* stream, bool ref) {
jsobj.AddProperty("runnable", is_runnable());
jsobj.AddProperty("livePorts", message_handler()->live_ports());
jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit());
+ jsobj.AddProperty("_isReloading", IsReloading());
if (debugger() != NULL) {
if (!is_runnable()) {
@@ -2187,6 +2299,9 @@ void Isolate::PauseEventHandler() {
message_notify_callback();
set_message_notify_callback(Isolate::WakePauseEventHandler);
+ const bool had_isolate_reload_context = reload_context() != NULL;
+ const int64_t start_time_micros =
+ !had_isolate_reload_context ? 0 : reload_context()->start_time_micros();
bool resume = false;
while (true) {
// Handle all available vm service messages, up to a resume
@@ -2200,6 +2315,17 @@ void Isolate::PauseEventHandler() {
break;
}
+ if (had_isolate_reload_context && (reload_context() == NULL)) {
+ if (FLAG_trace_reload) {
+ const int64_t reload_time_micros =
+ OS::GetCurrentMonotonicMicros() - start_time_micros;
+ double reload_millis =
+ MicrosecondsToMilliseconds(reload_time_micros);
+ OS::Print("Reloading has finished! (%.2f ms)\n", reload_millis);
+ }
+ break;
+ }
+
// Wait for more service messages.
Monitor::WaitResult res = ml.Wait();
ASSERT(res == Monitor::kNotified);

Powered by Google App Engine
This is Rietveld 408576698