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()));
 
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index c3979f3..5ada93f 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -305,10 +305,8 @@
 
   HClinitCheck* ProcessClinitCheckForInvoke(
       uint32_t dex_pc,
-      ArtMethod* method,
       uint32_t method_idx,
-      HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
-      SHARED_REQUIRES(Locks::mutator_lock_);
+      HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement);
 
   // Build a HNewInstance instruction.
   bool BuildNewInstance(uint16_t type_index, uint32_t dex_pc);
@@ -317,10 +315,6 @@
   bool IsInitialized(Handle<mirror::Class> cls) const
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Try to resolve a method using the class linker. Return null if a method could
-  // not be resolved.
-  ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
-
   ArenaAllocator* const arena_;
 
   // A list of the size of the dex code holding block information for
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 0063aef..a98d9c6 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -5943,16 +5943,12 @@
   Register temp = temp_location.AsRegister<Register>();
   uint32_t method_offset = mirror::Class::EmbeddedVTableEntryOffset(
       invoke->GetVTableIndex(), kArmPointerSize).Uint32Value();
-
-  // Use the calling convention instead of the location of the receiver, as
-  // intrinsics may have put the receiver in a different register. In the intrinsics
-  // slow path, the arguments have been moved to the right place, so here we are
-  // guaranteed that the receiver is the first register of the calling convention.
-  InvokeDexCallingConvention calling_convention;
-  Register receiver = calling_convention.GetRegisterAt(0);
+  LocationSummary* locations = invoke->GetLocations();
+  Location receiver = locations->InAt(0);
   uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
+  DCHECK(receiver.IsRegister());
   // /* HeapReference<Class> */ temp = receiver->klass_
-  __ LoadFromOffset(kLoadWord, temp, receiver, class_offset);
+  __ LoadFromOffset(kLoadWord, temp, receiver.AsRegister<Register>(), class_offset);
   MaybeRecordImplicitNullCheck(invoke);
   // Instead of simply (possibly) unpoisoning `temp` here, we should
   // emit a read barrier for the previous class reference load.
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 04acd9d..ac16268 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3618,12 +3618,8 @@
 }
 
 void CodeGeneratorARM64::GenerateVirtualCall(HInvokeVirtual* invoke, Location temp_in) {
-  // Use the calling convention instead of the location of the receiver, as
-  // intrinsics may have put the receiver in a different register. In the intrinsics
-  // slow path, the arguments have been moved to the right place, so here we are
-  // guaranteed that the receiver is the first register of the calling convention.
-  InvokeDexCallingConvention calling_convention;
-  Register receiver = calling_convention.GetRegisterAt(0);
+  LocationSummary* locations = invoke->GetLocations();
+  Location receiver = locations->InAt(0);
   Register temp = XRegisterFrom(temp_in);
   size_t method_offset = mirror::Class::EmbeddedVTableEntryOffset(
       invoke->GetVTableIndex(), kArm64PointerSize).SizeValue();
@@ -3634,10 +3630,11 @@
 
   DCHECK(receiver.IsRegister());
   // /* HeapReference<Class> */ temp = receiver->klass_
-  __ Ldr(temp.W(), HeapOperandFrom(LocationFrom(receiver), class_offset));
+  __ Ldr(temp.W(), HeapOperandFrom(receiver, class_offset));
   MaybeRecordImplicitNullCheck(invoke);
   // Instead of simply (possibly) unpoisoning `temp` here, we should
   // emit a read barrier for the previous class reference load.
+  // However this is not required in practice, as this is an
   // intermediate/temporary reference and because the current
   // concurrent copying collector keeps the from-space memory
   // intact/accessible until the end of the marking phase (the
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index bc5eb31..934f24b 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -2986,13 +2986,8 @@
 }
 
 void CodeGeneratorMIPS64::GenerateVirtualCall(HInvokeVirtual* invoke, Location temp_location) {
-  // Use the calling convention instead of the location of the receiver, as
-  // intrinsics may have put the receiver in a different register. In the intrinsics
-  // slow path, the arguments have been moved to the right place, so here we are
-  // guaranteed that the receiver is the first register of the calling convention.
-  InvokeDexCallingConvention calling_convention;
-  GpuRegister receiver = calling_convention.GetRegisterAt(0);
-
+  LocationSummary* locations = invoke->GetLocations();
+  Location receiver = locations->InAt(0);
   GpuRegister temp = temp_location.AsRegister<GpuRegister>();
   size_t method_offset = mirror::Class::EmbeddedVTableEntryOffset(
       invoke->GetVTableIndex(), kMips64PointerSize).SizeValue();
@@ -3000,7 +2995,8 @@
   Offset entry_point = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kMips64WordSize);
 
   // temp = object->GetClass();
-  __ LoadFromOffset(kLoadUnsignedWord, temp, receiver, class_offset);
+  DCHECK(receiver.IsRegister());
+  __ LoadFromOffset(kLoadUnsignedWord, temp, receiver.AsRegister<GpuRegister>(), class_offset);
   MaybeRecordImplicitNullCheck(invoke);
   // temp = temp->GetMethodAt(method_offset);
   __ LoadFromOffset(kLoadDoubleword, temp, temp, method_offset);
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index a8ed06c..1fc09a8 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1970,11 +1970,6 @@
 }
 
 void LocationsBuilderX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
-  IntrinsicLocationsBuilderX86 intrinsic(codegen_);
-  if (intrinsic.TryDispatch(invoke)) {
-    return;
-  }
-
   HandleInvoke(invoke);
 }
 
@@ -4156,16 +4151,12 @@
   Register temp = temp_in.AsRegister<Register>();
   uint32_t method_offset = mirror::Class::EmbeddedVTableEntryOffset(
       invoke->GetVTableIndex(), kX86PointerSize).Uint32Value();
-
-  // Use the calling convention instead of the location of the receiver, as
-  // intrinsics may have put the receiver in a different register. In the intrinsics
-  // slow path, the arguments have been moved to the right place, so here we are
-  // guaranteed that the receiver is the first register of the calling convention.
-  InvokeDexCallingConvention calling_convention;
-  Register receiver = calling_convention.GetRegisterAt(0);
+  LocationSummary* locations = invoke->GetLocations();
+  Location receiver = locations->InAt(0);
   uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
+  DCHECK(receiver.IsRegister());
   // /* HeapReference<Class> */ temp = receiver->klass_
-  __ movl(temp, Address(receiver, class_offset));
+  __ movl(temp, Address(receiver.AsRegister<Register>(), class_offset));
   MaybeRecordImplicitNullCheck(invoke);
   // Instead of simply (possibly) unpoisoning `temp` here, we should
   // emit a read barrier for the previous class reference load.
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 4618be9..534ee1c 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -802,17 +802,12 @@
   CpuRegister temp = temp_in.AsRegister<CpuRegister>();
   size_t method_offset = mirror::Class::EmbeddedVTableEntryOffset(
       invoke->GetVTableIndex(), kX86_64PointerSize).SizeValue();
-
-  // Use the calling convention instead of the location of the receiver, as
-  // intrinsics may have put the receiver in a different register. In the intrinsics
-  // slow path, the arguments have been moved to the right place, so here we are
-  // guaranteed that the receiver is the first register of the calling convention.
-  InvokeDexCallingConvention calling_convention;
-  Register receiver = calling_convention.GetRegisterAt(0);
-
+  LocationSummary* locations = invoke->GetLocations();
+  Location receiver = locations->InAt(0);
   size_t class_offset = mirror::Object::ClassOffset().SizeValue();
+  DCHECK(receiver.IsRegister());
   // /* HeapReference<Class> */ temp = receiver->klass_
-  __ movl(temp, Address(CpuRegister(receiver), class_offset));
+  __ movl(temp, Address(receiver.AsRegister<CpuRegister>(), class_offset));
   MaybeRecordImplicitNullCheck(invoke);
   // Instead of simply (possibly) unpoisoning `temp` here, we should
   // emit a read barrier for the previous class reference load.
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 2bff213..48bcd10 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -402,11 +402,6 @@
     }
   }
 
-  void VisitInvokeVirtual(HInvokeVirtual* invoke) OVERRIDE {
-    VisitInvoke(invoke);
-    StartAttributeStream("intrinsic") << invoke->GetIntrinsic();
-  }
-
   void VisitUnresolvedInstanceFieldGet(HUnresolvedInstanceFieldGet* field_access) OVERRIDE {
     StartAttributeStream("field_type") << field_access->GetFieldType();
   }
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 6d93be3..0363f20 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -192,10 +192,6 @@
   // We can query the dex cache directly. The verifier has populated it already.
   ArtMethod* resolved_method;
   if (invoke_instruction->IsInvokeStaticOrDirect()) {
-    if (invoke_instruction->AsInvokeStaticOrDirect()->IsStringInit()) {
-      VLOG(compiler) << "Not inlining a String.<init> method";
-      return false;
-    }
     MethodReference ref = invoke_instruction->AsInvokeStaticOrDirect()->GetTargetMethod();
     mirror::DexCache* const dex_cache = (&caller_dex_file == ref.dex_file)
         ? caller_compilation_unit_.GetDexCache().Get()
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 8340811..b01324e 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -384,7 +384,7 @@
   // InvokeStaticOrDirect.
   InvokeType intrinsic_type = GetIntrinsicInvokeType(intrinsic);
   InvokeType invoke_type = invoke->IsInvokeStaticOrDirect() ?
-      invoke->AsInvokeStaticOrDirect()->GetOptimizedInvokeType() :
+      invoke->AsInvokeStaticOrDirect()->GetInvokeType() :
       invoke->IsInvokeVirtual() ? kVirtual : kSuper;
   switch (intrinsic_type) {
     case kStatic:
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 2c2fc8c..d5110a7 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3418,7 +3418,7 @@
                         MethodReference target_method,
                         DispatchInfo dispatch_info,
                         InvokeType original_invoke_type,
-                        InvokeType optimized_invoke_type,
+                        InvokeType invoke_type,
                         ClinitCheckRequirement clinit_check_requirement)
       : HInvoke(arena,
                 number_of_arguments,
@@ -3432,7 +3432,7 @@
                 dex_pc,
                 method_index,
                 original_invoke_type),
-        optimized_invoke_type_(optimized_invoke_type),
+        invoke_type_(invoke_type),
         clinit_check_requirement_(clinit_check_requirement),
         target_method_(target_method),
         dispatch_info_(dispatch_info) { }
@@ -3478,11 +3478,7 @@
   // platform-specific special input, such as PC-relative addressing base.
   uint32_t GetSpecialInputIndex() const { return GetNumberOfArguments(); }
 
-  InvokeType GetOptimizedInvokeType() const { return optimized_invoke_type_; }
-  void SetOptimizedInvokeType(InvokeType invoke_type) {
-    optimized_invoke_type_ = invoke_type;
-  }
-
+  InvokeType GetInvokeType() const { return invoke_type_; }
   MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; }
   CodePtrLocation GetCodePtrLocation() const { return dispatch_info_.code_ptr_location; }
   bool IsRecursive() const { return GetMethodLoadKind() == MethodLoadKind::kRecursive; }
@@ -3505,7 +3501,6 @@
   }
   bool HasDirectCodePtr() const { return GetCodePtrLocation() == CodePtrLocation::kCallDirect; }
   MethodReference GetTargetMethod() const { return target_method_; }
-  void SetTargetMethod(MethodReference method) { target_method_ = method; }
 
   int32_t GetStringInitOffset() const {
     DCHECK(IsStringInit());
@@ -3531,7 +3526,7 @@
 
   // Is this instruction a call to a static method?
   bool IsStatic() const {
-    return GetOriginalInvokeType() == kStatic;
+    return GetInvokeType() == kStatic;
   }
 
   // Remove the HClinitCheck or the replacement HLoadClass (set as last input by
@@ -3604,7 +3599,7 @@
   void RemoveInputAt(size_t index);
 
  private:
-  InvokeType optimized_invoke_type_;
+  const InvokeType invoke_type_;
   ClinitCheckRequirement clinit_check_requirement_;
   // The target method may refer to different dex file or method index than the original
   // invoke. This happens for sharpened calls and for calls where a method was redeclared
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 5e1d1d9..a128079 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -49,8 +49,7 @@
   }
 
   // TODO: Avoid CompilerDriver.
-  InvokeType original_invoke_type = invoke->GetOriginalInvokeType();
-  InvokeType optimized_invoke_type = original_invoke_type;
+  InvokeType invoke_type = invoke->GetOriginalInvokeType();
   MethodReference target_method(&graph_->GetDexFile(), invoke->GetDexMethodIndex());
   int vtable_idx;
   uintptr_t direct_code, direct_method;
@@ -59,18 +58,15 @@
       invoke->GetDexPc(),
       false /* update_stats: already updated in builder */,
       true /* enable_devirtualization */,
-      &optimized_invoke_type,
+      &invoke_type,
       &target_method,
       &vtable_idx,
       &direct_code,
       &direct_method);
-  if (!success) {
-    // TODO: try using kDexCachePcRelative. It's always a valid method load
-    // kind as long as it's supported by the codegen
-    return;
-  }
-  invoke->SetOptimizedInvokeType(optimized_invoke_type);
-  invoke->SetTargetMethod(target_method);
+  DCHECK(success);
+  DCHECK_EQ(invoke_type, invoke->GetInvokeType());
+  DCHECK_EQ(target_method.dex_file, invoke->GetTargetMethod().dex_file);
+  DCHECK_EQ(target_method.dex_method_index, invoke->GetTargetMethod().dex_method_index);
 
   HInvokeStaticOrDirect::MethodLoadKind method_load_kind;
   HInvokeStaticOrDirect::CodePtrLocation code_ptr_location;