[vm] Better handle out-of-memory in the compiler.

TEST=run cfe tests with low heap limit
Change-Id: I527e853eeaf9cc810d141581cd623c2cf356df45
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214061
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Ryan Macnak 2021-09-28 18:42:23 +00:00 committed by commit-bot@chromium.org
parent 8e17ac781b
commit b8f0c8c917
4 changed files with 20 additions and 9 deletions

View file

@ -1347,6 +1347,7 @@ class CallSiteInliner : public ValueObject {
// changes while compiling. Propagate that 'error' and retry compilation
// later.
ASSERT(CompilerState::Current().is_aot() ||
(error.ptr() == Object::out_of_memory_error().ptr()) ||
Compiler::IsBackgroundCompilation() || error.IsUnhandledException());
Thread::Current()->long_jump_base()->Jump(1, error);
UNREACHABLE();

View file

@ -1177,7 +1177,7 @@ void Object::Init(IsolateGroup* isolate_group) {
LanguageError::New(error_str, Report::kBailout, Heap::kOld);
error_str = String::New("Out of memory", Heap::kOld);
*out_of_memory_error_ =
LanguageError::New(error_str, Report::kBailout, Heap::kOld);
LanguageError::New(error_str, Report::kError, Heap::kOld);
// Allocate the parameter arrays for method extractor types and names.
*extractor_parameter_types_ = Array::New(1, Heap::kOld);
@ -2639,9 +2639,7 @@ ObjectPtr Object::Allocate(intptr_t cls_id,
} else if (thread->top_exit_frame_info() != 0) {
// Use the preallocated out of memory exception to avoid calling
// into dart code or allocating any code.
const Instance& exception = Instance::Handle(
thread->isolate_group()->object_store()->out_of_memory());
Exceptions::Throw(thread, exception);
Exceptions::ThrowOOM();
UNREACHABLE();
} else {
// Nowhere to propagate an exception to.
@ -10089,6 +10087,10 @@ CodePtr Function::EnsureHasCode() const {
const Object& result =
Object::Handle(zone, Compiler::CompileFunction(thread, *this));
if (result.IsError()) {
if (result.ptr() == Object::out_of_memory_error().ptr()) {
Exceptions::ThrowOOM();
UNREACHABLE();
}
if (result.IsLanguageError()) {
Exceptions::ThrowCompileTimeError(LanguageError::Cast(result));
UNREACHABLE();
@ -10097,7 +10099,7 @@ CodePtr Function::EnsureHasCode() const {
UNREACHABLE();
}
// Compiling in unoptimized mode should never fail if there are no errors.
ASSERT(HasCode());
RELEASE_ASSERT(HasCode());
ASSERT(ForceOptimize() || unoptimized_code() == result.ptr());
return CurrentCode();
}

View file

@ -466,10 +466,7 @@ ErrorPtr Thread::HandleInterrupts() {
"\tisolate: %s\n",
isolate()->name());
}
NoSafepointScope no_safepoint;
ErrorPtr error = Thread::Current()->StealStickyError();
ASSERT(error->IsUnwindError());
return error;
return StealStickyError();
}
}
return Error::null();

View file

@ -181,6 +181,14 @@ CodePtr TypeTestingStubGenerator::OptimizedCodeForType(
if (!code.IsNull()) {
return code.ptr();
}
const Error& error = Error::Handle(Thread::Current()->StealStickyError());
if (!error.IsNull()) {
if (error.ptr() == Object::out_of_memory_error().ptr()) {
Exceptions::ThrowOOM();
} else {
UNREACHABLE();
}
}
// Fall back to default.
#else
@ -220,6 +228,9 @@ static CodePtr RetryCompilationWithFarBranches(
if (error.ptr() == Object::branch_offset_error().ptr()) {
ASSERT(!use_far_branches);
use_far_branches = true;
} else if (error.ptr() == Object::out_of_memory_error().ptr()) {
thread->set_sticky_error(error);
return Code::null();
} else {
UNREACHABLE();
}