Enable devirtualization for abstract and sub-class methods.

If we know the type of a receiver in the verifier we record devirtualization
data. Currently we only use this data to avoid virtual method dispatch when
we know the receiver of a method isn't a sub-class. This change allows
devirtualization of virtual and interface methods when we know the receiver's
type and the method the we'd find via dispatch is either known within boot or
has a reference from the current dex file.

Pass the receiver through to the method resolution trampoline as
devirtualization may mean the dex method index needs to be made more accurate
for the receiver.

Tidy up method devirtualization and related statistics.

Push the devirtualization map lookup into a less common case to avoid
taking its lock.

Make MethodReference a struct rather than a typedef of a pair, so the members
can have more meaningful names than first and second.

Rough statistics show that we devirtualize using this change around 2.5% of
the time, whilst some apps like GMS core devirtualize over 3.4% of the time.

Change-Id: Ieed3471dbedfc4cc881d652631b67176bb37d394
diff --git a/src/compiler/dex/mir_dataflow.cc b/src/compiler/dex/mir_dataflow.cc
index 9f61d73..f65c9ae 100644
--- a/src/compiler/dex/mir_dataflow.cc
+++ b/src/compiler/dex/mir_dataflow.cc
@@ -1237,17 +1237,17 @@
       return false;
   }
   DexCompilationUnit m_unit(cu_);
-  // TODO: add a flag so we don't counts the stats for this twice
-  uint32_t dex_method_idx = mir->dalvikInsn.vB;
+  CompilerDriver::MethodReference target_method(cu_->dex_file, mir->dalvikInsn.vB);
   int vtable_idx;
   uintptr_t direct_code;
   uintptr_t direct_method;
   uint32_t current_offset = static_cast<uint32_t>(current_offset_);
   bool fast_path =
-      cu_->compiler_driver->ComputeInvokeInfo(dex_method_idx, current_offset,
-                                              &m_unit, type,
-                                              vtable_idx, direct_code,
-                                              direct_method) &&
+      cu_->compiler_driver->ComputeInvokeInfo(&m_unit, current_offset,
+                                              type, target_method,
+                                              vtable_idx,
+                                              direct_code, direct_method,
+                                              false) &&
                                               !(cu_->enable_debug & (1 << kDebugSlowInvokePath));
   return (((type == kDirect) || (type == kStatic)) &&
           fast_path && ((direct_code == 0) || (direct_method == 0)));