summaryrefslogtreecommitdiff
path: root/runtime/thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/thread.cc')
-rw-r--r--runtime/thread.cc55
1 files changed, 30 insertions, 25 deletions
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 1d7e0659fb..f1f4a122b4 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -55,6 +55,7 @@
#include "mirror/object_array-inl.h"
#include "mirror/stack_trace_element.h"
#include "monitor.h"
+#include "nth_caller_visitor.h"
#include "oat_quick_method_header.h"
#include "object_lock.h"
#include "quick_exception_handler.h"
@@ -84,6 +85,8 @@
namespace art {
+extern "C" NO_RETURN void artDeoptimize(Thread* self);
+
bool Thread::is_started_ = false;
pthread_key_t Thread::pthread_key_self_;
ConditionVariable* Thread::resume_cond_ = nullptr;
@@ -270,7 +273,6 @@ ShadowFrame* Thread::PopStackedShadowFrame(StackedShadowFrameType type, bool mus
StackedShadowFrameRecord* record = tlsPtr_.stacked_shadow_frame_record;
if (must_be_present) {
DCHECK(record != nullptr);
- DCHECK_EQ(record->GetType(), type);
} else {
if (record == nullptr || record->GetType() != type) {
return nullptr;
@@ -2583,38 +2585,42 @@ void Thread::QuickDeliverException() {
// Get exception from thread.
mirror::Throwable* exception = GetException();
CHECK(exception != nullptr);
- bool is_deoptimization = (exception == GetDeoptimizationException());
- if (!is_deoptimization) {
- // This is a real exception: let the instrumentation know about it.
- instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
- if (instrumentation->HasExceptionCaughtListeners() &&
- IsExceptionThrownByCurrentMethod(exception)) {
- // Instrumentation may cause GC so keep the exception object safe.
- StackHandleScope<1> hs(this);
- HandleWrapper<mirror::Throwable> h_exception(hs.NewHandleWrapper(&exception));
- instrumentation->ExceptionCaughtEvent(this, exception);
- }
- // Does instrumentation need to deoptimize the stack?
- // Note: we do this *after* reporting the exception to instrumentation in case it
- // now requires deoptimization. It may happen if a debugger is attached and requests
- // new events (single-step, breakpoint, ...) when the exception is reported.
- is_deoptimization = Dbg::IsForcedInterpreterNeededForException(this);
- if (is_deoptimization) {
+ if (exception == GetDeoptimizationException()) {
+ artDeoptimize(this);
+ UNREACHABLE();
+ }
+
+ // This is a real exception: let the instrumentation know about it.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ if (instrumentation->HasExceptionCaughtListeners() &&
+ IsExceptionThrownByCurrentMethod(exception)) {
+ // Instrumentation may cause GC so keep the exception object safe.
+ StackHandleScope<1> hs(this);
+ HandleWrapper<mirror::Throwable> h_exception(hs.NewHandleWrapper(&exception));
+ instrumentation->ExceptionCaughtEvent(this, exception);
+ }
+ // Does instrumentation need to deoptimize the stack?
+ // Note: we do this *after* reporting the exception to instrumentation in case it
+ // now requires deoptimization. It may happen if a debugger is attached and requests
+ // new events (single-step, breakpoint, ...) when the exception is reported.
+ if (Dbg::IsForcedInterpreterNeededForException(this)) {
+ NthCallerVisitor visitor(this, 0, false);
+ visitor.WalkStack();
+ if (Runtime::Current()->IsDeoptimizeable(visitor.caller_pc)) {
// Save the exception into the deoptimization context so it can be restored
// before entering the interpreter.
PushDeoptimizationContext(
JValue(), /*is_reference */ false, /* from_code */ false, exception);
+ artDeoptimize(this);
+ UNREACHABLE();
}
}
+
// Don't leave exception visible while we try to find the handler, which may cause class
// resolution.
ClearException();
- QuickExceptionHandler exception_handler(this, is_deoptimization);
- if (is_deoptimization) {
- exception_handler.DeoptimizeStack();
- } else {
- exception_handler.FindCatch(exception);
- }
+ QuickExceptionHandler exception_handler(this, false);
+ exception_handler.FindCatch(exception);
exception_handler.UpdateInstrumentationStack();
exception_handler.DoLongJump();
}
@@ -3024,7 +3030,6 @@ void Thread::DeoptimizeWithDeoptimizationException(JValue* result) {
mirror::Throwable* pending_exception = nullptr;
bool from_code = false;
PopDeoptimizationContext(result, &pending_exception, &from_code);
- CHECK(!from_code) << "Deoptimizing from code should be done with single frame deoptimization";
SetTopOfStack(nullptr);
SetTopOfShadowStack(shadow_frame);