Allow one method to override multiple superclass methods.

Test: New test 182-method-linking.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --jvm
Bug: 211854716
Change-Id: I1034ccc5b775b35fe4cc4f815c693d348bbe76b8
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 7f2d926..d1de4ba 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -7533,6 +7533,13 @@
   ArenaStack stack_;
   ScopedArenaAllocator allocator_;
 
+  // If there are multiple methods with the same signature in the superclass vtable
+  // (which can happen with a new virtual method having the same signature as an
+  // inaccessible package-private method from another package in the superclass),
+  // we keep singly-linked lists in this single array that maps vtable index to the
+  // next vtable index in the list, `dex::kDexNoIndex` denotes the end of a list.
+  ArrayRef<uint32_t> same_signature_vtable_lists_;
+
   // Avoid large allocation for a few copied method records.
   // Keep the initial buffer on the stack to avoid arena allocations
   // if there are no special cases (the first arena allocation is costly).
@@ -7971,6 +7978,7 @@
           same_signature_vtable_lists = ArrayRef<uint32_t>(
               allocator_.AllocArray<uint32_t>(super_vtable_length), super_vtable_length);
           std::fill_n(same_signature_vtable_lists.data(), super_vtable_length, dex::kDexNoIndex);
+          same_signature_vtable_lists_ = same_signature_vtable_lists;
         }
         DCHECK_LT(*it, i);
         same_signature_vtable_lists[i] = *it;
@@ -8008,9 +8016,18 @@
       // superclass method would have been incorrectly overridden.
       bool overrides = klass->CanAccessMember(super_method->GetDeclaringClass(),
                                               super_method->GetAccessFlags());
+      if (overrides && super_method->IsFinal()) {
+        sants.reset();
+        ThrowLinkageError(klass, "Method %s overrides final method in class %s",
+                          virtual_method->PrettyMethod().c_str(),
+                          super_method->GetDeclaringClassDescriptor());
+        return 0u;
+      }
       if (UNLIKELY(!same_signature_vtable_lists.empty())) {
-        // We override only the first accessible virtual method from superclass.
-        // TODO: Override all methods that need to be overridden according to JLS. b/211854716
+        // We may override more than one method according to JLS, see b/211854716 .
+        // We record the highest overridden vtable index here so that we can walk
+        // the list to find other overridden methods when constructing the vtable.
+        // However, we walk all the methods to check for final method overriding.
         size_t current_index = super_index;
         while (same_signature_vtable_lists[current_index] != dex::kDexNoIndex) {
           DCHECK_LT(same_signature_vtable_lists[current_index], current_index);
@@ -8018,20 +8035,22 @@
           ArtMethod* current_method = super_vtable_accessor.GetVTableEntry(current_index);
           if (klass->CanAccessMember(current_method->GetDeclaringClass(),
                                      current_method->GetAccessFlags())) {
-            overrides = true;
-            super_index = current_index;
-            super_method = current_method;
+            if (current_method->IsFinal()) {
+              sants.reset();
+              ThrowLinkageError(klass, "Method %s overrides final method in class %s",
+                                virtual_method->PrettyMethod().c_str(),
+                                current_method->GetDeclaringClassDescriptor());
+              return 0u;
+            }
+            if (!overrides) {
+              overrides = true;
+              super_index = current_index;
+              super_method = current_method;
+            }
           }
         }
       }
       if (overrides) {
-        if (super_method->IsFinal()) {
-          sants.reset();
-          ThrowLinkageError(klass, "Method %s overrides final method in class %s",
-                            virtual_method->PrettyMethod().c_str(),
-                            super_method->GetDeclaringClassDescriptor());
-          return 0u;
-        }
         virtual_method->SetMethodIndex(super_index);
         continue;
       }
@@ -8426,9 +8445,25 @@
     }
 
     // Store new virtual methods in the new vtable.
+    ArrayRef<uint32_t> same_signature_vtable_lists = same_signature_vtable_lists_;
     for (ArtMethod& virtual_method : klass->GetVirtualMethodsSliceUnchecked(kPointerSize)) {
-      int32_t vtable_index = virtual_method.GetMethodIndexDuringLinking();
+      uint32_t vtable_index = virtual_method.GetMethodIndexDuringLinking();
       vtable->SetElementPtrSize(vtable_index, &virtual_method, kPointerSize);
+      if (UNLIKELY(vtable_index < same_signature_vtable_lists.size())) {
+        // We may override more than one method according to JLS, see b/211854716 .
+        // If we do, arbitrarily update the method index to the lowest overridden vtable index.
+        while (same_signature_vtable_lists[vtable_index] != dex::kDexNoIndex) {
+          DCHECK_LT(same_signature_vtable_lists[vtable_index], vtable_index);
+          vtable_index = same_signature_vtable_lists[vtable_index];
+          ArtMethod* current_method = super_class->GetVTableEntry(vtable_index, kPointerSize);
+          if (klass->CanAccessMember(current_method->GetDeclaringClass(),
+                                     current_method->GetAccessFlags())) {
+            DCHECK(!current_method->IsFinal());
+            vtable->SetElementPtrSize(vtable_index, &virtual_method, kPointerSize);
+            virtual_method.SetMethodIndex(vtable_index);
+          }
+        }
+      }
     }
 
     // For non-overridden vtable slots, copy a method from `super_class`.