Check the to-space invariant on a delivered exception.
Test: art/test/testrunner/testrunner.py
Bug: 62339341
Bug: 12687968
Change-Id: Ida5e91031cd94429a72fcc9d4d1333d21dd07421
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index d8b6237..f94923e 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -166,10 +166,9 @@
<< 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 8090f9b..12b63c9 100644
--- a/runtime/quick_exception_handler.h
+++ b/runtime/quick_exception_handler.h
@@ -112,6 +112,10 @@
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 968a23b..2412931 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3080,6 +3080,10 @@
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 @@
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();
}