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/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 #define I (isolate()) | 41 #define I (isolate()) |
42 #define Z (thread->zone()) | 42 #define Z (thread->zone()) |
43 | 43 |
44 #define TIMELINE_SCOPE(name) \ | 44 #define TIMELINE_SCOPE(name) \ |
45 TimelineDurationScope tds##name(Thread::Current(), \ | 45 TimelineDurationScope tds##name(Thread::Current(), \ |
46 Timeline::GetIsolateStream(), \ | 46 Timeline::GetIsolateStream(), \ |
47 #name) | 47 #name) |
48 | 48 |
49 | 49 |
50 InstanceMorpher::InstanceMorpher(const Class& from, const Class& to) | 50 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) |
51 : from_(from), to_(to), mapping_() { | 51 : from_(from), to_(to), mapping_() { |
52 ComputeMapping(); | 52 ComputeMapping(); |
53 before_ = new ZoneGrowableArray<const Instance*>(); | 53 before_ = new ZoneGrowableArray<const Instance*>(zone, 0); |
54 after_ = new ZoneGrowableArray<const Instance*>(); | 54 after_ = new ZoneGrowableArray<const Instance*>(zone, 0); |
55 ASSERT(from_.id() == to_.id()); | 55 ASSERT(from_.id() == to_.id()); |
56 cid_ = from_.id(); | 56 cid_ = from_.id(); |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 void InstanceMorpher::AddObject(RawObject* object) const { | 60 void InstanceMorpher::AddObject(RawObject* object) const { |
61 ASSERT(object->GetClassId() == cid()); | 61 ASSERT(object->GetClassId() == cid()); |
62 const Instance& instance = Instance::Cast(Object::Handle(object)); | 62 const Instance& instance = Instance::Cast(Object::Handle(object)); |
63 before_->Add(&instance); | 63 before_->Add(&instance); |
64 } | 64 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 void ClassReasonForCancelling::AppendTo(JSONArray* array) { | 209 void ClassReasonForCancelling::AppendTo(JSONArray* array) { |
210 JSONObject jsobj(array); | 210 JSONObject jsobj(array); |
211 jsobj.AddProperty("type", "ReasonForCancelling"); | 211 jsobj.AddProperty("type", "ReasonForCancelling"); |
212 jsobj.AddProperty("class", from_); | 212 jsobj.AddProperty("class", from_); |
213 const String& message = String::Handle(ToString()); | 213 const String& message = String::Handle(ToString()); |
214 jsobj.AddProperty("message", message); | 214 jsobj.AddProperty("message", message); |
215 } | 215 } |
216 | 216 |
217 | 217 |
218 RawError* IsolateReloadContext::error() const { | 218 RawError* IsolateReloadContext::error() const { |
219 ASSERT(has_error()); | 219 ASSERT(reload_aborted()); |
220 // Report the first error to the surroundings. | 220 // Report the first error to the surroundings. |
221 const Error& error = | 221 const Error& error = |
222 Error::Handle(reasons_to_cancel_reload_.At(0)->ToError()); | 222 Error::Handle(reasons_to_cancel_reload_.At(0)->ToError()); |
223 return error.raw(); | 223 return error.raw(); |
224 } | 224 } |
225 | 225 |
226 | 226 |
227 class ScriptUrlSetTraits { | 227 class ScriptUrlSetTraits { |
228 public: | 228 public: |
229 static bool ReportStats() { return false; } | 229 static bool ReportStats() { return false; } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 const String& a_lib_url = | 352 const String& a_lib_url = |
353 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); | 353 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); |
354 const String& b_lib_url = | 354 const String& b_lib_url = |
355 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); | 355 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); |
356 return a_lib_url.Equals(b_lib_url); | 356 return a_lib_url.Equals(b_lib_url); |
357 } | 357 } |
358 | 358 |
359 | 359 |
360 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, | 360 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, |
361 JSONStream* js) | 361 JSONStream* js) |
362 : start_time_micros_(OS::GetCurrentMonotonicMicros()), | 362 : zone_(Thread::Current()->zone()), |
| 363 start_time_micros_(OS::GetCurrentMonotonicMicros()), |
363 reload_timestamp_(OS::GetCurrentTimeMillis()), | 364 reload_timestamp_(OS::GetCurrentTimeMillis()), |
364 isolate_(isolate), | 365 isolate_(isolate), |
365 reload_skipped_(false), | 366 reload_skipped_(false), |
| 367 reload_aborted_(false), |
366 js_(js), | 368 js_(js), |
367 saved_num_cids_(-1), | 369 saved_num_cids_(-1), |
368 saved_class_table_(NULL), | 370 saved_class_table_(NULL), |
369 num_saved_libs_(-1), | 371 num_saved_libs_(-1), |
370 instance_morphers_(), | 372 instance_morphers_(), |
371 reasons_to_cancel_reload_(), | 373 reasons_to_cancel_reload_(), |
372 cid_mapper_(), | 374 cid_mapper_(), |
373 modified_libs_(NULL), | 375 modified_libs_(NULL), |
374 script_uri_(String::null()), | 376 script_uri_(String::null()), |
375 error_(Error::null()), | 377 error_(Error::null()), |
376 old_classes_set_storage_(Array::null()), | 378 old_classes_set_storage_(Array::null()), |
377 class_map_storage_(Array::null()), | 379 class_map_storage_(Array::null()), |
378 old_libraries_set_storage_(Array::null()), | 380 old_libraries_set_storage_(Array::null()), |
379 library_map_storage_(Array::null()), | 381 library_map_storage_(Array::null()), |
380 become_map_storage_(Array::null()), | 382 become_map_storage_(Array::null()), |
381 become_enum_mappings_(GrowableObjectArray::null()), | 383 become_enum_mappings_(GrowableObjectArray::null()), |
382 saved_root_library_(Library::null()), | 384 saved_root_library_(Library::null()), |
383 saved_libraries_(GrowableObjectArray::null()) { | 385 saved_libraries_(GrowableObjectArray::null()) { |
384 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not | 386 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not |
385 // associated with the isolate yet and if a GC is triggered here the raw | 387 // associated with the isolate yet and if a GC is triggered here the raw |
386 // objects will not be properly accounted for. | 388 // objects will not be properly accounted for. |
| 389 ASSERT(zone_ != NULL); |
387 } | 390 } |
388 | 391 |
389 | 392 |
390 IsolateReloadContext::~IsolateReloadContext() { | 393 IsolateReloadContext::~IsolateReloadContext() { |
391 } | 394 } |
392 | 395 |
393 | 396 |
394 void IsolateReloadContext::ReportError(const Error& error) { | 397 void IsolateReloadContext::ReportError(const Error& error) { |
395 if (FLAG_trace_reload) { | 398 if (FLAG_trace_reload) { |
396 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); | 399 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); |
397 } | 400 } |
398 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); | 401 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
399 service_event.set_reload_error(&error); | 402 service_event.set_reload_error(&error); |
400 Service::HandleEvent(&service_event); | 403 Service::HandleEvent(&service_event); |
401 } | 404 } |
402 | 405 |
403 | 406 |
404 void IsolateReloadContext::ReportSuccess() { | 407 void IsolateReloadContext::ReportSuccess() { |
405 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); | 408 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
406 Service::HandleEvent(&service_event); | 409 Service::HandleEvent(&service_event); |
407 } | 410 } |
408 | 411 |
409 | 412 |
410 class Aborted : public ReasonForCancelling { | 413 class Aborted : public ReasonForCancelling { |
411 public: | 414 public: |
412 explicit Aborted(const Error& error) | 415 explicit Aborted(Zone* zone, const Error& error) |
413 : ReasonForCancelling(), error_(error) { } | 416 : ReasonForCancelling(zone), error_(error) { } |
414 | 417 |
415 private: | 418 private: |
416 const Error& error_; | 419 const Error& error_; |
417 | 420 |
418 RawError* ToError() { return error_.raw(); } | 421 RawError* ToError() { return error_.raw(); } |
419 RawString* ToString() { | 422 RawString* ToString() { |
420 return String::NewFormatted("%s", error_.ToErrorCString()); | 423 return String::NewFormatted("%s", error_.ToErrorCString()); |
421 } | 424 } |
422 }; | 425 }; |
423 | 426 |
424 | 427 |
425 void IsolateReloadContext::StartReload(bool force_reload) { | 428 // NOTE: This function returns *after* FinalizeLoading is called. |
| 429 void IsolateReloadContext::Reload(bool force_reload) { |
426 TIMELINE_SCOPE(Reload); | 430 TIMELINE_SCOPE(Reload); |
427 Thread* thread = Thread::Current(); | 431 Thread* thread = Thread::Current(); |
428 ASSERT(isolate() == thread->isolate()); | 432 ASSERT(isolate() == thread->isolate()); |
429 | 433 |
430 // Grab root library before calling CheckpointBeforeReload. | 434 // Grab root library before calling CheckpointBeforeReload. |
431 const Library& root_lib = Library::Handle(object_store()->root_library()); | 435 const Library& root_lib = Library::Handle(object_store()->root_library()); |
432 ASSERT(!root_lib.IsNull()); | 436 ASSERT(!root_lib.IsNull()); |
433 const String& root_lib_url = String::Handle(root_lib.url()); | 437 const String& root_lib_url = String::Handle(root_lib.url()); |
434 | 438 |
435 // Check to see which libraries have been modified. | 439 // Check to see which libraries have been modified. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 Api::Scope api_scope(thread); | 483 Api::Scope api_scope(thread); |
480 | 484 |
481 Dart_Handle retval = | 485 Dart_Handle retval = |
482 (I->library_tag_handler())(Dart_kScriptTag, | 486 (I->library_tag_handler())(Dart_kScriptTag, |
483 Api::NewHandle(thread, Library::null()), | 487 Api::NewHandle(thread, Library::null()), |
484 Api::NewHandle(thread, root_lib_url.raw())); | 488 Api::NewHandle(thread, root_lib_url.raw())); |
485 result = Api::UnwrapHandle(retval); | 489 result = Api::UnwrapHandle(retval); |
486 } | 490 } |
487 if (result.IsError()) { | 491 if (result.IsError()) { |
488 const Error& error = Error::Cast(result); | 492 const Error& error = Error::Cast(result); |
489 AddReasonForCancelling(new Aborted(error)); | 493 AddReasonForCancelling(new Aborted(zone_, error)); |
490 } | 494 } |
491 } | 495 } |
492 | 496 |
493 | 497 |
494 void IsolateReloadContext::RegisterClass(const Class& new_cls) { | 498 void IsolateReloadContext::RegisterClass(const Class& new_cls) { |
495 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); | 499 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); |
496 if (old_cls.IsNull()) { | 500 if (old_cls.IsNull()) { |
497 I->class_table()->Register(new_cls); | 501 I->class_table()->Register(new_cls); |
498 | 502 |
499 if (FLAG_identity_reload) { | 503 if (FLAG_identity_reload) { |
(...skipping 10 matching lines...) Expand all Loading... |
510 isolate()->class_table()->SetAt(old_cls.id(), new_cls.raw()); | 514 isolate()->class_table()->SetAt(old_cls.id(), new_cls.raw()); |
511 if (!old_cls.is_enum_class()) { | 515 if (!old_cls.is_enum_class()) { |
512 new_cls.CopyCanonicalConstants(old_cls); | 516 new_cls.CopyCanonicalConstants(old_cls); |
513 } | 517 } |
514 new_cls.CopyCanonicalType(old_cls); | 518 new_cls.CopyCanonicalType(old_cls); |
515 AddBecomeMapping(old_cls, new_cls); | 519 AddBecomeMapping(old_cls, new_cls); |
516 AddClassMapping(new_cls, old_cls); | 520 AddClassMapping(new_cls, old_cls); |
517 } | 521 } |
518 | 522 |
519 | 523 |
520 void IsolateReloadContext::FinishReload() { | 524 // FinalizeLoading will be called *before* Reload() returns. |
| 525 void IsolateReloadContext::FinalizeLoading() { |
521 if (reload_skipped_) { | 526 if (reload_skipped_) { |
522 return; | 527 return; |
523 } | 528 } |
524 BuildLibraryMapping(); | 529 BuildLibraryMapping(); |
525 TIR_Print("---- DONE FINALIZING\n"); | 530 TIR_Print("---- DONE FINALIZING\n"); |
526 if (ValidateReload()) { | 531 if (ValidateReload()) { |
527 Commit(); | 532 Commit(); |
528 PostCommit(); | 533 PostCommit(); |
529 isolate()->set_last_reload_timestamp(reload_timestamp_); | 534 isolate()->set_last_reload_timestamp(reload_timestamp_); |
530 } else { | 535 } else { |
531 ReportReasonsForCancelling(); | 536 ReportReasonsForCancelling(); |
532 Rollback(); | 537 Rollback(); |
533 } | 538 } |
534 // ValidateReload mutates the direct subclass information and does | 539 // ValidateReload mutates the direct subclass information and does |
535 // not remove dead subclasses. Rebuild the direct subclass | 540 // not remove dead subclasses. Rebuild the direct subclass |
536 // information from scratch. | 541 // information from scratch. |
537 RebuildDirectSubclasses(); | 542 RebuildDirectSubclasses(); |
538 | 543 |
539 if (FLAG_write_protect_code) { | 544 if (FLAG_write_protect_code) { |
540 // Re-enable code page write protection. | 545 // Re-enable code page write protection. |
541 I->heap()->WriteProtectCode(true); | 546 I->heap()->WriteProtectCode(true); |
542 } | 547 } |
543 | 548 |
544 BackgroundCompiler::Enable(); | 549 BackgroundCompiler::Enable(); |
545 | 550 |
| 551 reload_aborted_ = HasReasonsForCancelling(); |
546 ReportOnJSON(js_); | 552 ReportOnJSON(js_); |
547 } | 553 } |
548 | 554 |
549 | 555 |
550 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) { | 556 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) { |
551 JSONObject jsobj(stream); | 557 JSONObject jsobj(stream); |
552 jsobj.AddProperty("type", "ReloadReport"); | 558 jsobj.AddProperty("type", "ReloadReport"); |
553 jsobj.AddProperty("success", !HasReasonsForCancelling()); | 559 jsobj.AddProperty("success", !HasReasonsForCancelling()); |
554 { | 560 { |
555 JSONObject details(&jsobj, "details"); | 561 JSONObject details(&jsobj, "details"); |
(...skipping 17 matching lines...) Expand all Loading... |
573 JSONArray array(&jsobj, "shapeChangeMappings"); | 579 JSONArray array(&jsobj, "shapeChangeMappings"); |
574 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { | 580 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { |
575 instance_morphers_.At(i)->AppendTo(&array); | 581 instance_morphers_.At(i)->AppendTo(&array); |
576 } | 582 } |
577 } | 583 } |
578 } | 584 } |
579 } | 585 } |
580 | 586 |
581 | 587 |
582 void IsolateReloadContext::AbortReload(const Error& error) { | 588 void IsolateReloadContext::AbortReload(const Error& error) { |
583 AddReasonForCancelling(new Aborted(error)); | 589 AddReasonForCancelling(new Aborted(zone_, error)); |
584 ReportReasonsForCancelling(); | 590 ReportReasonsForCancelling(); |
585 Rollback(); | 591 Rollback(); |
586 } | 592 } |
587 | 593 |
588 | 594 |
589 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { | 595 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { |
590 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack); | 596 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack); |
591 StackFrameIterator it(StackFrameIterator::kDontValidateFrames); | 597 StackFrameIterator it(StackFrameIterator::kDontValidateFrames); |
592 | 598 |
593 Function& func = Function::Handle(); | 599 Function& func = Function::Handle(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 | 721 |
716 const GrowableObjectArray& libs = | 722 const GrowableObjectArray& libs = |
717 GrowableObjectArray::Handle(object_store()->libraries()); | 723 GrowableObjectArray::Handle(object_store()->libraries()); |
718 Library& lib = Library::Handle(); | 724 Library& lib = Library::Handle(); |
719 Array& scripts = Array::Handle(); | 725 Array& scripts = Array::Handle(); |
720 Script& script = Script::Handle(); | 726 Script& script = Script::Handle(); |
721 intptr_t num_libs = libs.Length(); | 727 intptr_t num_libs = libs.Length(); |
722 | 728 |
723 // Construct the imported-by graph. | 729 // Construct the imported-by graph. |
724 ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by = | 730 ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by = |
725 new ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >(num_libs); | 731 new ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >(zone_, num_libs); |
726 imported_by->SetLength(num_libs); | 732 imported_by->SetLength(num_libs); |
727 for (intptr_t i = 0; i < num_libs; i++) { | 733 for (intptr_t i = 0; i < num_libs; i++) { |
728 (*imported_by)[i] = new ZoneGrowableArray<intptr_t>(); | 734 (*imported_by)[i] = new ZoneGrowableArray<intptr_t>(zone_, 0); |
729 } | 735 } |
730 Array& ports = Array::Handle(); | 736 Array& ports = Array::Handle(); |
731 Namespace& ns = Namespace::Handle(); | 737 Namespace& ns = Namespace::Handle(); |
732 Library& target = Library::Handle(); | 738 Library& target = Library::Handle(); |
733 | 739 |
734 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { | 740 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { |
735 lib ^= libs.At(lib_idx); | 741 lib ^= libs.At(lib_idx); |
736 ASSERT(lib_idx == lib.index()); | 742 ASSERT(lib_idx == lib.index()); |
737 if (lib.is_dart_scheme()) { | 743 if (lib.is_dart_scheme()) { |
738 // We don't care about imports among dart scheme libraries. | 744 // We don't care about imports among dart scheme libraries. |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt. | 1216 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt. |
1211 // Instance will from now be described by the isolate's class table. | 1217 // Instance will from now be described by the isolate's class table. |
1212 free(saved_class_table_); | 1218 free(saved_class_table_); |
1213 saved_class_table_ = NULL; | 1219 saved_class_table_ = NULL; |
1214 Become::ElementsForwardIdentity(before, after); | 1220 Become::ElementsForwardIdentity(before, after); |
1215 } | 1221 } |
1216 | 1222 |
1217 | 1223 |
1218 bool IsolateReloadContext::ValidateReload() { | 1224 bool IsolateReloadContext::ValidateReload() { |
1219 TIMELINE_SCOPE(ValidateReload); | 1225 TIMELINE_SCOPE(ValidateReload); |
1220 if (has_error()) return false; | 1226 if (reload_aborted()) return false; |
1221 | 1227 |
1222 // Validate libraries. | 1228 // Validate libraries. |
1223 { | 1229 { |
1224 ASSERT(library_map_storage_ != Array::null()); | 1230 ASSERT(library_map_storage_ != Array::null()); |
1225 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); | 1231 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); |
1226 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map); | 1232 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map); |
1227 Library& lib = Library::Handle(); | 1233 Library& lib = Library::Handle(); |
1228 Library& new_lib = Library::Handle(); | 1234 Library& new_lib = Library::Handle(); |
1229 while (it.MoveNext()) { | 1235 while (it.MoveNext()) { |
1230 const intptr_t entry = it.Current(); | 1236 const intptr_t entry = it.Current(); |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 ASSERT(!super_cls.IsNull()); | 1602 ASSERT(!super_cls.IsNull()); |
1597 super_cls.AddDirectSubclass(cls); | 1603 super_cls.AddDirectSubclass(cls); |
1598 } | 1604 } |
1599 } | 1605 } |
1600 } | 1606 } |
1601 } | 1607 } |
1602 | 1608 |
1603 #endif // !PRODUCT | 1609 #endif // !PRODUCT |
1604 | 1610 |
1605 } // namespace dart | 1611 } // namespace dart |
OLD | NEW |