Remove disable card marks, fix SetPatchLocation.

Should slightly improve performance. Added a no thread suspension allowed in patch oat code and
methods.

Added a new function to class linker, GetOatCodeFor which takes in a method reference instead of
pointer.

This fixes the issue where pruned methods were getting re-loaded during code and method patching.

Change-Id: I676bb88cb021b6d2e0db00adbcf1f2f04f82b72a
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 75f0f38..abb6dcf 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1461,6 +1461,42 @@
   return oat_class;
 }
 
+static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint32_t method_idx) {
+  const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
+  const DexFile::TypeId& type_id = dex_file.GetTypeId(method_id.class_idx_);
+  const DexFile::ClassDef* class_def = dex_file.FindClassDef(dex_file.GetTypeDescriptor(type_id));
+  CHECK(class_def != NULL);
+  const byte* class_data = dex_file.GetClassData(*class_def);
+  CHECK(class_data != NULL);
+  ClassDataItemIterator it(dex_file, class_data);
+  // Skip fields
+  while (it.HasNextStaticField()) {
+    it.Next();
+  }
+  while (it.HasNextInstanceField()) {
+    it.Next();
+  }
+  // Process methods
+  size_t class_def_method_index = 0;
+  while (it.HasNextDirectMethod()) {
+    if (it.GetMemberIndex() == method_idx) {
+      return class_def_method_index;
+    }
+    class_def_method_index++;
+    it.Next();
+  }
+  while (it.HasNextVirtualMethod()) {
+    if (it.GetMemberIndex() == method_idx) {
+      return class_def_method_index;
+    }
+    class_def_method_index++;
+    it.Next();
+  }
+  DCHECK(!it.HasNext());
+  LOG(FATAL) << "Failed to find method index " << method_idx << " in " << dex_file.GetLocation();
+  return 0;
+}
+
 const OatFile::OatMethod ClassLinker::GetOatMethodFor(const AbstractMethod* method) {
   // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
   // method for direct methods (or virtual methods made direct).
@@ -1487,6 +1523,10 @@
   ClassHelper kh(declaring_class);
   UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(kh.GetDexFile(), kh.GetDescriptor()));
   CHECK(oat_class.get() != NULL);
+  DCHECK_EQ(oat_method_index,
+            GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
+                                             method->GetDexMethodIndex()));
+
   return oat_class->GetOatMethod(oat_method_index);
 }
 
@@ -1496,6 +1536,15 @@
   return GetOatMethodFor(method).GetCode();
 }
 
+const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx) {
+  const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
+  const char* descriptor = dex_file.GetTypeDescriptor(dex_file.GetTypeId(method_id.class_idx_));
+  uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, method_idx);
+  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, descriptor));
+  CHECK(oat_class.get() != NULL);
+  return oat_class->GetOatMethod(oat_method_idx).GetCode();
+}
+
 void ClassLinker::FixupStaticTrampolines(Class* klass) {
   ClassHelper kh(klass);
   const DexFile::ClassDef* dex_class_def = kh.GetClassDef();