[vm, reload] Ensure the reload context is torn down properly when kernel loading fails for lack of memory.

Previously the OOM would be delivered to the enclosing exit frame, bypassing the reload context properly tearing down. In particular, this meant the VM continued to use the class table saved on the reload context, which didn't contain classes finalized after the reload was aborted.

TEST=scavenger_abort
Bug: https://github.com/dart-lang/sdk/issues/43118
Change-Id: I96ad227dbd961cd5755ce0de0483d7d74b6667e2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173142
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 18a32b7..a9e660f 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -19,6 +19,7 @@
 #include "vm/kernel_isolate.h"
 #include "vm/kernel_loader.h"
 #include "vm/log.h"
+#include "vm/longjump.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
@@ -1099,20 +1100,25 @@
     const String& root_lib_url) {
   Thread* thread = Thread::Current();
 
-  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
-  if (tmp.IsError()) {
-    return tmp.raw();
-  }
+  LongJumpScope jump;
+  if (setjmp(*jump.Set()) == 0) {
+    const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
+    if (tmp.IsError()) {
+      return tmp.raw();
+    }
 
-  // If main method disappeared or were not there to begin with then
-  // KernelLoader will return null. In this case lookup library by
-  // URL.
-  auto& lib = Library::Handle(Library::RawCast(tmp.raw()));
-  if (lib.IsNull()) {
-    lib = Library::LookupLibrary(thread, root_lib_url);
+    // If main method disappeared or were not there to begin with then
+    // KernelLoader will return null. In this case lookup library by
+    // URL.
+    auto& lib = Library::Handle(Library::RawCast(tmp.raw()));
+    if (lib.IsNull()) {
+      lib = Library::LookupLibrary(thread, root_lib_url);
+    }
+    isolate_->object_store()->set_root_library(lib);
+    return Object::null();
+  } else {
+    return thread->StealStickyError();
   }
-  isolate_->object_store()->set_root_library(lib);
-  return Object::null();
 }
 
 void IsolateReloadContext::ReloadPhase3FinalizeLoading() {