From 639bdd13993644a267f177f8f5936496bda65e2b Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 3 Jun 2015 11:22:45 -0700 Subject: ART: Single-frame deopt Add deoptimization of a single frame. Works by removing the managed code frame and jumping into the quick-to-interpreter bridge, and the bridge understanding a stored ShadowFrame. We need a separate fixup pass. For x86, we leave the return address on the stack so we don't need to push it there. Bug: 21611912 Change-Id: I06625685ced8b054244f8685ab50b238a705b9d2 --- runtime/quick_exception_handler.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'runtime/quick_exception_handler.h') diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h index 2e05c7e1e5..89d6a25128 100644 --- a/runtime/quick_exception_handler.h +++ b/runtime/quick_exception_handler.h @@ -49,6 +49,9 @@ class QuickExceptionHandler { // Deoptimize the stack to the upcall. For every compiled frame, we create a "copy" // shadow frame that will be executed with the interpreter. void DeoptimizeStack() SHARED_REQUIRES(Locks::mutator_lock_); + void DeoptimizeSingleFrame() SHARED_REQUIRES(Locks::mutator_lock_); + void DeoptimizeSingleFrameArchDependentFixup() SHARED_REQUIRES(Locks::mutator_lock_); + // Update the instrumentation stack by removing all methods that will be unwound // by the exception being thrown. void UpdateInstrumentationStack() SHARED_REQUIRES(Locks::mutator_lock_); @@ -58,7 +61,7 @@ class QuickExceptionHandler { SHARED_REQUIRES(Locks::mutator_lock_); // Long jump either to a catch handler or to the upcall. - NO_RETURN void DoLongJump() SHARED_REQUIRES(Locks::mutator_lock_); + NO_RETURN void DoLongJump(bool smash_caller_saves = true) SHARED_REQUIRES(Locks::mutator_lock_); void SetHandlerQuickFrame(ArtMethod** handler_quick_frame) { handler_quick_frame_ = handler_quick_frame; @@ -68,6 +71,10 @@ class QuickExceptionHandler { handler_quick_frame_pc_ = handler_quick_frame_pc; } + void SetHandlerQuickArg0(uintptr_t handler_quick_arg0) { + handler_quick_arg0_ = handler_quick_arg0; + } + ArtMethod* GetHandlerMethod() const { return handler_method_; } @@ -92,6 +99,11 @@ class QuickExceptionHandler { handler_frame_depth_ = frame_depth; } + // Walk the stack frames of the given thread, printing out non-runtime methods with their types + // of frames. Helps to verify that single-frame deopt really only deopted one frame. + static void DumpFramesWithType(Thread* self, bool details = false) + SHARED_REQUIRES(Locks::mutator_lock_); + private: Thread* const self_; Context* const context_; @@ -103,6 +115,8 @@ class QuickExceptionHandler { ArtMethod** handler_quick_frame_; // PC to branch to for the handler. uintptr_t handler_quick_frame_pc_; + // The value for argument 0. + uintptr_t handler_quick_arg0_; // The handler method to report to the debugger. ArtMethod* handler_method_; // The handler's dex PC, zero implies an uncaught exception. -- cgit v1.2.3-59-g8ed1b