Fix sticky error propagation from thread to isolate

BUG=
R=asiva@google.com, iposva@google.com

Review URL: https://codereview.chromium.org/1769183003 .
This commit is contained in:
Srdjan Mitrovic 2016-03-09 12:40:43 -08:00
parent ed52614322
commit 60ce67d91f
3 changed files with 33 additions and 8 deletions

View file

@ -1605,10 +1605,13 @@ static void RunLoopDone(uword param) {
DART_EXPORT Dart_Handle Dart_RunLoop() {
Thread* T = Thread::Current();
Isolate* I = T->isolate();
CHECK_API_SCOPE(T);
CHECK_CALLBACK_STATE(T);
Isolate* I;
{
Thread* T = Thread::Current();
I = T->isolate();
CHECK_API_SCOPE(T);
CHECK_CALLBACK_STATE(T);
}
API_TIMELINE_BEGIN_END;
// The message handler run loop does not expect to have a current isolate
// so we exit the isolate here and enter it again after the runloop is done.
@ -1627,13 +1630,14 @@ DART_EXPORT Dart_Handle Dart_RunLoop() {
}
}
::Dart_EnterIsolate(Api::CastIsolate(I));
if (T->sticky_error() != Object::null()) {
Dart_Handle error = Api::NewHandle(T, T->sticky_error());
T->clear_sticky_error();
if (I->sticky_error() != Object::null()) {
Dart_Handle error =
Api::NewHandle(Thread::Current(), I->sticky_error());
I->clear_sticky_error();
return error;
}
if (FLAG_print_class_table) {
HANDLESCOPE(T);
HANDLESCOPE(Thread::Current());
I->class_table()->Print();
}
return Api::Success();

View file

@ -813,6 +813,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
object_id_ring_(NULL),
tag_table_(GrowableObjectArray::null()),
deoptimized_code_array_(GrowableObjectArray::null()),
sticky_error_(Error::null()),
background_compiler_(NULL),
pending_service_extension_calls_(GrowableObjectArray::null()),
registered_service_extension_handlers_(GrowableObjectArray::null()),
@ -1864,6 +1865,9 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&deoptimized_code_array_));
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&sticky_error_));
// Visit the pending service extension calls.
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
@ -2081,6 +2085,11 @@ void Isolate::TrackDeoptimizedCode(const Code& code) {
}
void Isolate::clear_sticky_error() {
sticky_error_ = Error::null();
}
void Isolate::set_pending_service_extension_calls(
const GrowableObjectArray& value) {
pending_service_extension_calls_ = value.raw();
@ -2592,6 +2601,13 @@ void Isolate::UnscheduleThread(Thread* thread,
// so we create a MonitorLocker object which does not do any
// no_safepoint_scope_depth increments/decrements.
MonitorLocker ml(threads_lock(), false);
if (is_mutator) {
if (thread->sticky_error() != Error::null()) {
ASSERT(sticky_error_ == Error::null());
sticky_error_ = thread->sticky_error();
thread->clear_sticky_error();
}
}
if (!bypass_safepoint) {
// Ensure that the thread reports itself as being at a safepoint.
thread->EnterSafepoint();

View file

@ -581,6 +581,9 @@ class Isolate : public BaseIsolate {
void set_deoptimized_code_array(const GrowableObjectArray& value);
void TrackDeoptimizedCode(const Code& code);
RawError* sticky_error() const { return sticky_error_; }
void clear_sticky_error();
bool compilation_allowed() const { return compilation_allowed_; }
void set_compilation_allowed(bool allowed) {
compilation_allowed_ = allowed;
@ -808,6 +811,8 @@ class Isolate : public BaseIsolate {
RawGrowableObjectArray* deoptimized_code_array_;
RawError* sticky_error_;
// Background compilation.
BackgroundCompiler* background_compiler_;