Don't store copied methods in BSS.

Otherwise, we can end up in a state where the method on the stack is
unrelated to the receiver.

Also fix a comment related to GetCanonicalMethod and
StackVisitor::ValidateFrame.

Test: 810-checker-invoke-super-default
Change-Id: I3030e4af6059f7a4a7a1f046f2aabae8ce9057da
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index d5840fc..3f6215a 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -23,6 +23,7 @@
 
 #include "android-base/stringprintf.h"
 #include "art_method.h"
+#include "art_method-inl.h"
 #include "base/intrusive_forward_list.h"
 #include "bounds_check_elimination.h"
 #include "builder.h"
@@ -470,6 +471,9 @@
     StartAttributeStream("always_throws") << std::boolalpha
                                           << invoke->AlwaysThrows()
                                           << std::noboolalpha;
+    if (method != nullptr) {
+      StartAttributeStream("method_index") << method->GetMethodIndex();
+    }
   }
 
   void VisitInvokeUnresolved(HInvokeUnresolved* invoke) override {
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index ab28e4b..e9d1ee2 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -964,7 +964,9 @@
       // could resolve the callee to the wrong method.
       return nullptr;
     }
-    resolved_method = actual_method;
+    // Call GetCanonicalMethod in case the resolved method is a copy: for super calls, the encoding
+    // of ArtMethod in BSS relies on not having copies there.
+    resolved_method = actual_method->GetCanonicalMethod(class_linker->GetImagePointerSize());
   }
 
   if (*invoke_type == kInterface) {
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 67cd200..393369d 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -99,6 +99,7 @@
     } else if (!has_method_id) {
       method_load_kind = MethodLoadKind::kRuntimeCall;
     } else {
+      DCHECK(!callee->IsCopied());
       // Use PC-relative access to the .bss methods array.
       method_load_kind = MethodLoadKind::kBssEntry;
     }
@@ -124,6 +125,7 @@
     method_load_kind = MethodLoadKind::kRuntimeCall;
     code_ptr_location = CodePtrLocation::kCallArtMethod;
   } else {
+    DCHECK(!callee->IsCopied());
     // Use PC-relative access to the .bss methods array.
     method_load_kind = MethodLoadKind::kBssEntry;
     code_ptr_location = CodePtrLocation::kCallArtMethod;