diff options
-rw-r--r-- | runtime/quick_exception_handler.cc | 7 | ||||
-rw-r--r-- | runtime/quick_exception_handler.h | 4 | ||||
-rw-r--r-- | runtime/thread.cc | 16 |
3 files changed, 23 insertions, 4 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index d8b62370b8..f94923e065 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -166,10 +166,9 @@ void QuickExceptionHandler::FindCatch(ObjPtr<mirror::Throwable> exception) { << line_number << ")"; } } - if (clear_exception_) { - // Exception was cleared as part of delivery. - DCHECK(!self_->IsExceptionPending()); - } else { + // Exception was cleared as part of delivery. + DCHECK(!self_->IsExceptionPending()); + if (!clear_exception_) { // Put exception back in root set with clear throw location. self_->SetException(exception_ref.Get()); } diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h index 8090f9b035..12b63c933d 100644 --- a/runtime/quick_exception_handler.h +++ b/runtime/quick_exception_handler.h @@ -112,6 +112,10 @@ class QuickExceptionHandler { handler_dex_pc_ = dex_pc; } + bool GetClearException() const { + return clear_exception_; + } + void SetClearException(bool clear_exception) { clear_exception_ = clear_exception; } diff --git a/runtime/thread.cc b/runtime/thread.cc index 968a23b926..24129315b3 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -3080,6 +3080,10 @@ void Thread::QuickDeliverException() { UNREACHABLE(); } + if (kUseReadBarrier) { + ReadBarrier::AssertToSpaceInvariant(exception.Ptr()); + } + // This is a real exception: let the instrumentation know about it. instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (instrumentation->HasExceptionThrownListeners() && @@ -3121,6 +3125,18 @@ void Thread::QuickDeliverException() { QuickExceptionHandler exception_handler(this, false); exception_handler.FindCatch(exception); exception_handler.UpdateInstrumentationStack(); + if (exception_handler.GetClearException()) { + // Exception was cleared as part of delivery. + DCHECK(!IsExceptionPending()); + } else { + // Exception was put back with a throw location. + DCHECK(IsExceptionPending()); + if (kUseReadBarrier) { + // Check the to-space invariant on the re-installed exception. + ObjPtr<mirror::Throwable> reinstalled_exception = GetException(); + ReadBarrier::AssertToSpaceInvariant(reinstalled_exception.Ptr()); + } + } exception_handler.DoLongJump(); } |