Implement try/catch/throw in optimizing.

- We currently don't run optimizations in the presence of a try/catch.
- We therefore implement Quick's mapping table.
- Also fix a missing null check on array-length.

Change-Id: I6917dfcb868e75c1cf6eff32b7cbb60b6cfbd68f
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index a57bbdb..37e5e6b 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -292,7 +292,8 @@
         block_id_(-1),
         dex_pc_(dex_pc),
         lifetime_start_(kNoLifetime),
-        lifetime_end_(kNoLifetime) {}
+        lifetime_end_(kNoLifetime),
+        is_catch_block_(false) {}
 
   const GrowableArray<HBasicBlock*>& GetPredecessors() const {
     return predecessors_;
@@ -450,6 +451,9 @@
 
   uint32_t GetDexPc() const { return dex_pc_; }
 
+  bool IsCatchBlock() const { return is_catch_block_; }
+  void SetIsCatchBlock() { is_catch_block_ = true; }
+
  private:
   HGraph* const graph_;
   GrowableArray<HBasicBlock*> predecessors_;
@@ -464,6 +468,7 @@
   const uint32_t dex_pc_;
   size_t lifetime_start_;
   size_t lifetime_end_;
+  bool is_catch_block_;
 
   DISALLOW_COPY_AND_ASSIGN(HBasicBlock);
 };
@@ -495,6 +500,7 @@
   M(LessThan, Condition)                                                \
   M(LessThanOrEqual, Condition)                                         \
   M(LoadClass, Instruction)                                             \
+  M(LoadException, Instruction)                                         \
   M(LoadLocal, Instruction)                                             \
   M(LoadString, Instruction)                                            \
   M(Local, Instruction)                                                 \
@@ -517,6 +523,7 @@
   M(Sub, BinaryOperation)                                               \
   M(SuspendCheck, Instruction)                                          \
   M(Temporary, Instruction)                                             \
+  M(Throw, Instruction)                                                 \
   M(TypeConversion, Instruction)                                        \
 
 #define FOR_EACH_INSTRUCTION(M)                                         \
@@ -1052,7 +1059,7 @@
 };
 
 // The exit instruction is the only instruction of the exit block.
-// Instructions aborting the method (HTrow and HReturn) must branch to the
+// Instructions aborting the method (HThrow and HReturn) must branch to the
 // exit block.
 class HExit : public HTemplateInstruction<0> {
  public:
@@ -1071,7 +1078,7 @@
  public:
   HGoto() : HTemplateInstruction(SideEffects::None()) {}
 
-  virtual bool IsControlFlow() const { return true; }
+  bool IsControlFlow() const OVERRIDE { return true; }
 
   HBasicBlock* GetSuccessor() const {
     return GetBlock()->GetSuccessors().Get(0);
@@ -1092,7 +1099,7 @@
     SetRawInputAt(0, input);
   }
 
-  virtual bool IsControlFlow() const { return true; }
+  bool IsControlFlow() const OVERRIDE { return true; }
 
   HBasicBlock* IfTrueSuccessor() const {
     return GetBlock()->GetSuccessors().Get(0);
@@ -2284,6 +2291,38 @@
   DISALLOW_COPY_AND_ASSIGN(HStaticFieldSet);
 };
 
+// Implement the move-exception DEX instruction.
+class HLoadException : public HExpression<0> {
+ public:
+  HLoadException() : HExpression(Primitive::kPrimNot, SideEffects::None()) {}
+
+  DECLARE_INSTRUCTION(LoadException);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HLoadException);
+};
+
+class HThrow : public HTemplateInstruction<1> {
+ public:
+  HThrow(HInstruction* exception, uint32_t dex_pc)
+      : HTemplateInstruction(SideEffects::None()), dex_pc_(dex_pc) {
+    SetRawInputAt(0, exception);
+  }
+
+  bool IsControlFlow() const OVERRIDE { return true; }
+
+  bool NeedsEnvironment() const OVERRIDE { return true; }
+
+  uint32_t GetDexPc() const { return dex_pc_; }
+
+  DECLARE_INSTRUCTION(Throw);
+
+ private:
+  uint32_t dex_pc_;
+
+  DISALLOW_COPY_AND_ASSIGN(HThrow);
+};
+
 class MoveOperands : public ArenaObject<kArenaAllocMisc> {
  public:
   MoveOperands(Location source, Location destination, HInstruction* instruction)