| Index: vm/snapshot.cc
|
| ===================================================================
|
| --- vm/snapshot.cc (revision 15761)
|
| +++ vm/snapshot.cc (working copy)
|
| @@ -157,6 +157,7 @@
|
| tokens_(Array::Handle()),
|
| stream_(TokenStream::Handle()),
|
| data_(ExternalUint8Array::Handle()),
|
| + error_(UnhandledException::Handle()),
|
| backward_references_((kind == Snapshot::kFull) ?
|
| kNumInitialReferencesInFullSnapshot :
|
| kNumInitialReferences) {
|
| @@ -164,14 +165,29 @@
|
|
|
|
|
| RawObject* SnapshotReader::ReadObject() {
|
| - Object& obj = Object::Handle(ReadObjectImpl());
|
| - for (intptr_t i = 0; i < backward_references_.length(); i++) {
|
| - if (!backward_references_[i]->is_deserialized()) {
|
| - ReadObjectImpl();
|
| - backward_references_[i]->set_state(kIsDeserialized);
|
| + // Setup for long jump in case there is an exception while reading.
|
| + LongJump* base = isolate()->long_jump_base();
|
| + LongJump jump;
|
| + isolate()->set_long_jump_base(&jump);
|
| + const Instance& null_object = Instance::Handle();
|
| + *ErrorHandle() = UnhandledException::New(null_object, null_object);
|
| + if (setjmp(*jump.Set()) == 0) {
|
| + Object& obj = Object::Handle(ReadObjectImpl());
|
| + for (intptr_t i = 0; i < backward_references_.length(); i++) {
|
| + if (!backward_references_[i]->is_deserialized()) {
|
| + ReadObjectImpl();
|
| + backward_references_[i]->set_state(kIsDeserialized);
|
| + }
|
| }
|
| + isolate()->set_long_jump_base(base);
|
| + return obj.raw();
|
| + } else {
|
| + // An error occurred while reading, return the error object.
|
| + const Error& err = Error::Handle(isolate()->object_store()->sticky_error());
|
| + isolate()->object_store()->clear_sticky_error();
|
| + isolate()->set_long_jump_base(base);
|
| + return err.raw();
|
| }
|
| - return obj.raw();
|
| }
|
|
|
|
|
| @@ -615,10 +631,12 @@
|
| if (address == 0) {
|
| // Use the preallocated out of memory exception to avoid calling
|
| // into dart code or allocating any code.
|
| + // We do a longjmp at this point to unwind out of the entire
|
| + // read part and return the error object back.
|
| const Instance& exception =
|
| Instance::Handle(object_store()->out_of_memory());
|
| - Exceptions::Throw(exception);
|
| - UNREACHABLE();
|
| + ErrorHandle()->set_exception(exception);
|
| + Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle());
|
| }
|
| RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
|
| uword tags = 0;
|
|
|