Revert "Don't use the compiler driver for method resolution."

Fails 425 in debuggable mode.

This reverts commit 4db0bf9c4db6a09716c3388b7d2f88d534470339.

Change-Id: I346df8f75674564fc4fb241c60f23e250fc7f0a7
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 8e75bdc..d7754e8 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -735,79 +735,6 @@
   }
 }
 
-ArtMethod* HGraphBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) {
-  ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<2> hs(soa.Self());
-
-  ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker();
-  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
-      soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
-  Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass()));
-
-  ArtMethod* resolved_method = class_linker->ResolveMethod(
-      *dex_compilation_unit_->GetDexFile(),
-      method_idx,
-      dex_compilation_unit_->GetDexCache(),
-      class_loader,
-      /* referrer */ nullptr,
-      invoke_type);
-
-  if (UNLIKELY(resolved_method == nullptr)) {
-    // Clean up any exception left by type resolution.
-    soa.Self()->ClearException();
-    return nullptr;
-  }
-
-  // Check access. The class linker has a fast path for looking into the dex cache
-  // and does not check the access if it hits it.
-  if (compiling_class.Get() == nullptr) {
-    if (!resolved_method->IsPublic()) {
-      return nullptr;
-    }
-  } else if (!compiling_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
-                                                       resolved_method,
-                                                       dex_compilation_unit_->GetDexCache().Get(),
-                                                       method_idx)) {
-    return nullptr;
-  }
-
-  // We have to special case the invoke-super case, as ClassLinker::ResolveMethod does not.
-  // We need to look at the referrer's super class vtable.
-  if (invoke_type == kSuper) {
-    if (compiling_class.Get() == nullptr) {
-      // Invoking a super method requires knowing the actual super class. If we did not resolve
-      // the compiling method's declaring class (which only happens for ahead of time compilation),
-      // bail out.
-      DCHECK(Runtime::Current()->IsAotCompiler());
-      return nullptr;
-    }
-    uint16_t vtable_index = resolved_method->GetMethodIndex();
-    ArtMethod* actual_method = compiling_class->GetSuperClass()->GetVTableEntry(
-        vtable_index, class_linker->GetImagePointerSize());
-    if (actual_method != resolved_method &&
-        !IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) {
-      // TODO: The actual method could still be referenced in the current dex file, so we
-      // could try locating it.
-      // TODO: Remove the dex_file restriction.
-      return nullptr;
-    }
-    if (!actual_method->IsInvokable()) {
-      // Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub
-      // could resolve the callee to the wrong method.
-      return nullptr;
-    }
-    resolved_method = actual_method;
-  }
-
-  // Check for incompatible class changes. The class linker has a fast path for
-  // looking into the dex cache and does not check incompatible class changes if it hits it.
-  if (resolved_method->CheckIncompatibleClassChange(invoke_type)) {
-    return nullptr;
-  }
-
-  return resolved_method;
-}
-
 bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
                                 uint32_t dex_pc,
                                 uint32_t method_idx,
@@ -815,18 +742,22 @@
                                 bool is_range,
                                 uint32_t* args,
                                 uint32_t register_index) {
-  InvokeType invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode());
+  InvokeType original_invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode());
+  InvokeType optimized_invoke_type = original_invoke_type;
   const char* descriptor = dex_file_->GetMethodShorty(method_idx);
   Primitive::Type return_type = Primitive::GetType(descriptor[0]);
 
   // Remove the return type from the 'proto'.
   size_t number_of_arguments = strlen(descriptor) - 1;
-  if (invoke_type != kStatic) {  // instance call
+  if (original_invoke_type != kStatic) {  // instance call
     // One extra argument for 'this'.
     number_of_arguments++;
   }
 
   MethodReference target_method(dex_file_, method_idx);
+  int32_t table_index = 0;
+  uintptr_t direct_code = 0;
+  uintptr_t direct_method = 0;
 
   // Special handling for string init.
   int32_t string_init_offset = 0;
@@ -849,7 +780,7 @@
         method_idx,
         target_method,
         dispatch_info,
-        invoke_type,
+        original_invoke_type,
         kStatic /* optimized_invoke_type */,
         HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
     return HandleStringInit(invoke,
@@ -860,16 +791,23 @@
                             descriptor);
   }
 
-  ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type);
-
-  if (resolved_method == nullptr) {
+  // Handle unresolved methods.
+  if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_,
+                                           dex_pc,
+                                           true /* update_stats */,
+                                           true /* enable_devirtualization */,
+                                           &optimized_invoke_type,
+                                           &target_method,
+                                           &table_index,
+                                           &direct_code,
+                                           &direct_method)) {
     MaybeRecordStat(MethodCompilationStat::kUnresolvedMethod);
     HInvoke* invoke = new (arena_) HInvokeUnresolved(arena_,
                                                      number_of_arguments,
                                                      return_type,
                                                      dex_pc,
                                                      method_idx,
-                                                     invoke_type);
+                                                     original_invoke_type);
     return HandleInvoke(invoke,
                         number_of_vreg_arguments,
                         args,
@@ -879,26 +817,21 @@
                         nullptr /* clinit_check */);
   }
 
+  // Handle resolved methods (non string init).
+
+  DCHECK(optimized_invoke_type != kSuper);
+
   // Potential class initialization check, in the case of a static method call.
   HClinitCheck* clinit_check = nullptr;
   HInvoke* invoke = nullptr;
 
-  if (invoke_type == kDirect || invoke_type == kStatic || invoke_type == kSuper) {
+  if (optimized_invoke_type == kDirect || optimized_invoke_type == kStatic) {
     // By default, consider that the called method implicitly requires
     // an initialization check of its declaring method.
     HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement
         = HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit;
-    ScopedObjectAccess soa(Thread::Current());
-    if (invoke_type == kStatic) {
-      clinit_check = ProcessClinitCheckForInvoke(
-          dex_pc, resolved_method, method_idx, &clinit_check_requirement);
-    } else if (invoke_type == kSuper) {
-      if (IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) {
-        // Update the target method to the one resolved. Note that this may be a no-op if
-        // we resolved to the method referenced by the instruction.
-        method_idx = resolved_method->GetDexMethodIndex();
-        target_method = MethodReference(dex_file_, method_idx);
-      }
+    if (optimized_invoke_type == kStatic) {
+      clinit_check = ProcessClinitCheckForInvoke(dex_pc, method_idx, &clinit_check_requirement);
     }
 
     HInvokeStaticOrDirect::DispatchInfo dispatch_info = {
@@ -914,26 +847,24 @@
                                                 method_idx,
                                                 target_method,
                                                 dispatch_info,
-                                                invoke_type,
-                                                invoke_type,
+                                                original_invoke_type,
+                                                optimized_invoke_type,
                                                 clinit_check_requirement);
-  } else if (invoke_type == kVirtual) {
-    ScopedObjectAccess soa(Thread::Current());  // Needed for the method index
+  } else if (optimized_invoke_type == kVirtual) {
     invoke = new (arena_) HInvokeVirtual(arena_,
                                          number_of_arguments,
                                          return_type,
                                          dex_pc,
                                          method_idx,
-                                         resolved_method->GetMethodIndex());
+                                         table_index);
   } else {
-    DCHECK_EQ(invoke_type, kInterface);
-    ScopedObjectAccess soa(Thread::Current());  // Needed for the method index
+    DCHECK_EQ(optimized_invoke_type, kInterface);
     invoke = new (arena_) HInvokeInterface(arena_,
                                            number_of_arguments,
                                            return_type,
                                            dex_pc,
                                            method_idx,
-                                           resolved_method->GetDexMethodIndex());
+                                           table_index);
   }
 
   return HandleInvoke(invoke,
@@ -1031,18 +962,23 @@
 
 HClinitCheck* HGraphBuilder::ProcessClinitCheckForInvoke(
       uint32_t dex_pc,
-      ArtMethod* resolved_method,
       uint32_t method_idx,
       HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement) {
-  const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
-  Thread* self = Thread::Current();
-  StackHandleScope<4> hs(self);
+  ScopedObjectAccess soa(Thread::Current());
+  StackHandleScope<5> hs(soa.Self());
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(
       dex_compilation_unit_->GetClassLinker()->FindDexCache(
-          self, *dex_compilation_unit_->GetDexFile())));
+          soa.Self(), *dex_compilation_unit_->GetDexFile())));
+  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
+      soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
+  ArtMethod* resolved_method = compiler_driver_->ResolveMethod(
+      soa, dex_cache, class_loader, dex_compilation_unit_, method_idx, InvokeType::kStatic);
+
+  DCHECK(resolved_method != nullptr);
+
+  const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
   Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle(
-      outer_compilation_unit_->GetClassLinker()->FindDexCache(
-          self, outer_dex_file)));
+      outer_compilation_unit_->GetClassLinker()->FindDexCache(soa.Self(), outer_dex_file)));
   Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
   Handle<mirror::Class> resolved_method_class(hs.NewHandle(resolved_method->GetDeclaringClass()));