Revert "CHA for abstract methods."

This reverts commit ae6c189b9d63ca4c2ae0e952187819c5e442e3c9.

This is causing sporadic build failures with:
dex2oatd F 01-20 15:05:33 8343 10164 cha.cc:292] Check failed: method_in_super->HasSingleImplementation() 

Change-Id: I4435ab028d3f7893e18b44347f294326c573a255
diff --git a/runtime/cha.cc b/runtime/cha.cc
index a1ad585..d94b091 100644
--- a/runtime/cha.cc
+++ b/runtime/cha.cc
@@ -185,8 +185,7 @@
 };
 
 void ClassHierarchyAnalysis::VerifyNonSingleImplementation(mirror::Class* verify_class,
-                                                           uint16_t verify_index,
-                                                           ArtMethod* excluded_method) {
+                                                           uint16_t verify_index) {
   // Grab cha_lock_ to make sure all single-implementation updates are seen.
   PointerSize image_pointer_size =
       Runtime::Current()->GetClassLinker()->GetImagePointerSize();
@@ -196,11 +195,9 @@
       return;
     }
     ArtMethod* verify_method = verify_class->GetVTableEntry(verify_index, image_pointer_size);
-    if (verify_method != excluded_method) {
-      DCHECK(!verify_method->HasSingleImplementation())
-          << "class: " << verify_class->PrettyClass()
-          << " verify_method: " << verify_method->PrettyMethod(true);
-    }
+    DCHECK(!verify_method->HasSingleImplementation())
+        << "class: " << verify_class->PrettyClass()
+        << " verify_method: " << verify_method->PrettyMethod(true);
     verify_class = verify_class->GetSuperClass();
   }
 }
@@ -209,152 +206,41 @@
     Handle<mirror::Class> klass,
     ArtMethod* virtual_method,
     ArtMethod* method_in_super,
-    std::unordered_set<ArtMethod*>& invalidated_single_impl_methods,
-    PointerSize pointer_size) {
+    std::unordered_set<ArtMethod*>& invalidated_single_impl_methods) {
   // TODO: if klass is not instantiable, virtual_method isn't invocable yet so
   // even if it overrides, it doesn't invalidate single-implementation
   // assumption.
 
-  DCHECK((virtual_method != method_in_super) || virtual_method->IsAbstract());
+  DCHECK_NE(virtual_method, method_in_super);
   DCHECK(method_in_super->GetDeclaringClass()->IsResolved()) << "class isn't resolved";
   // If virtual_method doesn't come from a default interface method, it should
   // be supplied by klass.
-  DCHECK(virtual_method == method_in_super ||
-         virtual_method->IsCopied() ||
+  DCHECK(virtual_method->IsCopied() ||
          virtual_method->GetDeclaringClass() == klass.Get());
 
-  // To make updating single-implementation flags simple, we always maintain the following
-  // invariant:
-  // Say all virtual methods in the same vtable slot, starting from the bottom child class
-  // to super classes, is a sequence of unique methods m3, m2, m1, ... (after removing duplicate
-  // methods for inherited methods).
-  // For example for the following class hierarchy,
-  //   class A { void m() { ... } }
-  //   class B extends A { void m() { ... } }
-  //   class C extends B {}
-  //   class D extends C { void m() { ... } }
-  // the sequence is D.m(), B.m(), A.m().
-  // The single-implementation status for that sequence of methods begin with one or two true's,
-  // then become all falses. The only case where two true's are possible is for one abstract
-  // method m and one non-abstract method mImpl that overrides method m.
-  // With the invariant, when linking in a new class, we only need to at most update one or
-  // two methods in the sequence for their single-implementation status, in order to maintain
-  // the invariant.
-
+  // A new virtual_method should set method_in_super to
+  // non-single-implementation (if not set already).
+  // We don't grab cha_lock_. Single-implementation flag won't be set to true
+  // again once it's set to false.
   if (!method_in_super->HasSingleImplementation()) {
     // method_in_super already has multiple implementations. All methods in the
     // same vtable slots in its super classes should have
     // non-single-implementation already.
     if (kIsDebugBuild) {
       VerifyNonSingleImplementation(klass->GetSuperClass()->GetSuperClass(),
-                                    method_in_super->GetMethodIndex(),
-                                    nullptr /* excluded_method */);
+                                    method_in_super->GetMethodIndex());
     }
     return;
   }
 
   // Native methods don't have single-implementation flag set.
   DCHECK(!method_in_super->IsNative());
-
-  uint16_t method_index = method_in_super->GetMethodIndex();
-  if (method_in_super->IsAbstract()) {
-    if (kIsDebugBuild) {
-      // An abstract method should have made all methods in the same vtable
-      // slot above it in the class hierarchy having non-single-implementation.
-      mirror::Class* super_super = klass->GetSuperClass()->GetSuperClass();
-      VerifyNonSingleImplementation(super_super,
-                                    method_index,
-                                    method_in_super);
-    }
-
-    if (virtual_method->IsAbstract()) {
-      // SUPER: abstract, VIRTUAL: abstract.
-      if (method_in_super == virtual_method) {
-        DCHECK(klass->IsInstantiable());
-        // An instantiable subclass hasn't provided a concrete implementation of
-        // the abstract method. Invoking method_in_super may throw AbstractMethodError.
-        // This is an uncommon case, so we simply treat method_in_super as not
-        // having single-implementation.
-        invalidated_single_impl_methods.insert(method_in_super);
-        return;
-      } else {
-        // One abstract method overrides another abstract method. This is an uncommon
-        // case. We simply treat method_in_super as not having single-implementation.
-        invalidated_single_impl_methods.insert(method_in_super);
-        return;
-      }
-    } else {
-      // SUPER: abstract, VIRTUAL: non-abstract.
-      // A non-abstract method overrides an abstract method.
-      if (method_in_super->GetSingleImplementation(pointer_size) == nullptr) {
-        // Abstract method_in_super gets its first implementation. Keep it as having
-        // single-implementation and record that single implementation.
-        DCHECK(method_in_super->HasSingleImplementation());
-        method_in_super->SetSingleImplementation(virtual_method, pointer_size);
-        return;
-      } else {
-        // Abstract method_in_super already got one implementation.
-        // Invalidate method_in_super's single-implementation status.
-        invalidated_single_impl_methods.insert(method_in_super);
-        return;
-      }
-    }
-  } else {
-    if (virtual_method->IsAbstract()) {
-      // SUPER: non-abstract, VIRTUAL: abstract.
-      // An abstract method overrides a non-abstract method. This is an uncommon
-      // case, we simply treat both methods as not having single-implementation.
-      invalidated_single_impl_methods.insert(virtual_method);
-      // Fall-through to handle invalidating method_in_super of its
-      // single-implementation status.
-    }
-
-    // SUPER: non-abstract, VIRTUAL: non-abstract/abstract(fall-through from previous if).
-    // Invalidate method_in_super's single-implementation status.
-    invalidated_single_impl_methods.insert(method_in_super);
-
-    // method_in_super might be the single-implementation of another abstract method,
-    // which should be also invalidated of its single-implementation status.
-    mirror::Class* super_super = klass->GetSuperClass()->GetSuperClass();
-    while (super_super != nullptr &&
-           method_index < super_super->GetVTableLength()) {
-      ArtMethod* method_in_super_super = super_super->GetVTableEntry(method_index, pointer_size);
-      if (method_in_super_super != method_in_super) {
-        if (method_in_super_super->IsAbstract()) {
-          if (method_in_super_super->HasSingleImplementation()) {
-            // Invalidate method_in_super's single-implementation status.
-            invalidated_single_impl_methods.insert(method_in_super_super);
-            // No need to further traverse up the class hierarchy since if there
-            // are cases that one abstract method overrides another method, we
-            // should have made that method having non-single-implementation already.
-          } else {
-            // method_in_super_super is already non-single-implementation.
-            // No need to further traverse up the class hierarchy.
-          }
-        } else {
-          DCHECK(!method_in_super_super->HasSingleImplementation());
-          // No need to further traverse up the class hierarchy since two non-abstract
-          // methods (method_in_super and method_in_super_super) should have set all
-          // other methods (abstract or not) in the vtable slot to be non-single-implementation.
-        }
-
-        if (kIsDebugBuild) {
-          VerifyNonSingleImplementation(super_super->GetSuperClass(),
-                                        method_index,
-                                        method_in_super_super);
-        }
-        // No need to go any further.
-        return;
-      } else {
-        super_super = super_super->GetSuperClass();
-      }
-    }
-  }
+  // Invalidate method_in_super's single-implementation status.
+  invalidated_single_impl_methods.insert(method_in_super);
 }
 
 void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> klass,
-                                                          ArtMethod* method,
-                                                          PointerSize pointer_size) {
+                                                          ArtMethod* method) {
   DCHECK(method->IsCopied() || method->GetDeclaringClass() == klass.Get());
   if (klass->IsFinal() || method->IsFinal()) {
     // Final classes or methods do not need CHA for devirtualization.
@@ -367,21 +253,16 @@
     // cannot be inlined. It's not worthwhile to devirtualize the
     // call which can add a deoptimization point.
     DCHECK(!method->HasSingleImplementation());
-  } else if (method->IsAbstract()) {
-    if (method->GetDeclaringClass()->IsInstantiable()) {
-      // Rare case, but we do accept it (such as 800-smali/smali/b_26143249.smali).
-      // Do not attempt to devirtualize it.
-      method->SetHasSingleImplementation(false);
-    } else {
-      // Abstract method starts with single-implementation flag set and null
-      // implementation method.
-      method->SetHasSingleImplementation(true);
-      DCHECK(method->GetSingleImplementation(pointer_size) == nullptr);
-    }
   } else {
     method->SetHasSingleImplementation(true);
-    // Single implementation of non-abstract method is itself.
-    DCHECK_EQ(method->GetSingleImplementation(pointer_size), method);
+    if (method->IsAbstract()) {
+      // There is no real implementation yet.
+      // TODO: implement single-implementation logic for abstract methods.
+      DCHECK(method->GetSingleImplementation() == nullptr);
+    } else {
+      // Single implementation of non-abstract method is itself.
+      DCHECK_EQ(method->GetSingleImplementation(), method);
+    }
   }
 }
 
@@ -405,29 +286,19 @@
     ArtMethod* method_in_super = super_class->GetVTableEntry(i, image_pointer_size);
     if (method == method_in_super) {
       // vtable slot entry is inherited from super class.
-      if (method->IsAbstract() && klass->IsInstantiable()) {
-        // An instantiable class that inherits an abstract method is treated as
-        // supplying an implementation that throws AbstractMethodError.
-        CheckSingleImplementationInfo(klass,
-                                      method,
-                                      method_in_super,
-                                      invalidated_single_impl_methods,
-                                      image_pointer_size);
-      }
       continue;
     }
-    InitSingleImplementationFlag(klass, method, image_pointer_size);
+    InitSingleImplementationFlag(klass, method);
     CheckSingleImplementationInfo(klass,
                                   method,
                                   method_in_super,
-                                  invalidated_single_impl_methods,
-                                  image_pointer_size);
+                                  invalidated_single_impl_methods);
   }
 
   // For new virtual methods that don't override.
   for (int32_t i = super_class->GetVTableLength(); i < klass->GetVTableLength(); ++i) {
     ArtMethod* method = klass->GetVTableEntry(i, image_pointer_size);
-    InitSingleImplementationFlag(klass, method, image_pointer_size);
+    InitSingleImplementationFlag(klass, method);
   }
 
   Runtime* const runtime = Runtime::Current();