ART: Fix wrong CHECK in GetCurrentLocationForThrow

Under certain circumstances kDexNoIndex is actually an encoded
dex pc. Change the setup of CurrentMethodVisitor to account for that.

Bug: 16556938

(cherry picked from commit f9df5c1639a9418fcdf70476556a4c30b210701e)

Change-Id: Icb1d42ccd22296e2e0c629ebbd7e4d8c7d87f07a
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index c46efd8..d89290b 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -79,7 +79,6 @@
   // Emit the source code file name, <= 37 bytes.
   uint32_t pc;
   mirror::ArtMethod* m = self->GetCurrentMethod(&pc);
-  CHECK_NE(pc, DexFile::kDexNoIndex);  // TODO: Can we relax this check?
   const char* filename;
   uint32_t line_number;
   TranslateLocation(m, pc, &filename, &line_number);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index bbc5d99..e5f7aa4 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1972,9 +1972,10 @@
 // Note: this visitor may return with a method set, but dex_pc_ being DexFile:kDexNoIndex. This is
 //       so we don't abort in a special situation (thinlocked monitor) when dumping the Java stack.
 struct CurrentMethodVisitor FINAL : public StackVisitor {
-  CurrentMethodVisitor(Thread* thread, Context* context)
+  CurrentMethodVisitor(Thread* thread, Context* context, bool fail_on_error)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : StackVisitor(thread, context), this_object_(nullptr), method_(nullptr), dex_pc_(0) {}
+      : StackVisitor(thread, context), this_object_(nullptr), method_(nullptr), dex_pc_(0),
+        fail_on_error_(fail_on_error) {}
   bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     mirror::ArtMethod* m = GetMethod();
     if (m->IsRuntimeMethod()) {
@@ -1985,16 +1986,17 @@
       this_object_ = GetThisObject();
     }
     method_ = m;
-    dex_pc_ = GetDexPc(false);  // We may not have a valid PC. Let the caller deal with it.
+    dex_pc_ = GetDexPc(fail_on_error_);
     return false;
   }
   mirror::Object* this_object_;
   mirror::ArtMethod* method_;
   uint32_t dex_pc_;
+  const bool fail_on_error_;
 };
 
 mirror::ArtMethod* Thread::GetCurrentMethod(uint32_t* dex_pc) const {
-  CurrentMethodVisitor visitor(const_cast<Thread*>(this), nullptr);
+  CurrentMethodVisitor visitor(const_cast<Thread*>(this), nullptr, false);
   visitor.WalkStack(false);
   if (dex_pc != nullptr) {
     *dex_pc = visitor.dex_pc_;
@@ -2004,9 +2006,8 @@
 
 ThrowLocation Thread::GetCurrentLocationForThrow() {
   Context* context = GetLongJumpContext();
-  CurrentMethodVisitor visitor(this, context);
+  CurrentMethodVisitor visitor(this, context, true);
   visitor.WalkStack(false);
-  CHECK_NE(visitor.dex_pc_, DexFile::kDexNoIndex);  // TODO: Can we relax this?
   ReleaseLongJumpContext(context);
   return ThrowLocation(visitor.this_object_, visitor.method_, visitor.dex_pc_);
 }