Revert "Revert "Add JIT""

Added missing EntryPointToCodePointer.

This reverts commit a5ca888d715cd0c6c421313211caa1928be3e399.

Change-Id: Ia74df0ef3a7babbdcb0466fd24da28e304e3f5af
diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc
index b234950..3d3d979 100644
--- a/compiler/dex/mir_method_info.cc
+++ b/compiler/dex/mir_method_info.cc
@@ -33,51 +33,103 @@
     DCHECK(method_infos != nullptr);
     DCHECK_NE(count, 0u);
     for (auto it = method_infos, end = method_infos + count; it != end; ++it) {
-      MirMethodLoweringInfo unresolved(it->MethodIndex(), it->GetInvokeType());
+      MirMethodLoweringInfo unresolved(it->MethodIndex(), it->GetInvokeType(), it->IsQuickened());
+      unresolved.declaring_dex_file_ = it->declaring_dex_file_;
+      unresolved.vtable_idx_ = it->vtable_idx_;
       if (it->target_dex_file_ != nullptr) {
         unresolved.target_dex_file_ = it->target_dex_file_;
         unresolved.target_method_idx_ = it->target_method_idx_;
       }
-      DCHECK_EQ(memcmp(&unresolved, &*it, sizeof(*it)), 0);
+      if (kIsDebugBuild) {
+        unresolved.CheckEquals(*it);
+      }
     }
   }
 
   // We're going to resolve methods and check access in a tight loop. It's better to hold
   // the lock and needed references once than re-acquiring them again and again.
   ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<3> hs(soa.Self());
+  StackHandleScope<4> hs(soa.Self());
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(compiler_driver->GetDexCache(mUnit)));
   Handle<mirror::ClassLoader> class_loader(
       hs.NewHandle(compiler_driver->GetClassLoader(soa, mUnit)));
   Handle<mirror::Class> referrer_class(hs.NewHandle(
       compiler_driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit)));
+  auto current_dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
   // Even if the referrer class is unresolved (i.e. we're compiling a method without class
   // definition) we still want to resolve methods and record all available info.
+  const DexFile* const dex_file = mUnit->GetDexFile();
+  const bool use_jit = Runtime::Current()->UseJit();
+  const VerifiedMethod* const verified_method = mUnit->GetVerifiedMethod();
 
   for (auto it = method_infos, end = method_infos + count; it != end; ++it) {
+    // For quickened invokes, the dex method idx is actually the mir offset.
+    if (it->IsQuickened()) {
+      const auto* dequicken_ref = verified_method->GetDequickenIndex(it->method_idx_);
+      CHECK(dequicken_ref != nullptr);
+      it->target_dex_file_ = dequicken_ref->dex_file;
+      it->target_method_idx_ = dequicken_ref->index;
+    }
     // Remember devirtualized invoke target and set the called method to the default.
     MethodReference devirt_ref(it->target_dex_file_, it->target_method_idx_);
     MethodReference* devirt_target = (it->target_dex_file_ != nullptr) ? &devirt_ref : nullptr;
-    it->target_dex_file_ = mUnit->GetDexFile();
-    it->target_method_idx_ = it->MethodIndex();
-
     InvokeType invoke_type = it->GetInvokeType();
-    mirror::ArtMethod* resolved_method =
-        compiler_driver->ResolveMethod(soa, dex_cache, class_loader, mUnit, it->MethodIndex(),
-                                       invoke_type);
+    mirror::ArtMethod* resolved_method = nullptr;
+    if (!it->IsQuickened()) {
+      it->target_dex_file_ = dex_file;
+      it->target_method_idx_ = it->MethodIndex();
+      current_dex_cache.Assign(dex_cache.Get());
+      resolved_method = compiler_driver->ResolveMethod(soa, dex_cache, class_loader, mUnit,
+                                                       it->MethodIndex(), invoke_type);
+    } else {
+      // The method index is actually the dex PC in this case.
+      // Calculate the proper dex file and target method idx.
+      CHECK(use_jit);
+      CHECK_EQ(invoke_type, kVirtual);
+      // Don't devirt if we are in a different dex file since we can't have direct invokes in
+      // another dex file unless we always put a direct / patch pointer.
+      devirt_target = nullptr;
+      current_dex_cache.Assign(
+          Runtime::Current()->GetClassLinker()->FindDexCache(*it->target_dex_file_));
+      CHECK(current_dex_cache.Get() != nullptr);
+      DexCompilationUnit cu(
+          mUnit->GetCompilationUnit(), mUnit->GetClassLoader(), mUnit->GetClassLinker(),
+          *it->target_dex_file_, nullptr /* code_item not used */, 0u /* class_def_idx not used */,
+          it->target_method_idx_, 0u /* access_flags not used */,
+          nullptr /* verified_method not used */);
+      resolved_method = compiler_driver->ResolveMethod(soa, current_dex_cache, class_loader, &cu,
+                                                       it->target_method_idx_, invoke_type, false);
+      if (resolved_method != nullptr) {
+        // Since this was a dequickened virtual, it is guaranteed to be resolved. However, it may be
+        // resolved to an interface method. If this is the case then change the invoke type to
+        // interface with the assumption that sharp_type will be kVirtual.
+        if (resolved_method->GetInvokeType() == kInterface) {
+          it->flags_ = (it->flags_ & ~(kInvokeTypeMask << kBitInvokeTypeBegin)) |
+              (static_cast<uint16_t>(kInterface) << kBitInvokeTypeBegin);
+        }
+      }
+    }
     if (UNLIKELY(resolved_method == nullptr)) {
       continue;
     }
     compiler_driver->GetResolvedMethodDexFileLocation(resolved_method,
         &it->declaring_dex_file_, &it->declaring_class_idx_, &it->declaring_method_idx_);
-    it->vtable_idx_ = compiler_driver->GetResolvedMethodVTableIndex(resolved_method, invoke_type);
+    if (!it->IsQuickened()) {
+      // For quickened invoke virtuals we may have desharpened to an interface method which
+      // wont give us the right method index, in this case blindly dispatch or else we can't
+      // compile the method. Converting the invoke to interface dispatch doesn't work since we
+      // have no way to get the dex method index for quickened invoke virtuals in the interface
+      // trampolines.
+      it->vtable_idx_ =
+          compiler_driver->GetResolvedMethodVTableIndex(resolved_method, invoke_type);
+    }
 
-    MethodReference target_method(mUnit->GetDexFile(), it->MethodIndex());
+    MethodReference target_method(it->target_dex_file_, it->target_method_idx_);
     int fast_path_flags = compiler_driver->IsFastInvoke(
-        soa, dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method, &invoke_type,
-        &target_method, devirt_target, &it->direct_code_, &it->direct_method_);
-    bool is_referrers_class = (referrer_class.Get() == resolved_method->GetDeclaringClass());
-    bool is_class_initialized =
+        soa, dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method,
+        &invoke_type, &target_method, devirt_target, &it->direct_code_, &it->direct_method_);
+    const bool is_referrers_class = referrer_class.Get() == resolved_method->GetDeclaringClass();
+    const bool is_class_initialized =
         compiler_driver->IsMethodsClassInitialized(referrer_class.Get(), resolved_method);
     uint16_t other_flags = it->flags_ &
         ~(kFlagFastPath | kFlagClassIsInitialized | (kInvokeTypeMask << kBitSharpTypeBegin));