Locking and exception handling fixes for debugger/interpreter.

Change-Id: I20223113355a2d7b5deb4658035be2f788765fc1
diff --git a/src/debugger.h b/src/debugger.h
index d7d2800..c75f643 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -42,7 +42,7 @@
         receiver_(NULL), thread_(NULL), class_(NULL), method_(NULL),
         arg_count_(0), arg_values_(NULL), options_(0), error(JDWP::ERR_NONE),
         result_tag(JDWP::JT_VOID), exception(0),
-        lock_("a DebugInvokeReq lock"),
+        lock_("a DebugInvokeReq lock", kBreakpointInvokeLock),
         cond_("a DebugInvokeReq condition variable", lock_) {
   }
 
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index f89d648..e425ee8 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -39,6 +39,10 @@
 static const int64_t kMaxLong = std::numeric_limits<int64_t>::max();
 static const int64_t kMinLong = std::numeric_limits<int64_t>::min();
 
+static JDWP::FrameId throw_frame_id_ = 0;
+static AbstractMethod* throw_method_ = NULL;
+static uint32_t throw_dex_pc_ = 0;
+
 static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
                                    Object* receiver, JValue* args, JValue* result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1753,6 +1757,11 @@
         break;
     }
     if (UNLIKELY(self->IsExceptionPending())) {
+      if (throw_frame_id_ == 0) {
+        throw_method_ = shadow_frame.GetMethod();
+        throw_dex_pc_ = dex_pc;
+      }
+      throw_frame_id_++;
       uint32_t found_dex_pc =
           shadow_frame.GetMethod()->FindCatchBlock(self->GetException()->GetClass(),
                                                    inst->GetDexPc(insns));
@@ -1761,6 +1770,9 @@
         result.SetJ(0);
         return result;  // Handler in caller.
       } else {
+        Dbg::PostException(self, throw_frame_id_, throw_method_, throw_dex_pc_,
+                           shadow_frame.GetMethod(), found_dex_pc, self->GetException());
+        throw_frame_id_ = 0;
         next_inst = Instruction::At(insns + found_dex_pc);
       }
     }
diff --git a/src/locks.h b/src/locks.h
index aacd6c6..5ad42f7 100644
--- a/src/locks.h
+++ b/src/locks.h
@@ -42,15 +42,16 @@
   kClassLinkerClassesLock = 7,
   kBreakpointLock = 8,
   kThreadListLock = 9,
-  kJdwpEventListLock = 10,
-  kJdwpAttachLock = 11,
-  kJdwpStartLock = 12,
-  kJdwpSerialLock = 13,
-  kRuntimeShutdownLock = 14,
-  kHeapBitmapLock = 15,
-  kMonitorLock = 16,
-  kMutatorLock = 17,
-  kZygoteCreationLock = 18,
+  kBreakpointInvokeLock = 10,
+  kJdwpEventListLock = 11,
+  kJdwpAttachLock = 12,
+  kJdwpStartLock = 13,
+  kJdwpSerialLock = 14,
+  kRuntimeShutdownLock = 15,
+  kHeapBitmapLock = 16,
+  kMonitorLock = 17,
+  kMutatorLock = 18,
+  kZygoteCreationLock = 19,
   kMaxMutexLevel = kZygoteCreationLock,
 };
 std::ostream& operator<<(std::ostream& os, const LockLevel& rhs);