diff options
Diffstat (limited to 'runtime/thread.cc')
-rw-r--r-- | runtime/thread.cc | 55 |
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); |