Set vtable in class object to null after linking.

This is follow-up work of embedding imt and vtable for
faster interface/virtual call dispatching.
Once vtable becomes embedded, the original vtable is nulled.

Change-Id: I307696657d1e283654169dbecb8f7815c42bbabc
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6c5679e..c40424b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3570,9 +3570,9 @@
   MethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
   if (klass->HasSuperClass() &&
       klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
-    for (int i = klass->GetSuperClass()->GetVTable()->GetLength() - 1; i >= 0; --i) {
-      mh.ChangeMethod(klass->GetVTable()->GetWithoutChecks(i));
-      super_mh.ChangeMethod(klass->GetSuperClass()->GetVTable()->GetWithoutChecks(i));
+    for (int i = klass->GetSuperClass()->GetVTableLength() - 1; i >= 0; --i) {
+      mh.ChangeMethod(klass->GetVTableEntry(i));
+      super_mh.ChangeMethod(klass->GetSuperClass()->GetVTableEntry(i));
       if (mh.GetMethod() != super_mh.GetMethod() &&
           !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
         ThrowLinkageError(klass.Get(),
@@ -3730,10 +3730,6 @@
     // This will notify waiters on new_class that saw the not yet resolved
     // class in the class_table_ during EnsureResolved.
     new_class_h->SetStatus(mirror::Class::kStatusResolved, self);
-
-    // Only embedded imt should be used from this point.
-    new_class_h->SetImTable(NULL);
-    // TODO: remove vtable and only use embedded vtable.
   }
   return true;
 }
@@ -3866,17 +3862,31 @@
 bool ClassLinker::LinkVirtualMethods(Thread* self, Handle<mirror::Class> klass) {
   if (klass->HasSuperClass()) {
     uint32_t max_count = klass->NumVirtualMethods() +
-        klass->GetSuperClass()->GetVTable()->GetLength();
-    size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
+        klass->GetSuperClass()->GetVTableLength();
+    size_t actual_count = klass->GetSuperClass()->GetVTableLength();
     CHECK_LE(actual_count, max_count);
-    // TODO: do not assign to the vtable field until it is fully constructed.
     StackHandleScope<3> hs(self);
-    Handle<mirror::ObjectArray<mirror::ArtMethod>> vtable(
-        hs.NewHandle(klass->GetSuperClass()->GetVTable()->CopyOf(self, max_count)));
-    if (UNLIKELY(vtable.Get() == NULL)) {
-      CHECK(self->IsExceptionPending());  // OOME.
-      return false;
+    Handle<mirror::ObjectArray<mirror::ArtMethod>> vtable;
+    mirror::Class* super_class = klass->GetSuperClass();
+    if (super_class->ShouldHaveEmbeddedImtAndVTable()) {
+      vtable = hs.NewHandle(AllocArtMethodArray(self, max_count));
+      if (UNLIKELY(vtable.Get() == nullptr)) {
+        CHECK(self->IsExceptionPending());  // OOME.
+        return false;
+      }
+      int len = super_class->GetVTableLength();
+      for (int i=0; i<len; i++) {
+        vtable->Set<false>(i, super_class->GetVTableEntry(i));
+      }
+    } else {
+      CHECK(super_class->GetVTable() != nullptr) << PrettyClass(super_class);
+      vtable = hs.NewHandle(super_class->GetVTable()->CopyOf(self, max_count));
+      if (UNLIKELY(vtable.Get() == nullptr)) {
+        CHECK(self->IsExceptionPending());  // OOME.
+        return false;
+      }
     }
+
     // See if any of our virtual methods override the superclass.
     MethodHelper local_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
     MethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));