Using gcmap instead of shadow frame.

Fix misuse of TBAAJRuntime & TBAARuntimeInfo. Now, the TBAAJRuntime is
only for runtime support function.

Update DexPC before lock object and suspend.

Change-Id: I40fa37f4863fe6e127328a8413285ee3c62e8505
diff --git a/src/thread.cc b/src/thread.cc
index 75d0468..7490d2a 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -52,6 +52,7 @@
 #include "stack_indirect_reference_table.h"
 #include "thread_list.h"
 #include "utils.h"
+#include "verifier/dex_gc_map.h"
 #include "well_known_classes.h"
 
 namespace art {
@@ -1853,8 +1854,39 @@
     }
     ShadowFrame* shadow_frame = GetCurrentShadowFrame();
     if (shadow_frame != NULL) {
-      WrapperVisitor wrapperVisitor(visitor_, this);
-      shadow_frame->VisitRoots(wrapperVisitor);
+      AbstractMethod* m = shadow_frame->GetMethod();
+      size_t num_regs = shadow_frame->NumberOfVRegs();
+      if (m->IsNative() || shadow_frame->HasReferenceArray()) {
+        // SIRT for JNI or References for interpreter.
+        for (size_t reg = 0; reg < num_regs; ++reg) {
+          Object* ref = shadow_frame->GetVRegReference(reg);
+          if (ref != NULL) {
+            visitor_(ref, reg, this);
+          }
+        }
+      } else {
+        // Java method.
+        // Portable path use DexGcMap and store in Method.native_gc_map_.
+        const uint8_t* gc_map = m->GetNativeGcMap();
+        CHECK(gc_map != NULL) << PrettyMethod(m);
+        uint32_t gc_map_length = static_cast<uint32_t>((gc_map[0] << 24) |
+                                                       (gc_map[1] << 16) |
+                                                       (gc_map[2] << 8) |
+                                                       (gc_map[3] << 0));
+        verifier::DexPcToReferenceMap dex_gc_map(gc_map + 4, gc_map_length);
+        uint32_t dex_pc = GetDexPc();
+        const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc);
+        DCHECK(reg_bitmap != NULL);
+        num_regs = std::min(dex_gc_map.RegWidth() * 8, num_regs);
+        for (size_t reg = 0; reg < num_regs; ++reg) {
+          if (TestBitmap(reg, reg_bitmap)) {
+            Object* ref = shadow_frame->GetVRegReference(reg);
+            if (ref != NULL) {
+              visitor_(ref, reg, this);
+            }
+          }
+        }
+      }
     } else {
       AbstractMethod* m = GetMethod();
       // Process register map (which native and runtime methods don't have)
@@ -1903,21 +1935,6 @@
   }
 
  private:
-
-  class WrapperVisitor {
-   public:
-    WrapperVisitor(const RootVisitor& root_visitor, const StackVisitor* stack_visitor)
-      : root_visitor_(root_visitor), stack_visitor_(stack_visitor) {}
-
-    void operator()(const Object* obj, size_t offset) const {
-      root_visitor_(obj, offset, stack_visitor_);
-    }
-
-   private:
-    const RootVisitor& root_visitor_;
-    const StackVisitor* const stack_visitor_;
-  };
-
   static bool TestBitmap(int reg, const uint8_t* reg_vector) {
     return ((reg_vector[reg / 8] >> (reg % 8)) & 0x01) != 0;
   }