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

Unified Diff: runtime/vm/isolate_reload.cc

Issue 2512483002: Support reloading from source on top of a script snapshot. (Closed)
Patch Set: ... Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/object_reload.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/isolate_reload.cc
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index b8f1713dd822cdda97591eb52499b2a95662ec36..c375df3b8048c91b524acab028509d6a0b95a8ef 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -420,7 +420,11 @@ bool IsolateReloadContext::IsSameClass(const Class& a, const Class& b) {
const Library& a_lib = Library::Handle(a.library());
const Library& b_lib = Library::Handle(b.library());
- return IsSameLibrary(a_lib, b_lib);
+
+ if (a_lib.IsNull() || b_lib.IsNull()) {
+ return a_lib.raw() == b_lib.raw();
+ }
+ return (a_lib.private_key() == b_lib.private_key());
}
@@ -450,7 +454,7 @@ IsolateReloadContext::IsolateReloadContext(Isolate* isolate, JSONStream* js)
reasons_to_cancel_reload_(zone_, 0),
cid_mapper_(),
modified_libs_(NULL),
- script_uri_(String::null()),
+ script_url_(String::null()),
error_(Error::null()),
old_classes_set_storage_(Array::null()),
class_map_storage_(Array::null()),
@@ -459,7 +463,9 @@ IsolateReloadContext::IsolateReloadContext(Isolate* isolate, JSONStream* js)
become_map_storage_(Array::null()),
become_enum_mappings_(GrowableObjectArray::null()),
saved_root_library_(Library::null()),
- saved_libraries_(GrowableObjectArray::null()) {
+ saved_libraries_(GrowableObjectArray::null()),
+ root_url_prefix_(String::null()),
+ old_root_url_prefix_(String::null()) {
// NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not
// associated with the isolate yet and if a GC is triggered here the raw
// objects will not be properly accounted for.
@@ -502,20 +508,58 @@ class Aborted : public ReasonForCancelling {
};
+static intptr_t CommonSuffixLength(const char* a, const char* b) {
+ const intptr_t a_length = strlen(a);
+ const intptr_t b_length = strlen(b);
+ intptr_t a_cursor = a_length;
+ intptr_t b_cursor = b_length;
+
+ while ((a_cursor >= 0) && (b_cursor >= 0)) {
+ if (a[a_cursor] != b[b_cursor]) {
+ break;
+ }
+ a_cursor--;
+ b_cursor--;
+ }
+
+ ASSERT((a_length - a_cursor) == (b_length - b_cursor));
+ return (a_length - a_cursor);
+}
+
+
// NOTE: This function returns *after* FinalizeLoading is called.
-void IsolateReloadContext::Reload(bool force_reload) {
+void IsolateReloadContext::Reload(bool force_reload,
+ const char* root_script_url,
+ const char* packages_url_) {
TIMELINE_SCOPE(Reload);
Thread* thread = Thread::Current();
ASSERT(isolate() == thread->isolate());
// Grab root library before calling CheckpointBeforeReload.
- const Library& root_lib = Library::Handle(object_store()->root_library());
- ASSERT(!root_lib.IsNull());
- const String& root_lib_url = String::Handle(root_lib.url());
+ const Library& old_root_lib = Library::Handle(object_store()->root_library());
+ ASSERT(!old_root_lib.IsNull());
+ const String& old_root_lib_url = String::Handle(old_root_lib.url());
+ // Root library url.
+ const String& root_lib_url =
+ (root_script_url == NULL) ? old_root_lib_url
+ : String::Handle(String::New(root_script_url));
+
+ // Check to see if the base url of the loaded libraries has moved.
+ if (!old_root_lib_url.Equals(root_lib_url)) {
+ const char* old_root_library_url_c = old_root_lib_url.ToCString();
+ const char* root_library_url_c = root_lib_url.ToCString();
+ const intptr_t common_suffix_length =
+ CommonSuffixLength(root_library_url_c, old_root_library_url_c);
+ root_url_prefix_ = String::SubString(
+ root_lib_url, 0, root_lib_url.Length() - common_suffix_length + 1);
+ old_root_url_prefix_ =
+ String::SubString(old_root_lib_url, 0,
+ old_root_lib_url.Length() - common_suffix_length + 1);
+ }
// Check to see which libraries have been modified.
modified_libs_ = FindModifiedLibraries(force_reload);
- if (!modified_libs_->Contains(root_lib.index())) {
+ if (!modified_libs_->Contains(old_root_lib.index())) {
ASSERT(modified_libs_->IsEmpty());
reload_skipped_ = true;
ReportOnJSON(js_);
@@ -570,17 +614,25 @@ void IsolateReloadContext::Reload(bool force_reload) {
// for example, top level parse errors. We want to capture these errors while
// propagating the UnwindError or an UnhandledException error.
Object& result = Object::Handle(thread->zone());
+
+ String& packages_url = String::Handle();
+ if (packages_url_ != NULL) {
+ packages_url = String::New(packages_url_);
+ }
+
+ TIR_Print("---- ENTERING TAG HANDLER\n");
{
TransitionVMToNative transition(thread);
Api::Scope api_scope(thread);
Dart_Handle retval = (I->library_tag_handler())(
- Dart_kScriptTag, Api::NewHandle(thread, Library::null()),
+ Dart_kScriptTag, Api::NewHandle(thread, packages_url.raw()),
Api::NewHandle(thread, root_lib_url.raw()));
result = Api::UnwrapHandle(retval);
}
//
// WEIRD CONTROL FLOW ENDS.
+ TIR_Print("---- EXITED TAG HANDLER\n");
BackgroundCompiler::Enable();
@@ -613,6 +665,7 @@ void IsolateReloadContext::RegisterClass(const Class& new_cls) {
AddClassMapping(new_cls, new_cls);
return;
}
+ VTIR_Print("Registering class: %s\n", new_cls.ToCString());
new_cls.set_id(old_cls.id());
isolate()->class_table()->SetAt(old_cls.id(), new_cls.raw());
if (!old_cls.is_enum_class()) {
@@ -1658,6 +1711,11 @@ RawString* IsolateReloadContext::FindLibraryPrivateKey(
if (old.IsNull()) {
return String::null();
}
+#if defined(DEBUG)
+ VTIR_Print("`%s` is getting `%s`'s private key.\n",
+ String::Handle(replacement_or_new.url()).ToCString(),
+ String::Handle(old.url()).ToCString());
+#endif
return old.private_key();
}
@@ -1669,10 +1727,54 @@ RawLibrary* IsolateReloadContext::OldLibraryOrNull(
Library& lib = Library::Handle();
lib ^= old_libraries_set.GetOrNull(replacement_or_new);
old_libraries_set.Release();
+ if (lib.IsNull() && (root_url_prefix_ != String::null()) &&
+ (old_root_url_prefix_ != String::null())) {
+ return OldLibraryOrNullBaseMoved(replacement_or_new);
+ }
return lib.raw();
}
+// Attempt to find the pair to |replacement_or_new| with the knowledge that
+// the base url prefix has moved.
+RawLibrary* IsolateReloadContext::OldLibraryOrNullBaseMoved(
+ const Library& replacement_or_new) {
+ const String& url_prefix = String::Handle(root_url_prefix_);
+ const String& old_url_prefix = String::Handle(old_root_url_prefix_);
+ const intptr_t prefix_length = url_prefix.Length();
+ const intptr_t old_prefix_length = old_url_prefix.Length();
+ const String& new_url = String::Handle(replacement_or_new.url());
+ const String& suffix =
+ String::Handle(String::SubString(new_url, prefix_length));
+ if (!new_url.StartsWith(url_prefix)) {
+ return Library::null();
+ }
+ Library& old = Library::Handle();
+ String& old_url = String::Handle();
+ String& old_suffix = String::Handle();
+ GrowableObjectArray& saved_libs =
+ GrowableObjectArray::Handle(saved_libraries());
+ ASSERT(!saved_libs.IsNull());
+ for (intptr_t i = 0; i < saved_libs.Length(); i++) {
+ old = Library::RawCast(saved_libs.At(i));
+ old_url = old.url();
+ if (!old_url.StartsWith(old_url_prefix)) {
+ continue;
+ }
+ old_suffix ^= String::SubString(old_url, old_prefix_length);
+ if (old_suffix.IsNull()) {
+ continue;
+ }
+ if (old_suffix.Equals(suffix)) {
+ TIR_Print("`%s` is moving to `%s`\n", old_url.ToCString(),
+ new_url.ToCString());
+ return old.raw();
+ }
+ }
+ return Library::null();
+}
+
+
void IsolateReloadContext::BuildLibraryMapping() {
const GrowableObjectArray& libs =
GrowableObjectArray::Handle(object_store()->libraries());
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/object_reload.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698