Another fix for the resolution trampoline and invokesuper.

We need to fully resolve the target method before updating the BSS.

Test: 811
Bug: 169047229
Change-Id: I2f3a6d60e3e44b00daea4af15c02b55e1c9098d6
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 45c50b0..39987c1 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1317,24 +1317,6 @@
     DCHECK_EQ(caller->GetDexFile(), called_method.dex_file);
     called = linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
         self, called_method.index, caller, invoke_type);
-
-    // If successful, update .bss entry in oat file if any.
-    if (called != nullptr) {
-      // We only put non copied methods in the BSS. Putting a copy can lead to an
-      // odd situation where the ArtMethod being executed is unrelated to the
-      // receiver of the method.
-      called = called->GetCanonicalMethod();
-      if (invoke_type == kSuper) {
-        if (called->GetDexFile() == called_method.dex_file) {
-          called_method.index = called->GetDexMethodIndex();
-        } else {
-          called_method.index = called->FindDexMethodIndexInOtherDexFile(
-              *called_method.dex_file, called_method.index);
-          DCHECK_NE(called_method.index, dex::kDexNoIndex);
-        }
-      }
-      MaybeUpdateBssMethodEntry(called, called_method);
-    }
   }
   const void* code = nullptr;
   if (LIKELY(!self->IsExceptionPending())) {
@@ -1368,6 +1350,24 @@
                                << mirror::Object::PrettyTypeOf(receiver) << " "
                                << invoke_type << " " << orig_called->GetVtableIndex();
     }
+    // Now that we know the actual target, update .bss entry in oat file, if
+    // any.
+    if (!called_method_known_on_entry) {
+      // We only put non copied methods in the BSS. Putting a copy can lead to an
+      // odd situation where the ArtMethod being executed is unrelated to the
+      // receiver of the method.
+      called = called->GetCanonicalMethod();
+      if (invoke_type == kSuper) {
+        if (called->GetDexFile() == called_method.dex_file) {
+          called_method.index = called->GetDexMethodIndex();
+        } else {
+          called_method.index = called->FindDexMethodIndexInOtherDexFile(
+              *called_method.dex_file, called_method.index);
+          DCHECK_NE(called_method.index, dex::kDexNoIndex);
+        }
+      }
+      MaybeUpdateBssMethodEntry(called, called_method);
+    }
 
     // Static invokes need class initialization check but instance invokes can proceed even if
     // the class is erroneous, i.e. in the edge case of escaping instances of erroneous classes.