Make ClassLinker set Class::super_class_ plus test and build improvements

Create placeholder ClassLinker::java_lang_Object_ for use a
super-class of java_lang_Class_ instances.

	src/class_linker.cc
	src/class_linker.h

Expand ClassLinker FindClass test to verify Class::GetSuperClass

	src/class_linker_test.cc

Move DexFile::Load* methods to ClassLinker so they can reference
java_lang_Object_ and java_lang_Class_

	src/class_linker.cc
	src/class_linker.h
	src/dex_file.cc
	src/dex_file.h

Move corresponding Load tests from class_linker_test to dex_file_test

	src/class_linker_test.cc
	src/dex_file_test.cc

Tracking change to object_test to use ClassLinker::Load* methods

	src/object_test.cc

Move base64 to new src/common_test.h for reuse accross tests. Add
missing example source for MyClass dex.

	src/common_test.h
	src/class_linker_test.cc
	src/dex_file_test.cc
	src/object_test.cc

Change Heap::AllocClass to take DexFile argument

	src/heap.h

Remove Method::dex_file_ in favor of using Method::GetClass::GetDexFile

	src/object.cc
	src/object.h

Made a few more RawDexFile methods const

	src/raw_dex_file.cc
	src/raw_dex_file.h

Add convenience targets for build-art and test-art-host

	Android.mk

Drop use of _LOCAL_ from make variants, which isn't the appropriate
here, where we aren't differentiating between LOCAL_ and PRIVATE_.
Avoid redefinition of variables based on now removed
LIBART_TARGET_ARCH and TEST_TARGET_ARCH to support phony targets in
Android.mk

	build/Android.aexec.host.mk
	build/Android.aexec.mk
	build/Android.common.mk
	build/Android.libart.host.mk
	build/Android.libart.mk
	build/Android.test.host.mk
	build/Android.test.mk

Change-Id: I84ce2b7a2b4e37799d4d782b97c02d5e97ac081c
diff --git a/src/class_linker.cc b/src/class_linker.cc
index cf72a11..5b50113 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -20,10 +20,11 @@
 namespace art {
 
 void ClassLinker::Init() {
-  // Allocate and partially initialize the class Class.  This object
-  // will complete its initialization when its definition is loaded.
-  java_lang_Class_ = Heap::AllocClass();
-  java_lang_Class_->super_class_ = java_lang_Class_;
+  // Allocate and partially initialize the Object and Class classes.
+  // Initialization will be completed when the definitions are loaded.
+  java_lang_Object_ = Heap::AllocClass(NULL);
+  java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
+  java_lang_Class_ = Heap::AllocClass(NULL);
   java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
 
   // Allocate and initialize the primitive type classes.
@@ -56,12 +57,16 @@
       }
     }
     // Load the class from the dex file.
-    if (!strcmp(descriptor, "Ljava/lang/Class;")) {
+    if (!strcmp(descriptor, "Ljava/lang/Object;")) {
+      klass = java_lang_Object_;
+      klass->dex_file_ = dex_file;
+    } else if (!strcmp(descriptor, "Ljava/lang/Class;")) {
       klass = java_lang_Class_;
+      klass->dex_file_ = dex_file;
     } else {
-      klass = Heap::AllocClass();
+      klass = Heap::AllocClass(dex_file);
     }
-    bool is_loaded = dex_file->LoadClass(descriptor, klass);
+    bool is_loaded = LoadClass(descriptor, klass);
     if (!is_loaded) {
       // TODO: this occurs only when a dex file is provided.
       LG << "Class not found";  // TODO: NoClassDefFoundError
@@ -116,6 +121,153 @@
   return klass;
 }
 
+bool ClassLinker::LoadClass(const char* descriptor, Class* klass) {
+  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+  const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
+  if (class_def == NULL) {
+    return false;
+  } else {
+    return LoadClass(*class_def, klass);
+  }
+}
+
+bool ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
+  CHECK(klass != NULL);
+  CHECK(klass->dex_file_ != NULL);
+  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+  const byte* class_data = raw->GetClassData(class_def);
+  RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
+
+  const char* descriptor = raw->GetClassDescriptor(class_def);
+  CHECK(descriptor != NULL);
+
+  klass->klass_ = java_lang_Class_;
+  klass->descriptor_.set(descriptor);
+  klass->descriptor_alloc_ = NULL;
+  klass->access_flags_ = class_def.access_flags_;
+  klass->class_loader_ = NULL;  // TODO
+  klass->primitive_type_ = Class::kPrimNot;
+  klass->status_ = Class::kStatusIdx;
+
+  klass->super_class_ = NULL;
+  klass->super_class_idx_ = class_def.superclass_idx_;
+
+  klass->num_sfields_ = header.static_fields_size_;
+  klass->num_ifields_ = header.instance_fields_size_;
+  klass->num_direct_methods_ = header.direct_methods_size_;
+  klass->num_virtual_methods_ = header.virtual_methods_size_;
+
+  klass->source_file_ = raw->dexGetSourceFile(class_def);
+
+  // Load class interfaces.
+  LoadInterfaces(class_def, klass);
+
+  // Load static fields.
+  if (klass->num_sfields_ != 0) {
+    // TODO: allocate on the object heap.
+    klass->sfields_ = new StaticField[klass->NumStaticFields()]();
+    uint32_t last_idx = 0;
+    for (size_t i = 0; i < klass->num_sfields_; ++i) {
+      RawDexFile::Field raw_field;
+      raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+      LoadField(klass, raw_field, &klass->sfields_[i]);
+    }
+  }
+
+  // Load instance fields.
+  if (klass->NumInstanceFields() != 0) {
+    // TODO: allocate on the object heap.
+    klass->ifields_ = new InstanceField[klass->NumInstanceFields()]();
+    uint32_t last_idx = 0;
+    for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
+      RawDexFile::Field raw_field;
+      raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+      LoadField(klass, raw_field, klass->GetInstanceField(i));
+    }
+  }
+
+  // Load direct methods.
+  if (klass->NumDirectMethods() != 0) {
+    // TODO: append direct methods to class object
+    klass->direct_methods_ = new Method[klass->NumDirectMethods()]();
+    uint32_t last_idx = 0;
+    for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
+      RawDexFile::Method raw_method;
+      raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+      LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
+      // TODO: register maps
+    }
+  }
+
+  // Load virtual methods.
+  if (klass->NumVirtualMethods() != 0) {
+    // TODO: append virtual methods to class object
+    klass->virtual_methods_ = new Method[klass->NumVirtualMethods()]();
+    uint32_t last_idx = 0;
+    for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
+      RawDexFile::Method raw_method;
+      raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+      LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
+      // TODO: register maps
+    }
+  }
+
+  return klass;
+}
+
+void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
+                                 Class* klass) {
+  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+  const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
+  if (list != NULL) {
+    klass->interface_count_ = list->Size();
+    // TODO: allocate the interfaces array on the object heap.
+    klass->interfaces_ = new Class*[list->Size()]();
+    for (size_t i = 0; i < list->Size(); ++i) {
+      const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
+      klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
+    }
+  }
+}
+
+void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
+                            Field* dst) {
+  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+  const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
+  dst->klass_ = klass;
+  dst->name_ = raw->dexStringById(field_id.name_idx_);
+  dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
+  dst->access_flags_ = src.access_flags_;
+}
+
+void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
+                             Method* dst) {
+  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+  const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
+  dst->klass_ = klass;
+  dst->name_.set(raw->dexStringById(method_id.name_idx_));
+  dst->proto_idx_ = method_id.proto_idx_;
+  dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
+  dst->access_flags_ = src.access_flags_;
+
+  // TODO: check for finalize method
+
+  const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
+  if (code_item != NULL) {
+    dst->num_registers_ = code_item->registers_size_;
+    dst->num_ins_ = code_item->ins_size_;
+    dst->num_outs_ = code_item->outs_size_;
+    dst->insns_ = code_item->insns_;
+  } else {
+    uint16_t num_args = dst->NumArgRegisters();
+    if (!dst->IsStatic()) {
+      ++num_args;
+    }
+    dst->num_registers_ = dst->num_ins_ + num_args;
+    // TODO: native methods
+  }
+}
+
 DexFile* ClassLinker::FindInClassPath(const char* descriptor) {
   for (size_t i = 0; i != class_path_.size(); ++i) {
     DexFile* dex_file = class_path_[i];
@@ -131,7 +283,7 @@
 }
 
 Class* ClassLinker::CreatePrimitiveClass(JType type, const char* descriptor) {
-  Class* klass = Heap::AllocClass();
+  Class* klass = Heap::AllocClass(NULL);
   CHECK(klass != NULL);
   klass->super_class_ = java_lang_Class_;
   klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
@@ -348,8 +500,8 @@
 }
 
 bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
-                                                const Class* klass1,
-                                                const Class* klass2) {
+                                                 const Class* klass1,
+                                                 const Class* klass2) {
   const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
   const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
   RawDexFile::ParameterIterator *it;
@@ -378,8 +530,8 @@
 // Returns true if classes referenced by the descriptor are the
 // same classes in klass1 as they are in klass2.
 bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
-                                          const Class* klass1,
-                                          const Class* klass2) {
+                                           const Class* klass1,
+                                           const Class* klass2) {
   CHECK(descriptor != NULL);
   CHECK(klass1 != NULL);
   CHECK(klass2 != NULL);
@@ -432,7 +584,7 @@
     return;
   }
   const char* descriptor = klass->GetDescriptor().data();
-  RawDexFile* raw = dex_file->GetRaw();
+  const RawDexFile* raw = dex_file->GetRaw();
   const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
   CHECK(class_def != NULL);
   const byte* addr = raw->GetEncodedArray(*class_def);