Add Method::dex_cache_*_ short cuts to declaring_class_->dex_cache_

Change-Id: I6e14b296abdd74b7fe810fc43d814931fd8cb770
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 2e4aa9e..6379113 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -683,6 +683,11 @@
   dst->shorty_ = dex_file.GetShorty(method_id.proto_idx_);
   dst->access_flags_ = src.access_flags_;
 
+  dst->dex_cache_strings_ = klass->dex_cache_->GetStrings();
+  dst->dex_cache_classes_ = klass->dex_cache_->GetClasses();
+  dst->dex_cache_methods_ = klass->dex_cache_->GetMethods();
+  dst->dex_cache_fields_ = klass->dex_cache_->GetFields();
+
   // TODO: check for finalize method
 
   const DexFile::CodeItem* code_item = dex_file.GetCodeItem(src);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 88ddd07..ca305f1 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -2,6 +2,7 @@
 
 #include "common_test.h"
 #include "class_linker.h"
+#include "dex_cache.h"
 #include "dex_file.h"
 #include "heap.h"
 
@@ -79,6 +80,28 @@
     EXPECT_EQ(2U, array->NumInterfaces());
   }
 
+  void AssertDexFileMethod(Class* klass, Method* method) {
+    EXPECT_TRUE(method != NULL);
+    EXPECT_TRUE(method->GetName() != NULL);
+    EXPECT_TRUE(method->GetSignature() != NULL);
+
+    EXPECT_TRUE(method->dex_cache_strings_ != NULL);
+    EXPECT_TRUE(method->dex_cache_classes_ != NULL);
+    EXPECT_TRUE(method->dex_cache_methods_ != NULL);
+    EXPECT_TRUE(method->dex_cache_fields_ != NULL);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(), method->dex_cache_strings_);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetClasses(), method->dex_cache_classes_);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetMethods(), method->dex_cache_methods_);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
+  }
+
+  void AssertDexFileField(Class* klass, Field* field) {
+    EXPECT_TRUE(field != NULL);
+    EXPECT_EQ(klass, field->GetDeclaringClass());
+    EXPECT_TRUE(field->GetName() != NULL);
+    EXPECT_TRUE(field->GetDescriptor() != NULL);
+  }
+
   void AssertDexFileClass(ClassLoader* class_loader, const char* descriptor) {
     ASSERT_TRUE(descriptor != NULL);
     Class* klass = class_linker_->FindSystemClass(descriptor);
@@ -132,35 +155,26 @@
 
     for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
       Method* method = klass->GetDirectMethod(i);
-      EXPECT_TRUE(method != NULL);
+      AssertDexFileMethod(klass, method);
       EXPECT_EQ(klass, method->GetDeclaringClass());
-      EXPECT_TRUE(method->GetName() != NULL);
-      EXPECT_TRUE(method->GetSignature() != NULL);
     }
 
     for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
       Method* method = klass->GetVirtualMethod(i);
-      EXPECT_TRUE(method != NULL);
-      EXPECT_TRUE(method->GetName() != NULL);
-      EXPECT_TRUE(method->GetSignature() != NULL);
+      AssertDexFileMethod(klass, method);
+      EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass));
     }
 
     for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
       Field* field = klass->GetInstanceField(i);
-      EXPECT_TRUE(field != NULL);
+      AssertDexFileField(klass, field);
       EXPECT_FALSE(field->IsStatic());
-      EXPECT_EQ(klass, field->GetDeclaringClass());
-      EXPECT_TRUE(field->GetName() != NULL);
-      EXPECT_TRUE(field->GetDescriptor() != NULL);
     }
 
     for (size_t i = 0; i < klass->NumStaticFields(); i++) {
       Field* field = klass->GetStaticField(i);
-      EXPECT_TRUE(field != NULL);
+      AssertDexFileField(klass, field);
       EXPECT_TRUE(field->IsStatic());
-      EXPECT_EQ(klass, field->GetDeclaringClass());
-      EXPECT_TRUE(field->GetName() != NULL);
-      EXPECT_TRUE(field->GetDescriptor() != NULL);
    }
 
     // Confirm that all instances fields are packed together at the start
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 534a29b..f34dbe4 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -18,7 +18,7 @@
 class DexCache : public ObjectArray<Object> {
  public:
 
-  enum ArrayIndexes {
+  enum ArrayIndex {
     kLocation = 0,
     kStrings  = 1,
     kClasses  = 2,
@@ -85,20 +85,26 @@
     GetFields()->Set(field_idx, resolved);
   }
 
- private:
   ObjectArray<String>* GetStrings() const {
-    return static_cast<ObjectArray<String>*>(Get(kStrings));
+    return static_cast<ObjectArray<String>*>(GetNonNull(kStrings));
   }
   ObjectArray<Class>* GetClasses() const {
-    return static_cast<ObjectArray<Class>*>(Get(kClasses));
+    return static_cast<ObjectArray<Class>*>(GetNonNull(kClasses));
   }
   ObjectArray<Method>* GetMethods() const {
-    return static_cast<ObjectArray<Method>*>(Get(kMethods));
+    return static_cast<ObjectArray<Method>*>(GetNonNull(kMethods));
   }
   ObjectArray<Field>* GetFields() const {
-    return static_cast<ObjectArray<Field>*>(Get(kFields));
+    return static_cast<ObjectArray<Field>*>(GetNonNull(kFields));
   }
-  DexCache();
+
+ private:
+  Object* GetNonNull(ArrayIndex array_index) const {
+    Object* obj = Get(array_index);
+    DCHECK(obj != NULL);
+    return obj;
+  }
+  DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
 };
 
 }  // namespace art
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
index 674ec0f..71125cc 100644
--- a/src/dex_cache_test.cc
+++ b/src/dex_cache_test.cc
@@ -18,10 +18,25 @@
 
   DexCache* dex_cache = class_linker_->AllocDexCache(java_lang_dex_file_.get());
   ASSERT_TRUE(dex_cache != NULL);
+
   EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings());
   EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),   dex_cache->NumClasses());
   EXPECT_EQ(java_lang_dex_file_->NumMethodIds(), dex_cache->NumMethods());
   EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),  dex_cache->NumFields());
+
+  EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
+  EXPECT_LE(0, dex_cache->GetClasses()->GetLength());
+  EXPECT_LE(0, dex_cache->GetMethods()->GetLength());
+  EXPECT_LE(0, dex_cache->GetFields()->GetLength());
+
+  EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
+            static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
+  EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),
+            static_cast<uint32_t>(dex_cache->GetClasses()->GetLength()));
+  EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
+            static_cast<uint32_t>(dex_cache->GetMethods()->GetLength()));
+  EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
+            static_cast<uint32_t>(dex_cache->GetFields()->GetLength()));
 }
 
 }  // namespace art
diff --git a/src/object.h b/src/object.h
index e246dea..0bbb4f4 100644
--- a/src/object.h
+++ b/src/object.h
@@ -610,6 +610,12 @@
   // The short-form method descriptor string.
   StringPiece shorty_;
 
+  // short cuts to declaring_class_->dex_cache_ members for fast compiled code access
+  ObjectArray<String>* dex_cache_strings_;
+  ObjectArray<Class>* dex_cache_classes_;
+  ObjectArray<Method>* dex_cache_methods_;
+  ObjectArray<Field>* dex_cache_fields_;
+
  private:
   // Compiled code associated with this method
   const void* code_;