Remove kExceptionPending flag from thread and codegen.

Code just checks if exception_ is NULL instead. Compiled code simply
clears the exception_ field for MOVE_EXCEPTION instead of calling a
helper.

Change-Id: Iefaa780f66c327c3d20598bd71d3c14d7a9c8119
diff --git a/src/compiler/codegen/arm/call_arm.cc b/src/compiler/codegen/arm/call_arm.cc
index 9696bca..cb3af5e 100644
--- a/src/compiler/codegen/arm/call_arm.cc
+++ b/src/compiler/codegen/arm/call_arm.cc
@@ -541,6 +541,18 @@
   GenMemBarrier(cu, kStoreLoad);
 }
 
+void ArmCodegen::GenMoveException(CompilationUnit* cu, RegLocation rl_dest)
+{
+  int ex_offset = Thread::ExceptionOffset().Int32Value();
+  RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
+  int reset_reg = AllocTemp(cu);
+  LoadWordDisp(cu, rARM_SELF, ex_offset, rl_result.low_reg);
+  LoadConstant(cu, reset_reg, 0);
+  StoreWordDisp(cu, rARM_SELF, ex_offset, reset_reg);
+  FreeTemp(cu, reset_reg);
+  StoreValue(cu, rl_dest, rl_result);
+}
+
 /*
  * Mark garbage collection card. Skip if the value we're storing is null.
  */
diff --git a/src/compiler/codegen/arm/codegen_arm.h b/src/compiler/codegen/arm/codegen_arm.h
index ca39e5a..8d99049 100644
--- a/src/compiler/codegen/arm/codegen_arm.h
+++ b/src/compiler/codegen/arm/codegen_arm.h
@@ -138,6 +138,7 @@
     virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind);
     virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
     virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+    virtual void GenMoveException(CompilationUnit* cu, RegLocation rl_dest);
     virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
                                                RegLocation rl_result, int lit, int first_bit,
                                                int second_bit);
diff --git a/src/compiler/codegen/codegen.h b/src/compiler/codegen/codegen.h
index 7a85ce8..595a1db 100644
--- a/src/compiler/codegen/codegen.h
+++ b/src/compiler/codegen/codegen.h
@@ -130,7 +130,6 @@
     void GenConstClass(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest);
     void GenConstString(CompilationUnit* cu, uint32_t string_idx, RegLocation rl_dest);
     void GenNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest);
-    void GenMoveException(CompilationUnit* cu, RegLocation rl_dest);
     void GenThrow(CompilationUnit* cu, RegLocation rl_src);
     void GenInstanceof(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest,
                        RegLocation rl_src);
@@ -332,6 +331,7 @@
     virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind) = 0;
     virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src) = 0;
     virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src) = 0;
+    virtual void GenMoveException(CompilationUnit* cu, RegLocation rl_dest) = 0;
     virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
                                                RegLocation rl_result, int lit, int first_bit,
                                                int second_bit) = 0;
diff --git a/src/compiler/codegen/gen_common.cc b/src/compiler/codegen/gen_common.cc
index 57cf2a5..e1054db 100644
--- a/src/compiler/codegen/gen_common.cc
+++ b/src/compiler/codegen/gen_common.cc
@@ -915,20 +915,6 @@
   StoreValue(cu, rl_dest, rl_result);
 }
 
-void Codegen::GenMoveException(CompilationUnit* cu, RegLocation rl_dest)
-{
-  FlushAllRegs(cu);  /* Everything to home location */
-  int func_offset = ENTRYPOINT_OFFSET(pGetAndClearException);
-  if (cu->instruction_set == kX86) {
-    // Runtime helper will load argument for x86.
-    CallRuntimeHelperReg(cu, func_offset, TargetReg(kArg0), false);
-  } else {
-    CallRuntimeHelperReg(cu, func_offset, TargetReg(kSelf), false);
-  }
-  RegLocation rl_result = GetReturn(cu, false);
-  StoreValue(cu, rl_dest, rl_result);
-}
-
 void Codegen::GenThrow(CompilationUnit* cu, RegLocation rl_src)
 {
   FlushAllRegs(cu);
diff --git a/src/compiler/codegen/mips/call_mips.cc b/src/compiler/codegen/mips/call_mips.cc
index f14ebab..76c9fbd 100644
--- a/src/compiler/codegen/mips/call_mips.cc
+++ b/src/compiler/codegen/mips/call_mips.cc
@@ -294,6 +294,18 @@
   MarkSafepointPC(cu, call_inst);
 }
 
+void MipsCodegen::GenMoveException(CompilationUnit* cu, RegLocation rl_dest)
+{
+  int ex_offset = Thread::ExceptionOffset().Int32Value();
+  RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
+  int reset_reg = AllocTemp(cu);
+  LoadWordDisp(cu, rMIPS_SELF, ex_offset, rl_result.low_reg);
+  LoadConstant(cu, reset_reg, 0);
+  StoreWordDisp(cu, rMIPS_SELF, ex_offset, reset_reg);
+  FreeTemp(cu, reset_reg);
+  StoreValue(cu, rl_dest, rl_result);
+}
+
 /*
  * Mark garbage collection card. Skip if the value we're storing is null.
  */
diff --git a/src/compiler/codegen/mips/codegen_mips.h b/src/compiler/codegen/mips/codegen_mips.h
index 4178f2e..fcd5669 100644
--- a/src/compiler/codegen/mips/codegen_mips.h
+++ b/src/compiler/codegen/mips/codegen_mips.h
@@ -138,6 +138,7 @@
     virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind);
     virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
     virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+    virtual void GenMoveException(CompilationUnit* cu, RegLocation rl_dest);
     virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
                                                RegLocation rl_result, int lit, int first_bit,
                                                int second_bit);
diff --git a/src/compiler/codegen/mir_to_lir.cc b/src/compiler/codegen/mir_to_lir.cc
index 1d64661..2bc0f86 100644
--- a/src/compiler/codegen/mir_to_lir.cc
+++ b/src/compiler/codegen/mir_to_lir.cc
@@ -85,6 +85,7 @@
     case Instruction::MOVE_EXCEPTION:
       cg->GenMoveException(cu, rl_dest);
       break;
+
     case Instruction::RETURN_VOID:
       if (((cu->access_flags & kAccConstructor) != 0) &&
           cu->compiler->RequiresConstructorBarrier(Thread::Current(), cu->dex_file,
diff --git a/src/compiler/codegen/x86/call_x86.cc b/src/compiler/codegen/x86/call_x86.cc
index 80de901..727c5e8 100644
--- a/src/compiler/codegen/x86/call_x86.cc
+++ b/src/compiler/codegen/x86/call_x86.cc
@@ -191,6 +191,15 @@
   branch2->target = NewLIR0(cu, kPseudoTargetLabel);
 }
 
+void X86Codegen::GenMoveException(CompilationUnit* cu, RegLocation rl_dest)
+{
+  int ex_offset = Thread::ExceptionOffset().Int32Value();
+  RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
+  NewLIR2(cu, kX86Mov32RT, rl_result.low_reg, ex_offset);
+  NewLIR2(cu, kX86Mov32TI, ex_offset, 0);
+  StoreValue(cu, rl_dest, rl_result);
+}
+
 /*
  * Mark garbage collection card. Skip if the value we're storing is null.
  */
diff --git a/src/compiler/codegen/x86/codegen_x86.h b/src/compiler/codegen/x86/codegen_x86.h
index f467e83..25f4461 100644
--- a/src/compiler/codegen/x86/codegen_x86.h
+++ b/src/compiler/codegen/x86/codegen_x86.h
@@ -139,6 +139,7 @@
     virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind);
     virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
     virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+    virtual void GenMoveException(CompilationUnit* cu, RegLocation rl_dest);
     virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
                                                RegLocation rl_result, int lit, int first_bit,
                                                int second_bit);
diff --git a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
index 146eee4..15218b8 100644
--- a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
+++ b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
@@ -165,9 +165,6 @@
   points->pInitializeTypeFromCode = art_initialize_type_from_code;
   points->pResolveStringFromCode = art_resolve_string_from_code;
 
-  // Exceptions
-  points->pGetAndClearException = GetAndClearException;
-
   // Field
   points->pSet32Instance = art_set32_instance_from_code;
   points->pSet32Static = art_set32_static_from_code;
diff --git a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
index ddff280..db773ba 100644
--- a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
+++ b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
@@ -167,9 +167,6 @@
   points->pInitializeTypeFromCode = art_initialize_type_from_code;
   points->pResolveStringFromCode = art_resolve_string_from_code;
 
-  // Exceptions
-  points->pGetAndClearException = GetAndClearException;
-
   // Field
   points->pSet32Instance = art_set32_instance_from_code;
   points->pSet32Static = art_set32_static_from_code;
diff --git a/src/oat/runtime/oat_support_entrypoints.h b/src/oat/runtime/oat_support_entrypoints.h
index 1c7fa1b..113a56c 100644
--- a/src/oat/runtime/oat_support_entrypoints.h
+++ b/src/oat/runtime/oat_support_entrypoints.h
@@ -54,9 +54,6 @@
   void* (*pInitializeTypeFromCode)(uint32_t, void*);
   void* (*pResolveStringFromCode)(void*, uint32_t);
 
-  // Exceptions
-  void* (*pGetAndClearException)(Thread*);
-
   // Field
   int (*pSet32Instance)(uint32_t, void*, int32_t);  // field_idx, obj, src
   int (*pSet32Static)(uint32_t, int32_t);
diff --git a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
index c4c2798..fce2251 100644
--- a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
+++ b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
@@ -42,9 +42,6 @@
 extern "C" void* art_initialize_type_and_verify_access_from_code(uint32_t, void*);
 extern "C" void* art_resolve_string_from_code(void*, uint32_t);
 
-// Exception entrypoints.
-extern "C" void* art_get_and_clear_exception(Thread*);
-
 // Field entrypoints.
 extern "C" int art_set32_instance_from_code(uint32_t, void*, int32_t);
 extern "C" int art_set32_static_from_code(uint32_t, int32_t);
@@ -147,9 +144,6 @@
   points->pDebugMe = DebugMe;
   points->pUpdateDebuggerFromCode = NULL; // Controlled by SetDebuggerUpdatesEnabled.
 
-  // Exceptions
-  points->pGetAndClearException = art_get_and_clear_exception;
-
   // DexCache
   points->pInitializeStaticStorage = art_initialize_static_storage_from_code;
   points->pInitializeTypeAndVerifyAccessFromCode = art_initialize_type_and_verify_access_from_code;
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index cdb8167..400ae2f 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -390,13 +390,6 @@
     mov %ebx, %eax                // restore original eax
     ret
 
-DEFINE_FUNCTION art_get_and_clear_exception
-    subl LITERAL(8), %esp         // alignment padding
-    pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
-    call SYMBOL(GetAndClearException)  // (Thread*)
-    addl LITERAL(12), %esp        // pop arguments
-    ret
-
 ONE_ARG_DOWNCALL art_lock_object_from_code, artLockObjectFromCode, ret
 ONE_ARG_DOWNCALL art_unlock_object_from_code, artUnlockObjectFromCode, RETURN_IF_EAX_ZERO
 
diff --git a/src/thread.cc b/src/thread.cc
index fbd6a88..d27710b 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1589,7 +1589,6 @@
   ENTRY_POINT_INFO(pInitializeTypeAndVerifyAccessFromCode),
   ENTRY_POINT_INFO(pInitializeTypeFromCode),
   ENTRY_POINT_INFO(pResolveStringFromCode),
-  ENTRY_POINT_INFO(pGetAndClearException),
   ENTRY_POINT_INFO(pSet32Instance),
   ENTRY_POINT_INFO(pSet32Static),
   ENTRY_POINT_INFO(pSet64Instance),
diff --git a/src/thread.h b/src/thread.h
index 352da27..76aea75 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -102,8 +102,7 @@
   kSuspendRequest   = 1,  // If set implies that suspend_count_ > 0 and the Thread should enter the
                           // safepoint handler.
   kCheckpointRequest = 2, // Request that the thread do some checkpoint work and then continue.
-  kExceptionPending = 4,  // If set implies that exception_ != NULL.
-  kEnterInterpreter = 8,  // Instruct managed code it should enter the interpreter.
+  kEnterInterpreter = 4,  // Instruct managed code it should enter the interpreter.
 };
 
 class PACKED(4) Thread {
@@ -301,9 +300,7 @@
   bool IsStillStarting() const;
 
   bool IsExceptionPending() const {
-    bool result = ReadFlag(kExceptionPending);
-    DCHECK_EQ(result, exception_ != NULL);
-    return result;
+    return exception_ != NULL;
   }
 
   Throwable* GetException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -316,14 +313,10 @@
     CHECK(new_exception != NULL);
     // TODO: DCHECK(!IsExceptionPending());
     exception_ = new_exception;
-    AtomicSetFlag(kExceptionPending);
-    DCHECK(IsExceptionPending());
   }
 
   void ClearException() {
     exception_ = NULL;
-    AtomicClearFlag(kExceptionPending);
-    DCHECK(!IsExceptionPending());
   }
 
   void DeliverException(Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {