summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/quick_exception_handler.cc7
-rw-r--r--runtime/quick_exception_handler.h4
-rw-r--r--runtime/thread.cc16
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();
}