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