Finish moving state to managed heap

Change-Id: I8a3b0e353b30268a05d6ed8ea0a6a4bead100660
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;
         }