Finish moving state to managed heap

Change-Id: I8a3b0e353b30268a05d6ed8ea0a6a4bead100660
diff --git a/Android.mk b/Android.mk
index d6c8eb3..462aa29 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,6 +17,13 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+# These can be overridden via the environment or by editing to
+# enable/disable certain build configuration.
+ART_BUILD_TARGET_NDEBUG ?= true
+ART_BUILD_TARGET_DEBUG ?= true
+ART_BUILD_HOST_NDEBUG ?= true
+ART_BUILD_HOST_DEBUG ?= true
+
 build_path := $(LOCAL_PATH)/build
 include $(build_path)/Android.common.mk
 
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 8b22b83..3c203d4 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -173,3 +173,18 @@
 	SystemMethods \
 	Invoke \
 	XandY
+
+ART_BUILD_TARGET := false
+ART_BUILD_HOST := false
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+  ART_BUILD_TARGET := true
+endif
+ifeq ($(ART_BUILD_TARGET_DEBUG),true)
+  ART_BUILD_TARGET := true
+endif
+ifeq ($(ART_BUILD_HOST_NDEBUG),true)
+  ART_BUILD_HOST := true
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),true)
+  ART_BUILD_HOST := true
+endif
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index 328f60a..2abb42a 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -60,17 +60,20 @@
   endif
 endef
 
-$(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),target,ndebug))
-$(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),target,debug))
-ifeq ($(WITH_HOST_DALVIK),true)
-  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),host,ndebug))
-  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),host,debug))
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),target,ndebug))
+  $(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),target,ndebug))
 endif
-
-$(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),target,ndebug))
-$(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),target,debug))
-ifeq ($(WITH_HOST_DALVIK),true)
+ifeq ($(ART_BUILD_TARGET_DEBUG),true)
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),target,debug))
+  $(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),target,debug))
+endif
+ifeq ($(ART_BUILD_HOST_NDEBUG),true)
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),host,ndebug))
   $(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),host,ndebug))
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),true)
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),host,debug))
   $(eval $(call build-art-executable,oatexec,$(OATEXEC_SRC_FILES),host,debug))
 endif
 
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 3218a42..974907e 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -53,9 +53,15 @@
   endif
 endef
 
-$(eval $(call build-libart,target,ndebug))
-$(eval $(call build-libart,target,debug))
-ifeq ($(WITH_HOST_DALVIK),true)
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+  $(eval $(call build-libart,target,ndebug))
+endif
+ifeq ($(ART_BUILD_TARGET_DEBUG),true)
+  $(eval $(call build-libart,target,debug))
+endif
+ifeq ($(ART_BUILD_HOST_NDEBUG),true)
   $(eval $(call build-libart,host,ndebug))
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),true)
   $(eval $(call build-libart,host,debug))
 endif
diff --git a/build/Android.libarttest.mk b/build/Android.libarttest.mk
index 107eddc..9cde3e5 100644
--- a/build/Android.libarttest.mk
+++ b/build/Android.libarttest.mk
@@ -37,7 +37,9 @@
   endif
 endef
 
-$(eval $(call build-libarttest,target))
-ifeq ($(WITH_HOST_DALVIK),true)
+ifeq ($(ART_BUILD_TARGET),true)
+  $(eval $(call build-libarttest,target))
+endif
+ifeq ($(ART_BUILD_HOST),true)
   $(eval $(call build-libarttest,host))
 endif
diff --git a/build/Android.test.mk b/build/Android.test.mk
index 9dabd4f..90fc44a 100644
--- a/build/Android.test.mk
+++ b/build/Android.test.mk
@@ -50,8 +50,10 @@
   endif
 endef
 
-$(foreach file,$(TEST_TARGET_SRC_FILES), $(eval $(call build-art-test,target,$(file))))
-ifeq ($(WITH_HOST_DALVIK),true)
+ifeq ($(ART_BUILD_TARGET),true)
+  $(foreach file,$(TEST_TARGET_SRC_FILES), $(eval $(call build-art-test,target,$(file))))
+endif
+ifeq ($(ART_BUILD_HOST),true)
   $(foreach file,$(TEST_HOST_SRC_FILES), $(eval $(call build-art-test,host,$(file))))
 endif
 
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c81df8d..8595bfc 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -151,7 +151,7 @@
 
   // Create array interface entries to populate once we can load system classes
   array_interfaces_ = AllocObjectArray<Class>(2);
-  array_iftable_ = new InterfaceEntry[2];
+  array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
 
   // Create int array type for AllocDexCache (done in AppendToBootClassPath)
   Class* int_array_class = AllocClass(java_lang_Class, sizeof(Class));
@@ -195,8 +195,7 @@
 
   // now we can use FindSystemClass
 
-  // Object and String just need more minimal setup, since they do not have
-  // extra C++ fields.
+  // Object and String need to be rerun through FindSystemClass to finish init
   java_lang_Object->SetStatus(Class::kStatusNotReady);
   Class* Object_class = FindSystemClass("Ljava/lang/Object;");
   CHECK_EQ(java_lang_Object, Object_class);
@@ -206,8 +205,7 @@
   CHECK_EQ(java_lang_String, String_class);
   CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(String));
 
-  // Setup the primitive array type classes - can't be done until Object has
-  // a vtable
+  // Setup the primitive array type classes - can't be done until Object has a vtable
   SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
   BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
 
@@ -245,10 +243,9 @@
   array_interfaces_->Set(1, java_io_Serializable);
   // We assume that Cloneable/Serializable don't have superinterfaces --
   // normally we'd have to crawl up and explicitly list all of the
-  // supers as well.  These interfaces don't have any methods, so we
-  // don't have to worry about the ifviPool either.
-  array_iftable_[0].SetInterface(array_interfaces_->Get(0));
-  array_iftable_[1].SetInterface(array_interfaces_->Get(1));
+  // supers as well.
+  array_iftable_->Set(0, AllocInterfaceEntry(array_interfaces_->Get(0)));
+  array_iftable_->Set(1, AllocInterfaceEntry(array_interfaces_->Get(1)));
 
   // Sanity check Object[]'s interfaces
   CHECK_EQ(java_lang_Cloneable, object_array_class->GetInterface(0));
@@ -549,6 +546,14 @@
   return down_cast<CodeAndDirectMethods*>(IntArray::Alloc(CodeAndDirectMethods::LengthAsArray(length)));
 }
 
+InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) {
+  DCHECK(interface->IsInterface());
+  ObjectArray<Object>* array = AllocObjectArray<Object>(InterfaceEntry::LengthAsArray());
+  InterfaceEntry* interface_entry = down_cast<InterfaceEntry*>(array);
+  interface_entry->SetInterface(interface);
+  return interface_entry;
+}
+
 Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
   DCHECK_GE(class_size, sizeof(Class));
   Class* klass = Heap::AllocObject(java_lang_Class, class_size)->AsClass();
@@ -774,7 +779,7 @@
   size_t num_direct_methods = header.direct_methods_size_;
   size_t num_virtual_methods = header.virtual_methods_size_;
 
-  klass->SetSourceFile(dex_file.dexGetSourceFile(dex_class_def));
+  klass->SetSourceFile(String::AllocFromModifiedUtf8(dex_file.dexGetSourceFile(dex_class_def)));
 
   // Load class interfaces.
   LoadInterfaces(dex_file, dex_class_def, klass);
@@ -1099,8 +1104,7 @@
   // Use the single, global copies of "interfaces" and "iftable"
   // (remember not to free them for arrays).
   new_class->SetInterfaces(array_interfaces_);
-  new_class->SetIFTableCount(2);
-  new_class->SetIFTable(array_iftable_);
+  new_class->SetIfTable(array_iftable_);
 
   // Inherit access flags from the component type.  Arrays can't be
   // used as a superclass or interface, so we want to add "final"
@@ -1303,13 +1307,12 @@
       }
     }
   }
-  for (size_t i = 0; i < klass->GetIFTableCount(); ++i) {
-    const InterfaceEntry* iftable = &klass->GetIFTable()[i];
-    Class* interface = iftable->GetInterface();
+  for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
+    InterfaceEntry* interface_entry = klass->GetIfTable()->Get(i);
+    Class* interface = interface_entry->GetInterface();
     if (klass->GetClassLoader() != interface->GetClassLoader()) {
       for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
-        uint32_t vtable_index = iftable->GetMethodIndexArray()[j];
-        const Method* method = klass->GetVirtualMethod(vtable_index);
+        const Method* method = interface_entry->GetMethodArray()->Get(j);
         if (!HasSameMethodDescriptorClasses(method, interface,
                                             method->GetClass())) {
           LG << "Classes resolve differently in interface";  // TODO: LinkageError
@@ -1684,71 +1687,61 @@
 }
 
 bool ClassLinker::LinkInterfaceMethods(Class* klass) {
-  int pool_offset = 0;
-  int pool_size = 0;
   int miranda_count = 0;
   int miranda_alloc = 0;
   size_t super_ifcount;
   if (klass->HasSuperClass()) {
-    super_ifcount = klass->GetSuperClass()->GetIFTableCount();
+    super_ifcount = klass->GetSuperClass()->GetIfTableCount();
   } else {
     super_ifcount = 0;
   }
   size_t ifcount = super_ifcount;
   ifcount += klass->NumInterfaces();
   for (size_t i = 0; i < klass->NumInterfaces(); i++) {
-    ifcount += klass->GetInterface(i)->GetIFTableCount();
+    ifcount += klass->GetInterface(i)->GetIfTableCount();
   }
   if (ifcount == 0) {
     // TODO: enable these asserts with klass status validation
-    // DCHECK(klass->GetIFTableCount() == 0);
-    // DCHECK(klass->GetIFTable() == NULL);
+    // DCHECK(klass->GetIfTableCount() == 0);
+    // DCHECK(klass->GetIfTable() == NULL);
     return true;
   }
-  InterfaceEntry* iftable = new InterfaceEntry[ifcount];
-  memset(iftable, 0x00, sizeof(InterfaceEntry) * ifcount);
+  ObjectArray<InterfaceEntry>* iftable = AllocObjectArray<InterfaceEntry>(ifcount);
   if (super_ifcount != 0) {
-    memcpy(iftable, klass->GetSuperClass()->GetIFTable(),
-           sizeof(InterfaceEntry) * super_ifcount);
+    ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
+    for (size_t i = 0; i < super_ifcount; i++) {
+      iftable->Set(i, AllocInterfaceEntry(super_iftable->Get(i)->GetInterface()));
+    }
   }
   // Flatten the interface inheritance hierarchy.
   size_t idx = super_ifcount;
   for (size_t i = 0; i < klass->NumInterfaces(); i++) {
-    Class* interf = klass->GetInterface(i);
-    DCHECK(interf != NULL);
-    if (!interf->IsInterface()) {
+    Class* interface = klass->GetInterface(i);
+    DCHECK(interface != NULL);
+    if (!interface->IsInterface()) {
       LG << "Class implements non-interface class";  // TODO: IncompatibleClassChangeError
       return false;
     }
-    iftable[idx++].SetInterface(interf);
-    for (size_t j = 0; j < interf->GetIFTableCount(); j++) {
-      iftable[idx++].SetInterface(interf->GetIFTable()[j].GetInterface());
+    iftable->Set(idx++, AllocInterfaceEntry(interface));
+    for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
+      iftable->Set(idx++, AllocInterfaceEntry(interface->GetIfTable()->Get(j)->GetInterface()));
     }
   }
-  klass->SetIFTable(iftable);
+  klass->SetIfTable(iftable);
   CHECK_EQ(idx, ifcount);
-  klass->SetIFTableCount(ifcount);
   if (klass->IsInterface() || super_ifcount == ifcount) {
     return true;
   }
-  for (size_t i = super_ifcount; i < ifcount; i++) {
-    pool_size += iftable[i].GetInterface()->NumVirtualMethods();
-  }
-  if (pool_size == 0) {
-    return true;
-  }
-  klass->SetIfviPoolCount(pool_size);
-  uint32_t* ifvi_pool = new uint32_t[pool_size];
-  klass->SetIfviPool(ifvi_pool);
   std::vector<Method*> miranda_list;
-  for (size_t i = super_ifcount; i < ifcount; ++i) {
-    iftable[i].SetMethodIndexArray(ifvi_pool + pool_offset);
-    Class* interface = iftable[i].GetInterface();
-    pool_offset += interface->NumVirtualMethods();    // end here
+  for (size_t i = 0; i < ifcount; ++i) {
+    InterfaceEntry* interface_entry = iftable->Get(i);
+    Class* interface = interface_entry->GetInterface();
+    ObjectArray<Method>* method_array = AllocObjectArray<Method>(interface->NumVirtualMethods());
+    interface_entry->SetMethodArray(method_array);
     ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
     for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
       Method* interface_method = interface->GetVirtualMethod(j);
-      int k;  // must be signed
+      int32_t k;
       for (k = vtable->GetLength() - 1; k >= 0; --k) {
         Method* vtable_method = vtable->Get(k);
         if (interface_method->HasSameNameAndDescriptor(vtable_method)) {
@@ -1756,7 +1749,7 @@
             LG << "Implementation not public";
             return false;
           }
-          iftable[i].GetMethodIndexArray()[j] = k;
+          method_array->Set(j, vtable_method);
           break;
         }
       }
@@ -1769,16 +1762,16 @@
             miranda_list.resize(miranda_alloc);
           }
         }
+        Method* miranda_method = NULL;
         int mir;
         for (mir = 0; mir < miranda_count; mir++) {
-          Method* miranda_method = miranda_list[mir];
+          miranda_method = miranda_list[mir];
           if (miranda_method->HasSameNameAndDescriptor(interface_method)) {
             break;
           }
         }
-        // point the interface table at a phantom slot index
-        iftable[i].GetMethodIndexArray()[j] =
-            vtable->GetLength() + mir;
+        // point the interface table at a phantom slot
+        method_array->Set(j, miranda_method);
         if (mir == miranda_count) {
           miranda_list[miranda_count++] = interface_method;
         }
diff --git a/src/class_linker.h b/src/class_linker.h
index fe375c2..e9606a7 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -175,6 +175,7 @@
   Field* AllocField();
   Method* AllocMethod();
   CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
+  InterfaceEntry* AllocInterfaceEntry(Class* interface);
 
   Class* CreatePrimitiveClass(const char* descriptor,
                               Class::PrimitiveType type);
@@ -331,7 +332,7 @@
   }
 
   ObjectArray<Class>* array_interfaces_;
-  InterfaceEntry* array_iftable_;
+  ObjectArray<InterfaceEntry>* array_iftable_;
 
   bool init_done_;
 
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index c3bb4c3..eab184e 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -390,16 +390,26 @@
 
     bool error = false;
 
-    if (!klass->IsClassClass() && instance)
-      if (size != (instance ? klass->GetObjectSize() : klass->GetClassSize())) {
+    if (!klass->IsClassClass() && instance) {
+      size_t expected_size = instance ? klass->GetObjectSize() : klass->GetClassSize();
+      if (size != expected_size) {
         LG << "Class size mismatch:"
            << " class=" << class_descriptor
            << " Java=" << klass->GetObjectSize()
-           << " C++=" << (instance ? klass->GetObjectSize() : klass->GetClassSize());
+           << " C++=" << expected_size;
+        error = true;
+      }
+    }
+
+    size_t num_fields = instance ? klass->NumInstanceFields() : klass->NumStaticFields();
+    if (offsets.size() != num_fields) {
+      LG << "Field count mismatch:"
+         << " class=" << class_descriptor
+         << " Java=" << num_fields
+         << " C++=" << offsets.size();
       error = true;
     }
 
-    CHECK_EQ(offsets.size(), instance ? klass->NumInstanceFields() : klass->NumStaticFields());
     for (size_t i = 0; i < offsets.size(); i++) {
       Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
       if (!field->GetName()->Equals(offsets[i].java_name)) {
@@ -550,9 +560,11 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, dex_cache_),                     "shadow$_dex_cache_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, direct_methods_),                "shadow$_direct_methods_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifields_),                       "shadow$_ifields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_),                       "shadow$_iftable_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_),                    "shadow$_interfaces_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_type_idx_),           "shadow$_interfaces_type_idx_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, sfields_),                       "shadow$_sfields_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_),                   "shadow$_source_file_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_),                   "shadow$_super_class_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, verify_error_class_),            "shadow$_verify_error_class_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, virtual_methods_),               "shadow$_virtual_methods_"));
@@ -563,17 +575,12 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, array_rank_),                    "shadow$_array_rank_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_size_),                    "shadow$_class_size_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, clinit_thread_id_),              "shadow$_clinit_thread_id_"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_),                       "shadow$_iftable_"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_count_),                 "shadow$_iftable_count_"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_),                     "shadow$_ifvi_pool_"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_count_),               "shadow$_ifvi_pool_count_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_instance_fields_), "shadow$_num_reference_instance_fields_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_static_fields_),   "shadow$_num_reference_static_fields_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, object_size_),                   "shadow$_object_size_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, primitive_type_),                "shadow$_primitive_type_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_instance_offsets_),    "shadow$_reference_instance_offsets_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_static_offsets_),      "shadow$_reference_static_offsets_"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_),                   "shadow$_source_file_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, status_),                        "shadow$_status_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_type_idx_),          "shadow$_super_class_type_idx_"));
   };
@@ -662,9 +669,6 @@
     size = sizeof(ClassClass);
     class_descriptor = "Ljava/lang/Class;";
 
-    // padding 32-bit
-    // this space intentionally left blank
-
     // alphabetical 64-bit
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(ClassClass, serialVersionUID_), "serialVersionUID"));
   };
@@ -680,11 +684,11 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, ASCII_),                  "ASCII"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
 
-    // padding 32-bit
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, REPLACEMENT_CHAR_),       "REPLACEMENT_CHAR"));
-
     // alphabetical 64-bit
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, serialVersionUID_),       "serialVersionUID"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, REPLACEMENT_CHAR_),       "REPLACEMENT_CHAR"));
   };
 };
 
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 22dae24..0ac2ee1 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -182,9 +182,9 @@
     return static_cast<ObjectArray<StaticStorageBase>*>(GetNonNull(kInitializedStaticStorage));
   }
 
- static size_t LengthAsArray() {
-   return kMax;
- }
+  static size_t LengthAsArray() {
+    return kMax;
+  }
 
  private:
 
diff --git a/src/object.cc b/src/object.cc
index 2c66690..3696374 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -497,9 +497,8 @@
 
   bool have_executable_code = (GetCode() != NULL);
 #if !defined(__arm__)
-  // Currently we can only compile for ARM, so we can't execute
-  // code on other architectures even if we do have it.
-  have_executable_code = false;
+  // Currently we can only compile non-native methods for ARM.
+  have_executable_code = IsNative();
 #endif
 
   if (have_executable_code && stub != NULL) {
@@ -620,8 +619,10 @@
   // All interfaces implemented directly and by our superclass, and
   // recursively all super-interfaces of those interfaces, are listed
   // in iftable_, so we can just do a linear scan through that.
-  for (size_t i = 0; i < iftable_count_; i++) {
-    if (iftable_[i].GetInterface() == klass) {
+  int32_t iftable_count = GetIfTableCount();
+  ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+  for (int32_t i = 0; i < iftable_count; i++) {
+    if (iftable->Get(i)->GetInterface() == klass) {
       return true;
     }
   }
@@ -783,11 +784,12 @@
   Class* declaring_class = method->GetDeclaringClass();
   DCHECK(declaring_class->IsInterface());
   // TODO cache to improve lookup speed
-  for (size_t i = 0; i < iftable_count_; i++) {
-    InterfaceEntry& interface_entry = iftable_[i];
-    if (interface_entry.GetInterface() == declaring_class) {
-      return GetVTable()->Get(
-          interface_entry.GetMethodIndexArray()[method->GetMethodIndex()]);
+  int32_t iftable_count = GetIfTableCount();
+  ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+  for (int32_t i = 0; i < iftable_count; i++) {
+    InterfaceEntry* interface_entry = iftable->Get(i);
+    if (interface_entry->GetInterface() == declaring_class) {
+      return interface_entry->GetMethodArray()->Get(method->GetMethodIndex());
     }
   }
   UNIMPLEMENTED(FATAL) << "Need to throw an error of some kind";
@@ -802,9 +804,10 @@
     return method;
   }
 
-  InterfaceEntry* iftable = GetIFTable();
-  for (size_t i = 0; i < GetIFTableCount(); i++) {
-    method = iftable[i].GetInterface()->FindVirtualMethod(name, signature);
+  int32_t iftable_count = GetIfTableCount();
+  ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+  for (int32_t i = 0; i < iftable_count; i++) {
+    method = iftable->Get(i)->GetInterface()->FindVirtualMethod(name, signature);
     if (method != NULL) {
       return method;
     }
diff --git a/src/object.h b/src/object.h
index 8f51244..b7cbee5 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1072,7 +1072,7 @@
   // in Class::vtable_.
   //
   // For abstract methods in an interface class, this is the offset
-  // of the method in "iftable_[n]->method_index_array_".
+  // of the method in "iftable_->Get(n)->GetMethodArray()".
   uint32_t method_index_;  // (could be uint16_t)
 
   // The target native method registered with this method
@@ -1761,49 +1761,23 @@
     return GetInterfaces()->Get(i);
   }
 
-  size_t GetIFTableCount() const {
-    DCHECK(IsResolved());
-    DCHECK(sizeof(size_t) == sizeof(int32_t));
-    return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, iftable_count_), false);
+  int32_t GetIfTableCount() const {
+    ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+    if (iftable == NULL) {
+      return 0;
+    }
+    return iftable->GetLength();
   }
 
-  void SetIFTableCount(size_t new_iftable_count) {
-    DCHECK(sizeof(size_t) == sizeof(int32_t));
-    SetField32(OFFSET_OF_OBJECT_MEMBER(Class, iftable_count_),
-               new_iftable_count, false);
-  }
-
-  InterfaceEntry* GetIFTable() const {
+  ObjectArray<InterfaceEntry>* GetIfTable() const {
     DCHECK(IsResolved());
-    return GetFieldPtr<InterfaceEntry*>(
+    return GetFieldObject<ObjectArray<InterfaceEntry>*>(
         OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
   }
 
-  void SetIFTable(InterfaceEntry* new_iftable) {
-    SetFieldPtr<InterfaceEntry*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_),
-                                 new_iftable, false);
-  }
-
-  size_t GetIfviPoolCount() const {
-    DCHECK(IsResolved());
-    CHECK(sizeof(size_t) == sizeof(int32_t));
-    return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_count_), false);
-  }
-
-  void SetIfviPoolCount(size_t new_count) {
-    CHECK(sizeof(size_t) == sizeof(int32_t));
-    SetField32(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_count_), new_count,
-               false);
-  }
-
-  uint32_t* GetIfviPool() const {
-    DCHECK(IsResolved());
-    return GetFieldPtr<uint32_t*>(
-        OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_), false);
-  }
-
-  void SetIfviPool(uint32_t* new_pool) {
-    SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_), new_pool, false);
+  void SetIfTable(ObjectArray<InterfaceEntry>* new_iftable) {
+    SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_),
+		   new_iftable, false);
   }
 
   // Get instance fields
@@ -1955,14 +1929,14 @@
                           klass, false);
   }
 
-  const char* GetSourceFile() const {
+  String* GetSourceFile() const {
     DCHECK(IsLoaded());
-    return GetFieldPtr<const char*>(
+    return GetFieldPtr<String*>(
         OFFSET_OF_OBJECT_MEMBER(Class, source_file_), false);
   }
 
-  void SetSourceFile(const char* new_source_file) {
-    SetFieldPtr<const char*>(OFFSET_OF_OBJECT_MEMBER(Class, source_file_),
+  void SetSourceFile(String* new_source_file) {
+    SetFieldPtr<String*>(OFFSET_OF_OBJECT_MEMBER(Class, source_file_),
                              new_source_file, false);
   }
 
@@ -1981,7 +1955,7 @@
   // For array classes, the class object for base element, for
   // instanceof/checkcast (for String[][][], this will be String).
   // Otherwise, NULL.
-  Class* component_type_;  // TODO: make an instance field
+  Class* component_type_;
 
   // descriptor for the class such as "Ljava/lang/Class;" or "[C"
   String* descriptor_;
@@ -2005,6 +1979,21 @@
   // specifies the number of reference fields.
   ObjectArray<Field>* ifields_;
 
+  // Interface table (iftable_), one entry per interface supported by
+  // this class.  That means one entry for each interface we support
+  // directly, indirectly via superclass, or indirectly via
+  // superinterface.  This will be null if neither we nor our
+  // superclass implement any interfaces.
+  //
+  // Why we need this: given "class Foo implements Face", declare
+  // "Face faceObj = new Foo()".  Invoke faceObj.blah(), where "blah"
+  // is part of the Face interface.  We can't easily use a single
+  // vtable.
+  //
+  // For every interface a concrete class implements, we create an array
+  // of the concrete vtable_ methods for the methods in the interface.
+  ObjectArray<InterfaceEntry>* iftable_;
+
   // array of interfaces this class implements directly
   // see also interfaces_type_idx_
   ObjectArray<Class>* interfaces_;
@@ -2016,6 +2005,9 @@
   // Static fields
   ObjectArray<Field>* sfields_;
 
+  // source file name, if known.  Otherwise, NULL.
+  String* source_file_;
+
   // The superclass, or NULL if this is java.lang.Object or a
   // primitive type.
   // see also super_class_type_idx_;
@@ -2046,40 +2038,6 @@
   // threadId, used to check for recursive <clinit> invocation
   pid_t clinit_thread_id_;
 
-  // Interface table (iftable_), one entry per interface supported by
-  // this class.  That means one entry for each interface we support
-  // directly, indirectly via superclass, or indirectly via
-  // superinterface.  This will be null if neither we nor our
-  // superclass implement any interfaces.
-  //
-  // Why we need this: given "class Foo implements Face", declare
-  // "Face faceObj = new Foo()".  Invoke faceObj.blah(), where "blah"
-  // is part of the Face interface.  We can't easily use a single
-  // vtable.
-  //
-  // For every interface a concrete class implements, we create a list
-  // of virtualMethod indices for the methods in the interface.
-  //
-  // see also iftable_count_;
-  // TODO convert to ObjectArray<?>
-  //
-  InterfaceEntry* iftable_;
-
-  // size of iftable_
-  size_t iftable_count_;
-
-  // The interface vtable indices for iftable get stored here.  By
-  // placing them all in a single pool for each class that implements
-  // interfaces, we decrease the number of allocations.
-  //
-  // see also ifvi_pool_count_
-  //
-  // TODO convert to IntArray
-  uint32_t* ifvi_pool_;
-
-  // size of ifvi_pool_
-  size_t ifvi_pool_count_;
-
   // number of instance fields that are object refs
   size_t num_reference_instance_fields_;
 
@@ -2099,9 +2057,6 @@
   // Bitmap of offsets of sfields.
   uint32_t reference_static_offsets_;
 
-  // source file name, if known.  Otherwise, NULL.
-  const char* source_file_;
-
   // state of class initialization
   Status status_;
 
@@ -2328,8 +2283,6 @@
 
 class ClassClass : public Class {
  private:
-  // Padding to ensure the 64-bit serialVersionUID_ begins on a 8-byte boundary
-  int32_t padding_;
   int64_t serialVersionUID_;
   friend struct ClassClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
@@ -2339,8 +2292,8 @@
  private:
   CharArray* ASCII_;
   Object* CASE_INSENSITIVE_ORDER_;
-  uint32_t REPLACEMENT_CHAR_;
   int64_t serialVersionUID_;
+  uint32_t REPLACEMENT_CHAR_;
   friend struct StringClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
 };
@@ -2725,39 +2678,49 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(StackTraceElement);
 };
 
-class InterfaceEntry {
+ class InterfaceEntry : public ObjectArray<Object> {
  public:
-  InterfaceEntry() : interface_(NULL), method_index_array_(NULL) {
-  }
-
   Class* GetInterface() const {
-    DCHECK(interface_ != NULL);
-    return interface_;
+    Class* interface = Get(kInterface)->AsClass();
+    DCHECK(interface != NULL);
+    return interface;
   }
 
   void SetInterface(Class* interface) {
+    DCHECK(interface != NULL);
     DCHECK(interface->IsInterface());
-    interface_ = interface;
+    DCHECK(Get(kInterface) == NULL);
+    Set(kInterface, interface);
   }
 
-  uint32_t* GetMethodIndexArray() const {
-    return method_index_array_;
+  ObjectArray<Method>* GetMethodArray() const {
+    ObjectArray<Method>* method_array = down_cast<ObjectArray<Method>*>(Get(kMethodArray));
+    DCHECK(method_array != NULL);
+    return method_array;
   }
 
-  void SetMethodIndexArray(uint32_t* new_mia) {
-    method_index_array_ = new_mia;
+  void SetMethodArray(ObjectArray<Method>* new_ma) {
+    DCHECK(new_ma != NULL);
+    DCHECK(Get(kMethodArray) == NULL);
+    Set(kMethodArray, new_ma);
+  }
+
+  static size_t LengthAsArray() {
+    return kMax;
   }
 
  private:
-  // Points to the interface class.
-  Class* interface_;
 
-  // Index into array of vtable offsets.  This points into the
-  // ifvi_pool_, which holds the vtables for all interfaces declared by
-  // this class.
-  uint32_t* method_index_array_;
+  enum ArrayIndex {
+    // Points to the interface class.
+    kInterface   = 0,
+    // Method pointers into the vtable, allow fast map from interface
+    // method index to concrete instance method.
+    kMethodArray = 1,
+    kMax         = 2,
+  };
 
-  DISALLOW_COPY_AND_ASSIGN(InterfaceEntry);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(InterfaceEntry);
 };
 
 }  // namespace art
diff --git a/src/thread.cc b/src/thread.cc
index 9361d00..78cb1c6 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -325,7 +325,11 @@
   if (errno != 0) {
     PLOG(FATAL) << "pthread_mutexattr_init failed";
   }
+#if VERIFY_OBJECT_ENABLED
+  errno = pthread_mutexattr_settype(&debug_attributes, PTHREAD_MUTEX_RECURSIVE);
+#else
   errno = pthread_mutexattr_settype(&debug_attributes, PTHREAD_MUTEX_ERRORCHECK);
+#endif
   if (errno != 0) {
     PLOG(FATAL) << "pthread_mutexattr_settype failed";
   }
@@ -928,7 +932,7 @@
     StackTraceElement* obj =
         StackTraceElement::Alloc(readable_descriptor,
                                  method->GetName(),
-                                 String::AllocFromModifiedUtf8(klass->GetSourceFile()),
+                                 klass->GetSourceFile(),
                                  dex_file.GetLineNumFromPC(method,
                                      method->ToDexPC(build_trace_visitor.GetPC(i))));
     java_traces->Set(i, obj);