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

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

Issue 2201283002: Fix reload handling of unwind / stackoverflow errors (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: status file addition Created 4 years, 4 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
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | tests/lib/lib.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 358
359 359
360 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, 360 IsolateReloadContext::IsolateReloadContext(Isolate* isolate,
361 JSONStream* js) 361 JSONStream* js)
362 : zone_(Thread::Current()->zone()), 362 : zone_(Thread::Current()->zone()),
363 start_time_micros_(OS::GetCurrentMonotonicMicros()), 363 start_time_micros_(OS::GetCurrentMonotonicMicros()),
364 reload_timestamp_(OS::GetCurrentTimeMillis()), 364 reload_timestamp_(OS::GetCurrentTimeMillis()),
365 isolate_(isolate), 365 isolate_(isolate),
366 reload_skipped_(false), 366 reload_skipped_(false),
367 reload_aborted_(false), 367 reload_aborted_(false),
368 reload_finalized_(false),
368 js_(js), 369 js_(js),
369 saved_num_cids_(-1), 370 saved_num_cids_(-1),
370 saved_class_table_(NULL), 371 saved_class_table_(NULL),
371 num_saved_libs_(-1), 372 num_saved_libs_(-1),
372 instance_morphers_(zone_, 0), 373 instance_morphers_(zone_, 0),
373 reasons_to_cancel_reload_(zone_, 0), 374 reasons_to_cancel_reload_(zone_, 0),
374 cid_mapper_(), 375 cid_mapper_(),
375 modified_libs_(NULL), 376 modified_libs_(NULL),
376 script_uri_(String::null()), 377 script_uri_(String::null()),
377 error_(Error::null()), 378 error_(Error::null()),
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 468
468 // Ensure all functions on the stack have unoptimized code. 469 // Ensure all functions on the stack have unoptimized code.
469 EnsuredUnoptimizedCodeForStack(); 470 EnsuredUnoptimizedCodeForStack();
470 // Deoptimize all code that had optimizing decisions that are dependent on 471 // Deoptimize all code that had optimizing decisions that are dependent on
471 // assumptions from field guards or CHA or deferred library prefixes. 472 // assumptions from field guards or CHA or deferred library prefixes.
472 // TODO(johnmccutchan): Deoptimizing dependent code here (before the reload) 473 // TODO(johnmccutchan): Deoptimizing dependent code here (before the reload)
473 // is paranoid. This likely can be moved to the commit phase. 474 // is paranoid. This likely can be moved to the commit phase.
474 DeoptimizeDependentCode(); 475 DeoptimizeDependentCode();
475 Checkpoint(); 476 Checkpoint();
476 477
478 // WEIRD CONTROL FLOW BEGINS.
479 //
480 // The flow of execution until we return from the tag handler can be complex.
481 //
482 // On a successful load, the following will occur:
483 // 1) Tag Handler is invoked and the embedder is in control.
484 // 2) All sources and libraries are loaded.
485 // 3) Dart_FinalizeLoading is called by the embedder.
486 // 4) Dart_FinalizeLoading invokes IsolateReloadContext::FinalizeLoading
487 // and we are temporarily back in control.
488 // This is where we validate the reload and commit or reject.
489 // 5) Dart_FinalizeLoading invokes Dart code related to deferred libraries.
490 // 6) The tag handler returns and we move on.
491 //
492 // Even after a successful reload the Dart code invoked in (5) can result
493 // in an Unwind error or a StackOverflow error. This error will be returned
494 // by the tag handler. The tag handler can return other errors, for example,
495 // top level parse errors. We want to capture these errors while propagating
496 // the Unwind or StackOverflow errors.
477 Object& result = Object::Handle(thread->zone()); 497 Object& result = Object::Handle(thread->zone());
478 { 498 {
479 TransitionVMToNative transition(thread); 499 TransitionVMToNative transition(thread);
480 Api::Scope api_scope(thread); 500 Api::Scope api_scope(thread);
481 501
482 Dart_Handle retval = 502 Dart_Handle retval =
483 (I->library_tag_handler())(Dart_kScriptTag, 503 (I->library_tag_handler())(Dart_kScriptTag,
484 Api::NewHandle(thread, Library::null()), 504 Api::NewHandle(thread, Library::null()),
485 Api::NewHandle(thread, root_lib_url.raw())); 505 Api::NewHandle(thread, root_lib_url.raw()));
486 result = Api::UnwrapHandle(retval); 506 result = Api::UnwrapHandle(retval);
487 } 507 }
508 //
509 // WEIRD CONTROL FLOW ENDS.
488 510
489 BackgroundCompiler::Enable(); 511 BackgroundCompiler::Enable();
490 512
491 if (result.IsUnwindError()) { 513 if (result.IsUnwindError() ||
492 // Ignore an unwind error because the isolate is dead. 514 (result.raw() == isolate()->object_store()->stack_overflow())) {
493 return; 515 // When returning from the tag handler with an Unwind error or a
516 // StackOverflow error, propagate it and give up.
517 Exceptions::PropagateError(Error::Cast(result));
518 UNREACHABLE();
494 } 519 }
495 520
521 // Other errors (e.g. a parse error) are captured by the reload system.
496 if (result.IsError()) { 522 if (result.IsError()) {
497 FinalizeFailedLoad(Error::Cast(result)); 523 FinalizeFailedLoad(Error::Cast(result));
498 } 524 }
499 } 525 }
500 526
501 527
502 void IsolateReloadContext::RegisterClass(const Class& new_cls) { 528 void IsolateReloadContext::RegisterClass(const Class& new_cls) {
503 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); 529 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls));
504 if (old_cls.IsNull()) { 530 if (old_cls.IsNull()) {
505 I->class_table()->Register(new_cls); 531 I->class_table()->Register(new_cls);
(...skipping 18 matching lines...) Expand all
524 AddClassMapping(new_cls, old_cls); 550 AddClassMapping(new_cls, old_cls);
525 } 551 }
526 552
527 553
528 // FinalizeLoading will be called *before* Reload() returns but will not be 554 // FinalizeLoading will be called *before* Reload() returns but will not be
529 // called if the embedder fails to load sources. 555 // called if the embedder fails to load sources.
530 void IsolateReloadContext::FinalizeLoading() { 556 void IsolateReloadContext::FinalizeLoading() {
531 if (reload_skipped_) { 557 if (reload_skipped_) {
532 return; 558 return;
533 } 559 }
560 ASSERT(!reload_finalized_);
534 BuildLibraryMapping(); 561 BuildLibraryMapping();
535 TIR_Print("---- LOAD SUCCEEDED\n"); 562 TIR_Print("---- LOAD SUCCEEDED\n");
536 if (ValidateReload()) { 563 if (ValidateReload()) {
537 Commit(); 564 Commit();
538 PostCommit(); 565 PostCommit();
539 isolate()->set_last_reload_timestamp(reload_timestamp_); 566 isolate()->set_last_reload_timestamp(reload_timestamp_);
540 } else { 567 } else {
541 ReportReasonsForCancelling(); 568 ReportReasonsForCancelling();
542 Rollback(); 569 Rollback();
543 } 570 }
544 // ValidateReload mutates the direct subclass information and does 571 // ValidateReload mutates the direct subclass information and does
545 // not remove dead subclasses. Rebuild the direct subclass 572 // not remove dead subclasses. Rebuild the direct subclass
546 // information from scratch. 573 // information from scratch.
547 RebuildDirectSubclasses(); 574 RebuildDirectSubclasses();
548
549 CommonFinalizeTail(); 575 CommonFinalizeTail();
550 } 576 }
551 577
552 578
553 // FinalizeFailedLoad will be called *before* Reload() returns and will only 579 // FinalizeFailedLoad will be called *before* Reload() returns and will only
554 // be called if the embedder fails to load sources. 580 // be called if the embedder fails to load sources.
555 void IsolateReloadContext::FinalizeFailedLoad(const Error& error) { 581 void IsolateReloadContext::FinalizeFailedLoad(const Error& error) {
556 TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n"); 582 TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n");
557 AddReasonForCancelling(new Aborted(zone_, error)); 583 AddReasonForCancelling(new Aborted(zone_, error));
558 ReportReasonsForCancelling(); 584 ReportReasonsForCancelling();
559 Rollback(); 585 if (!reload_finalized_) {
586 Rollback();
587 }
560 CommonFinalizeTail(); 588 CommonFinalizeTail();
561 } 589 }
562 590
563 591
564 void IsolateReloadContext::CommonFinalizeTail() { 592 void IsolateReloadContext::CommonFinalizeTail() {
565 ReportOnJSON(js_); 593 ReportOnJSON(js_);
594 reload_finalized_ = true;
566 } 595 }
567 596
568 597
569 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) { 598 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) {
599 // Clear the buffer.
600 stream->buffer()->Clear();
570 JSONObject jsobj(stream); 601 JSONObject jsobj(stream);
571 jsobj.AddProperty("type", "ReloadReport"); 602 jsobj.AddProperty("type", "ReloadReport");
572 jsobj.AddProperty("success", !HasReasonsForCancelling()); 603 jsobj.AddProperty("success", !HasReasonsForCancelling());
573 { 604 {
574 JSONObject details(&jsobj, "details"); 605 JSONObject details(&jsobj, "details");
575 if (HasReasonsForCancelling()) { 606 if (HasReasonsForCancelling()) {
576 // Reload was rejected. 607 // Reload was rejected.
577 JSONArray array(&jsobj, "notices"); 608 JSONArray array(&jsobj, "notices");
578 for (intptr_t i = 0; i < reasons_to_cancel_reload_.length(); i++) { 609 for (intptr_t i = 0; i < reasons_to_cancel_reload_.length(); i++) {
579 ReasonForCancelling* reason = reasons_to_cancel_reload_.At(i); 610 ReasonForCancelling* reason = reasons_to_cancel_reload_.At(i);
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 ASSERT(!super_cls.IsNull()); 1644 ASSERT(!super_cls.IsNull());
1614 super_cls.AddDirectSubclass(cls); 1645 super_cls.AddDirectSubclass(cls);
1615 } 1646 }
1616 } 1647 }
1617 } 1648 }
1618 } 1649 }
1619 1650
1620 #endif // !PRODUCT 1651 #endif // !PRODUCT
1621 1652
1622 } // namespace dart 1653 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | tests/lib/lib.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698