Refactor exception handling for deoptimization

This CL refactors the exception handling (on the quick side) by isolating the
search of catch handler and the preparation of deoptimization.

We rename the CatchFinder class to QuickExceptionHandler so it's less specific
to catch handler search.

Finding catch handler happens in QuickExceptionHandler::FindCatch. Since the
CatchBlockStackVisitor resolves exception types, it may cause thread suspension
and breaks the assertion current thread can't be suspended. Therefore, we place
the exception in a SirtRef (while it is detached from the current thread) and
remove the thread suspension assertion.

Deoptimization now happens in QuickExceptionHandler::DeoptimizeStack. It uses
the new DeoptimizeStackVisitor class to create shadow frames.

We also add the Thread::GetDeoptimizationException method to get the definition
of the fake exception in only one place.

Change-Id: I01b19fa72af64329b5c3b6c7f0c3339d2d724978
diff --git a/runtime/catch_block_stack_visitor.h b/runtime/catch_block_stack_visitor.h
index ce67e27..6f0fe11 100644
--- a/runtime/catch_block_stack_visitor.h
+++ b/runtime/catch_block_stack_visitor.h
@@ -17,39 +17,39 @@
 #ifndef ART_RUNTIME_CATCH_BLOCK_STACK_VISITOR_H_
 #define ART_RUNTIME_CATCH_BLOCK_STACK_VISITOR_H_
 
-#include "mirror/throwable.h"
-#include "thread.h"
+#include "mirror/object-inl.h"
+#include "stack.h"
+#include "sirt_ref-inl.h"
 
 namespace art {
-class CatchFinder;
+
+namespace mirror {
+class Throwable;
+}  // namespace mirror
+class Context;
+class QuickExceptionHandler;
+class Thread;
 class ThrowLocation;
 
 // Finds catch handler or prepares deoptimization.
-class CatchBlockStackVisitor : public StackVisitor {
+class CatchBlockStackVisitor FINAL : public StackVisitor {
  public:
-  CatchBlockStackVisitor(Thread* self, Context* context, mirror::Throwable* exception,
-                         bool is_deoptimization, CatchFinder* catch_finder)
+  CatchBlockStackVisitor(Thread* self, Context* context, SirtRef<mirror::Throwable>& exception,
+                         QuickExceptionHandler* exception_handler)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : StackVisitor(self, context),
-        self_(self), is_deoptimization_(is_deoptimization),
-        to_find_(is_deoptimization ? nullptr : exception->GetClass()),
-        catch_finder_(catch_finder), native_method_count_(0), prev_shadow_frame_(nullptr) {
+      : StackVisitor(self, context), self_(self), to_find_(self, exception->GetClass()),
+        exception_handler_(exception_handler) {
   }
 
-  bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
  private:
   bool HandleTryItems(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  bool HandleDeoptimization(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   Thread* const self_;
-  const bool is_deoptimization_;
   // The type of the exception catch block to find.
-  mirror::Class* to_find_;
-  CatchFinder* const catch_finder_;
-  // Number of native methods passed in crawl (equates to number of SIRTs to pop)
-  uint32_t native_method_count_;
-  ShadowFrame* prev_shadow_frame_;
+  SirtRef<mirror::Class> to_find_;
+  QuickExceptionHandler* const exception_handler_;
 
   DISALLOW_COPY_AND_ASSIGN(CatchBlockStackVisitor);
 };