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/mutex.h" 22 #include "stack.h" // StackReference 23 24 namespace art { 25 26 namespace mirror { 27 class ArtMethod; 28 class Throwable; 29 } // namespace mirror 30 class Context; 31 class Thread; 32 class ThrowLocation; 33 class ShadowFrame; 34 35 // Manages exception delivery for Quick backend. Not used by Portable backend. 36 class QuickExceptionHandler { 37 public: 38 QuickExceptionHandler(Thread* self, bool is_deoptimization) 39 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 40 41 ~QuickExceptionHandler() { 42 LOG(FATAL) << "UNREACHABLE"; // Expected to take long jump. 43 } 44 45 void FindCatch(const ThrowLocation& throw_location, mirror::Throwable* exception, 46 bool is_exception_reported) 47 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 48 void DeoptimizeStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 49 void UpdateInstrumentationStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 50 void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 51 52 void SetHandlerQuickFrame(StackReference<mirror::ArtMethod>* handler_quick_frame) { 53 handler_quick_frame_ = handler_quick_frame; 54 } 55 56 void SetHandlerQuickFramePc(uintptr_t handler_quick_frame_pc) { 57 handler_quick_frame_pc_ = handler_quick_frame_pc; 58 } 59 60 mirror::ArtMethod* GetHandlerMethod() const { 61 return handler_method_; 62 } 63 64 void SetHandlerMethod(mirror::ArtMethod* handler_quick_method) { 65 handler_method_ = handler_quick_method; 66 } 67 68 uint32_t GetHandlerDexPc() const { 69 return handler_dex_pc_; 70 } 71 72 void SetHandlerDexPc(uint32_t dex_pc) { 73 handler_dex_pc_ = dex_pc; 74 } 75 76 void SetClearException(bool clear_exception) { 77 clear_exception_ = clear_exception; 78 } 79 80 void SetHandlerFrameDepth(size_t frame_depth) { 81 handler_frame_depth_ = frame_depth; 82 } 83 84 private: 85 Thread* const self_; 86 Context* const context_; 87 const bool is_deoptimization_; 88 // Is method tracing active? 89 const bool method_tracing_active_; 90 // Quick frame with found handler or last frame if no handler found. 91 StackReference<mirror::ArtMethod>* handler_quick_frame_; 92 // PC to branch to for the handler. 93 uintptr_t handler_quick_frame_pc_; 94 // The handler method to report to the debugger. 95 mirror::ArtMethod* handler_method_; 96 // The handler's dex PC, zero implies an uncaught exception. 97 uint32_t handler_dex_pc_; 98 // Should the exception be cleared as the catch block has no move-exception? 99 bool clear_exception_; 100 // Frame depth of the catch handler or the upcall. 101 size_t handler_frame_depth_; 102 103 DISALLOW_COPY_AND_ASSIGN(QuickExceptionHandler); 104 }; 105 106 } // namespace art 107 #endif // ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_ 108