1d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz/* 2d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * Copyright (C) 2014 The Android Open Source Project 3d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * 4d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * Licensed under the Apache License, Version 2.0 (the "License"); 5d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * you may not use this file except in compliance with the License. 6d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * You may obtain a copy of the License at 7d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * 8d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * http://www.apache.org/licenses/LICENSE-2.0 9d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * 10d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * Unless required by applicable law or agreed to in writing, software 11d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * distributed under the License is distributed on an "AS IS" BASIS, 12d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * See the License for the specific language governing permissions and 14d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz * limitations under the License. 15d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz */ 16d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 17fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#ifndef ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 18fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#define ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 19d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 20fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#include "base/logging.h" 21794ad76e8d5b5b9132819d5b08a0570e27615644Andreas Gampe#include "base/macros.h" 22fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#include "base/mutex.h" 23cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe#include "stack.h" // StackReference 24d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 25d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertznamespace art { 26d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 27fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertznamespace mirror { 28fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertzclass Throwable; 29fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz} // namespace mirror 30e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod; 31fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertzclass Context; 32fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertzclass Thread; 33fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertzclass ShadowFrame; 34fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz 35956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes// Manages exception delivery for Quick backend. 36fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertzclass QuickExceptionHandler { 37d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz public: 38fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz QuickExceptionHandler(Thread* self, bool is_deoptimization) 3990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 40d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 4165b798ea10dd716c1bb3dda029f9bf255435af72Andreas Gampe NO_RETURN ~QuickExceptionHandler() { 42d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz LOG(FATAL) << "UNREACHABLE"; // Expected to take long jump. 432c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 44d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 45d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 46520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Find the catch handler for the given exception. 4790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void FindCatch(mirror::Throwable* exception) SHARED_REQUIRES(Locks::mutator_lock_); 48520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz 49520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Deoptimize the stack to the upcall. For every compiled frame, we create a "copy" 50520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // shadow frame that will be executed with the interpreter. 5190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void DeoptimizeStack() SHARED_REQUIRES(Locks::mutator_lock_); 52639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe void DeoptimizeSingleFrame() SHARED_REQUIRES(Locks::mutator_lock_); 53639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe void DeoptimizeSingleFrameArchDependentFixup() SHARED_REQUIRES(Locks::mutator_lock_); 54639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe 55520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Update the instrumentation stack by removing all methods that will be unwound 56520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // by the exception being thrown. 5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void UpdateInstrumentationStack() SHARED_REQUIRES(Locks::mutator_lock_); 58520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz 5977a48ae01bbc5b05ca009cf09e2fcb53e4c8ff23David Brazdil // Set up environment before delivering an exception to optimized code. 6077a48ae01bbc5b05ca009cf09e2fcb53e4c8ff23David Brazdil void SetCatchEnvironmentForOptimizedHandler(StackVisitor* stack_visitor) 6177a48ae01bbc5b05ca009cf09e2fcb53e4c8ff23David Brazdil SHARED_REQUIRES(Locks::mutator_lock_); 6277a48ae01bbc5b05ca009cf09e2fcb53e4c8ff23David Brazdil 63520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Long jump either to a catch handler or to the upcall. 64639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe NO_RETURN void DoLongJump(bool smash_caller_saves = true) SHARED_REQUIRES(Locks::mutator_lock_); 65d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 66e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void SetHandlerQuickFrame(ArtMethod** handler_quick_frame) { 67d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz handler_quick_frame_ = handler_quick_frame; 68d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 69d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 70d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz void SetHandlerQuickFramePc(uintptr_t handler_quick_frame_pc) { 71d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz handler_quick_frame_pc_ = handler_quick_frame_pc; 72d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 73d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 74524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray void SetHandlerMethodHeader(const OatQuickMethodHeader* handler_method_header) { 75524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray handler_method_header_ = handler_method_header; 76524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray } 77524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray 78639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe void SetHandlerQuickArg0(uintptr_t handler_quick_arg0) { 79639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe handler_quick_arg0_ = handler_quick_arg0; 80639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe } 81639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe 82e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* GetHandlerMethod() const { 835cf98196d488437acd1e989c08a554ef697fded1Ian Rogers return handler_method_; 845cf98196d488437acd1e989c08a554ef697fded1Ian Rogers } 855cf98196d488437acd1e989c08a554ef697fded1Ian Rogers 86e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void SetHandlerMethod(ArtMethod* handler_quick_method) { 875cf98196d488437acd1e989c08a554ef697fded1Ian Rogers handler_method_ = handler_quick_method; 885cf98196d488437acd1e989c08a554ef697fded1Ian Rogers } 895cf98196d488437acd1e989c08a554ef697fded1Ian Rogers 905cf98196d488437acd1e989c08a554ef697fded1Ian Rogers uint32_t GetHandlerDexPc() const { 915cf98196d488437acd1e989c08a554ef697fded1Ian Rogers return handler_dex_pc_; 925cf98196d488437acd1e989c08a554ef697fded1Ian Rogers } 935cf98196d488437acd1e989c08a554ef697fded1Ian Rogers 94d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz void SetHandlerDexPc(uint32_t dex_pc) { 95d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz handler_dex_pc_ = dex_pc; 96d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 97d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 98d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz void SetClearException(bool clear_exception) { 99d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz clear_exception_ = clear_exception; 100d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 101d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 102649278cec7119cdd1bea3d0b710dbb2aa7c650b6Hiroshi Yamauchi void SetHandlerFrameDepth(size_t frame_depth) { 103649278cec7119cdd1bea3d0b710dbb2aa7c650b6Hiroshi Yamauchi handler_frame_depth_ = frame_depth; 104d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz } 105d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 106639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe // Walk the stack frames of the given thread, printing out non-runtime methods with their types 107639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe // of frames. Helps to verify that single-frame deopt really only deopted one frame. 108639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe static void DumpFramesWithType(Thread* self, bool details = false) 109639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe SHARED_REQUIRES(Locks::mutator_lock_); 110639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe 111d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz private: 112d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz Thread* const self_; 113d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz Context* const context_; 114520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Should we deoptimize the stack? 115d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz const bool is_deoptimization_; 116d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz // Is method tracing active? 117520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz const bool method_tracing_active_; 118d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz // Quick frame with found handler or last frame if no handler found. 119e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod** handler_quick_frame_; 120d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz // PC to branch to for the handler. 121d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz uintptr_t handler_quick_frame_pc_; 122524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray // Quick code of the handler. 123524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray const OatQuickMethodHeader* handler_method_header_; 124639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe // The value for argument 0. 125639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe uintptr_t handler_quick_arg0_; 1265cf98196d488437acd1e989c08a554ef697fded1Ian Rogers // The handler method to report to the debugger. 127e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* handler_method_; 1285cf98196d488437acd1e989c08a554ef697fded1Ian Rogers // The handler's dex PC, zero implies an uncaught exception. 129d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz uint32_t handler_dex_pc_; 130d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz // Should the exception be cleared as the catch block has no move-exception? 131d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz bool clear_exception_; 132649278cec7119cdd1bea3d0b710dbb2aa7c650b6Hiroshi Yamauchi // Frame depth of the catch handler or the upcall. 133649278cec7119cdd1bea3d0b710dbb2aa7c650b6Hiroshi Yamauchi size_t handler_frame_depth_; 134d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 135fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz DISALLOW_COPY_AND_ASSIGN(QuickExceptionHandler); 136d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz}; 137d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz 138d45a1f5d1dd5bc9badfab3a8aee90c934d9f2227Sebastien Hertz} // namespace art 139fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#endif // ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 140