Clarify CodeAndMethods to CodeAndDirectMethods

Change-Id: Ifa564ea25f4c7eb168f367274679a4915b9f4715
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 4738926..41a1c55 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -434,12 +434,12 @@
                   AllocObjectArray<Class>(dex_file.NumTypeIds()),
                   AllocObjectArray<Method>(dex_file.NumMethodIds()),
                   AllocObjectArray<Field>(dex_file.NumFieldIds()),
-                  AllocCodeAndMethods(dex_file.NumMethodIds()));
+                  AllocCodeAndDirectMethods(dex_file.NumMethodIds()));
   return dex_cache;
 }
 
-CodeAndMethods* ClassLinker::AllocCodeAndMethods(size_t length) {
-  return down_cast<CodeAndMethods*>(IntArray::Alloc(CodeAndMethods::LengthAsArray(length)));
+CodeAndDirectMethods* ClassLinker::AllocCodeAndDirectMethods(size_t length) {
+  return down_cast<CodeAndDirectMethods*>(IntArray::Alloc(CodeAndDirectMethods::LengthAsArray(length)));
 }
 
 Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
@@ -698,7 +698,7 @@
       dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
       Method* meth = AllocMethod();
       klass->SetDirectMethod(i, meth);
-      LoadMethod(dex_file, dex_method, klass, meth);
+      LoadMethod(dex_file, dex_method, klass, meth, true);
       // TODO: register maps
     }
   }
@@ -714,7 +714,7 @@
       dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
       Method* meth = AllocMethod();
       klass->SetVirtualMethod(i, meth);
-      LoadMethod(dex_file, dex_method, klass, meth);
+      LoadMethod(dex_file, dex_method, klass, meth, false);
       // TODO: register maps
     }
   }
@@ -751,7 +751,8 @@
 void ClassLinker::LoadMethod(const DexFile& dex_file,
                              const DexFile::Method& src,
                              Class* klass,
-                             Method* dst) {
+                             Method* dst,
+                             bool is_direct) {
   const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
   dst->declaring_class_ = klass;
   dst->name_ = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache());
@@ -769,7 +770,9 @@
   dst->dex_cache_types_ = klass->dex_cache_->GetTypes();
   dst->dex_cache_methods_ = klass->dex_cache_->GetMethods();
   dst->dex_cache_fields_ = klass->dex_cache_->GetFields();
-  dst->dex_cache_code_and_methods_ = klass->dex_cache_->GetCodeAndMethods();
+  dst->dex_cache_code_and_direct_methods_ = klass->dex_cache_->GetCodeAndDirectMethods();
+
+  dst->is_direct_ = is_direct;
 
   // TODO: check for finalize method
 
diff --git a/src/class_linker.h b/src/class_linker.h
index 306613f..5e3ac78 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -146,7 +146,7 @@
   ObjectArray<T>* AllocObjectArray(size_t length) {
     return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
   }
-  CodeAndMethods* AllocCodeAndMethods(size_t length);
+  CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
 
   Class* CreatePrimitiveClass(const char* descriptor);
 
@@ -176,7 +176,8 @@
   void LoadMethod(const DexFile& dex_file,
                   const DexFile::Method& dex_method,
                   Class* klass,
-                  Method* dst);
+                  Method* dst,
+                  bool is_direct);
 
   Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader);
 
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 71bf523..9fd5fb5 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -105,13 +105,13 @@
     EXPECT_TRUE(method->dex_cache_types_ != NULL);
     EXPECT_TRUE(method->dex_cache_methods_ != NULL);
     EXPECT_TRUE(method->dex_cache_fields_ != NULL);
-    EXPECT_TRUE(method->dex_cache_code_and_methods_ != NULL);
+    EXPECT_TRUE(method->dex_cache_code_and_direct_methods_ != NULL);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(), method->dex_cache_strings_);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetTypes(), method->dex_cache_types_);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetMethods(), method->dex_cache_methods_);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndMethods(),
-              method->dex_cache_code_and_methods_);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndDirectMethods(),
+              method->dex_cache_code_and_direct_methods_);
   }
 
   void AssertField(Class* klass, Field* field) {
@@ -143,6 +143,7 @@
       EXPECT_TRUE(klass->IsAbstract());
       if (klass->NumDirectMethods() == 1) {
         EXPECT_TRUE(klass->GetDirectMethod(0)->GetName()->Equals("<clinit>"));
+        EXPECT_TRUE(klass->GetDirectMethod(0)->IsDirect());
       } else {
         EXPECT_EQ(0U, klass->NumDirectMethods());
       }
@@ -171,12 +172,14 @@
     for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
       Method* method = klass->GetDirectMethod(i);
       AssertMethod(klass, method);
+      EXPECT_TRUE(method->IsDirect());
       EXPECT_EQ(klass, method->GetDeclaringClass());
     }
 
     for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
       Method* method = klass->GetVirtualMethod(i);
       AssertMethod(klass, method);
+      EXPECT_FALSE(method->IsDirect());
       EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass));
     }
 
diff --git a/src/compiler.cc b/src/compiler.cc
index d1605a7..c8ff794 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -17,7 +17,7 @@
   Resolve(class_loader);
   // TODO add verification step
   Compile(class_loader);
-  SetCodeAndMethod(class_loader);
+  SetCodeAndDirectMethods(class_loader);
   return class_loader;
 }
 
@@ -104,23 +104,28 @@
   // CHECK(method->HasCode());  // TODO: enable this check ASAP
 }
 
-void Compiler::SetCodeAndMethod(const ClassLoader* class_loader) {
+void Compiler::SetCodeAndDirectMethods(const ClassLoader* class_loader) {
   const std::vector<const DexFile*>& class_path = class_loader->GetClassPath();
   for (size_t i = 0; i != class_path.size(); ++i) {
     const DexFile* dex_file = class_path[i];
     CHECK(dex_file != NULL);
-    SetCodeAndMethodDexFile(class_loader, *dex_file);
+    SetCodeAndDirectMethodsDexFile(class_loader, *dex_file);
   }
 }
 
-void Compiler::SetCodeAndMethodDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
+void Compiler::SetCodeAndDirectMethodsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   DexCache* dex_cache = class_linker->FindDexCache(dex_file);
-  CodeAndMethods* code_and_methods = dex_cache->GetCodeAndMethods();
+  CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
   for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
     Method* method = dex_cache->GetResolvedMethod(i);
-    if (method != NULL) {
-      code_and_methods->SetResolvedMethod(i, method);
+    if (method == NULL) {
+      code_and_direct_methods->SetResolvedDirectMethodTrampoline(i);
+    } else if (method->IsDirect()) {
+      code_and_direct_methods->SetResolvedDirectMethod(i, method);
+    } else {
+      // TODO: we currently leave the entry blank for resolved
+      // non-direct methods.  we could put in an error stub.
     }
   }
 }
diff --git a/src/compiler.h b/src/compiler.h
index 864f29d..fde7a37 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -28,9 +28,9 @@
   void CompileMethod(Method* klass);
 
   // After compiling, walk all the DexCaches and set the code and
-  // method pointers of CodeAndMethod entries in the DexCaches.
-  void SetCodeAndMethod(const ClassLoader* class_loader);
-  void SetCodeAndMethodDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
+  // method pointers of CodeAndDirectMethods entries in the DexCaches.
+  void SetCodeAndDirectMethods(const ClassLoader* class_loader);
+  void SetCodeAndDirectMethodsDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
 };
 
 }  // namespace art
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 6a2f81e..f6dc5c7 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -99,12 +99,12 @@
 
   // TODO: check that all Method::GetCode() values are non-null
 
-  EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndMethods());
-  CodeAndMethods* code_and_methods = dex_cache->GetCodeAndMethods();
-  for (size_t i = 0; i < dex_cache->NumCodeAndMethods(); i++) {
+  EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
+  CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
+  for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
     Method* method = dex_cache->GetResolvedMethod(i);
-    EXPECT_EQ(method->GetCode(), code_and_methods->GetResolvedCode(i));
-    EXPECT_EQ(method,            code_and_methods->GetResolvedMethod(i));
+    EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
+    EXPECT_EQ(method,            code_and_direct_methods->GetResolvedMethod(i));
   }
 }
 
diff --git a/src/dex_cache.cc b/src/dex_cache.cc
index 88fbd2f..a4538c9 100644
--- a/src/dex_cache.cc
+++ b/src/dex_cache.cc
@@ -14,19 +14,19 @@
                     ObjectArray<Class>* types,
                     ObjectArray<Method>* methods,
                     ObjectArray<Field>* fields,
-                    CodeAndMethods* code_and_methods) {
+                    CodeAndDirectMethods* code_and_direct_methods) {
   CHECK(location != NULL);
   CHECK(strings != NULL);
   CHECK(types != NULL);
   CHECK(methods != NULL);
   CHECK(fields != NULL);
-  CHECK(code_and_methods != NULL);
+  CHECK(code_and_direct_methods != NULL);
   Set(kLocation,       location);
   Set(kStrings,        strings);
   Set(kTypes,          types);
   Set(kMethods,        methods);
   Set(kFields,         fields);
-  Set(kCodeAndMethods, code_and_methods);
+  Set(kCodeAndDirectMethods, code_and_direct_methods);
 }
 
 }  // namespace art
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 2f75c86..1e46a90 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -16,7 +16,7 @@
 class String;
 union JValue;
 
-class CodeAndMethods : public IntArray {
+class CodeAndDirectMethods : public IntArray {
  public:
   Method* GetResolvedCode(uint32_t method_idx) const {
     return reinterpret_cast<Method*>(Get(method_idx * kMax + kCode));
@@ -25,8 +25,15 @@
     return reinterpret_cast<byte*>(Get(method_idx * kMax + kMethod));
   }
 
-  void SetResolvedMethod(uint32_t method_idx, Method* method) {
+  void SetResolvedDirectMethodTrampoline(uint32_t method_idx) {
+    UNIMPLEMENTED(FATAL) << "need to install a trampoline to resolve the method_idx at runtime";
+    Set(method_idx * kMax + kCode,   0xffffffff);
+    Set(method_idx * kMax + kMethod, method_idx);
+  }
+
+  void SetResolvedDirectMethod(uint32_t method_idx, Method* method) {
     CHECK(method != NULL);
+    CHECK(method->IsDirect());
     // CHECK(method->GetCode() != NULL);  // TODO enable when all code is compiling
     Set(method_idx * kMax + kCode,   reinterpret_cast<int32_t>(method->GetCode()));
     Set(method_idx * kMax + kMethod, reinterpret_cast<int32_t>(method));
@@ -52,7 +59,7 @@
             ObjectArray<Class>* types,
             ObjectArray<Method>* methods,
             ObjectArray<Field>* fields,
-            CodeAndMethods* code_and_methods);
+            CodeAndDirectMethods* code_and_direct_methods);
 
   String* GetLocation() const {
     return Get(kLocation)->AsString();
@@ -89,8 +96,8 @@
     return GetFields()->GetLength();
   }
 
-  size_t NumCodeAndMethods() const {
-    return GetCodeAndMethods()->GetLength();
+  size_t NumCodeAndDirectMethods() const {
+    return GetCodeAndDirectMethods()->GetLength();
   }
 
   String* GetResolvedString(uint32_t string_idx) const {
@@ -137,8 +144,8 @@
   ObjectArray<Field>* GetFields() const {
     return static_cast<ObjectArray<Field>*>(GetNonNull(kFields));
   }
-  CodeAndMethods* GetCodeAndMethods() const {
-    return static_cast<CodeAndMethods*>(GetNonNull(kCodeAndMethods));
+  CodeAndDirectMethods* GetCodeAndDirectMethods() const {
+    return static_cast<CodeAndDirectMethods*>(GetNonNull(kCodeAndDirectMethods));
   }
 
  static size_t LengthAsArray() {
@@ -148,13 +155,13 @@
  private:
 
   enum ArrayIndex {
-    kLocation       = 0,
-    kStrings        = 1,
-    kTypes          = 2,
-    kMethods        = 3,
-    kFields         = 4,
-    kCodeAndMethods = 5,
-    kMax            = 6,
+    kLocation             = 0,
+    kStrings              = 1,
+    kTypes                = 2,
+    kMethods              = 3,
+    kFields               = 4,
+    kCodeAndDirectMethods = 5,
+    kMax                  = 6,
   };
 
   Object* GetNonNull(ArrayIndex array_index) const {
diff --git a/src/object.h b/src/object.h
index 2cdfae2..51bf999 100644
--- a/src/object.h
+++ b/src/object.h
@@ -18,7 +18,7 @@
 
 class Array;
 class Class;
-class CodeAndMethods;
+class CodeAndDirectMethods;
 class DexCache;
 class Field;
 class InterfaceEntry;
@@ -542,6 +542,10 @@
     return shorty_[0] == 'V';
   }
 
+  bool IsDirect() const {
+    return is_direct_;
+  }
+
   // "Args" may refer to any of the 3 levels of "Args."
   // To avoid confusion, our code will denote which "Args" clearly:
   //  1. UserArgs: Args that a user see.
@@ -719,7 +723,9 @@
   ObjectArray<Class>* dex_cache_types_;
   ObjectArray<Method>* dex_cache_methods_;
   ObjectArray<Field>* dex_cache_fields_;
-  CodeAndMethods* dex_cache_code_and_methods_;
+  CodeAndDirectMethods* dex_cache_code_and_direct_methods_;
+
+  bool is_direct_;
 
  private:
   // Compiled code associated with this method