1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 18 #define ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 19 20 #include "base/logging.h" 21 #include "base/macros.h" 22 #include "base/mutex.h" 23 #include "stack.h" // StackReference 24 25 namespace art { 26 27 namespace mirror { 28 class Throwable; 29 } // namespace mirror 30 class ArtMethod; 31 class Context; 32 class Thread; 33 class ShadowFrame; 34 35 // Manages exception delivery for Quick backend. 36 class QuickExceptionHandler { 37 public: 38 QuickExceptionHandler(Thread* self, bool is_deoptimization) 39 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 40 ~QuickExceptionHandler()41 NO_RETURN ~QuickExceptionHandler() { 42 LOG(FATAL) << "UNREACHABLE"; // Expected to take long jump. 43 UNREACHABLE(); 44 } 45 46 void FindCatch(mirror::Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 47 void DeoptimizeStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 48 void UpdateInstrumentationStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 49 NO_RETURN void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 50 SetHandlerQuickFrame(ArtMethod ** handler_quick_frame)51 void SetHandlerQuickFrame(ArtMethod** handler_quick_frame) { 52 handler_quick_frame_ = handler_quick_frame; 53 } 54 SetHandlerQuickFramePc(uintptr_t handler_quick_frame_pc)55 void SetHandlerQuickFramePc(uintptr_t handler_quick_frame_pc) { 56 handler_quick_frame_pc_ = handler_quick_frame_pc; 57 } 58 GetHandlerMethod()59 ArtMethod* GetHandlerMethod() const { 60 return handler_method_; 61 } 62 SetHandlerMethod(ArtMethod * handler_quick_method)63 void SetHandlerMethod(ArtMethod* handler_quick_method) { 64 handler_method_ = handler_quick_method; 65 } 66 GetHandlerDexPc()67 uint32_t GetHandlerDexPc() const { 68 return handler_dex_pc_; 69 } 70 SetHandlerDexPc(uint32_t dex_pc)71 void SetHandlerDexPc(uint32_t dex_pc) { 72 handler_dex_pc_ = dex_pc; 73 } 74 SetClearException(bool clear_exception)75 void SetClearException(bool clear_exception) { 76 clear_exception_ = clear_exception; 77 } 78 SetHandlerFrameDepth(size_t frame_depth)79 void SetHandlerFrameDepth(size_t frame_depth) { 80 handler_frame_depth_ = frame_depth; 81 } 82 83 private: 84 Thread* const self_; 85 Context* const context_; 86 const bool is_deoptimization_; 87 // Is method tracing active? 88 const bool method_tracing_active_; 89 // Quick frame with found handler or last frame if no handler found. 90 ArtMethod** handler_quick_frame_; 91 // PC to branch to for the handler. 92 uintptr_t handler_quick_frame_pc_; 93 // The handler method to report to the debugger. 94 ArtMethod* handler_method_; 95 // The handler's dex PC, zero implies an uncaught exception. 96 uint32_t handler_dex_pc_; 97 // Should the exception be cleared as the catch block has no move-exception? 98 bool clear_exception_; 99 // Frame depth of the catch handler or the upcall. 100 size_t handler_frame_depth_; 101 102 DISALLOW_COPY_AND_ASSIGN(QuickExceptionHandler); 103 }; 104 105 } // namespace art 106 #endif // ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 107