Revert "Revert "Check FastInstance() early for special getters and setters.""

This reverts commit 632e458dc267fadfb8120be3ab02701e09e64875.

Change-Id: I5098c41ee84fbbb39397133a7ecfd367fecebe42
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 9f48351..5b9d66c 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -29,6 +29,7 @@
 #include "dex_file-inl.h"
 #include "dex/verification_results.h"
 #include "dex/verified_method.h"
+#include "dex/quick/dex_file_method_inliner.h"
 #include "jni_internal.h"
 #include "object_utils.h"
 #include "runtime.h"
@@ -49,6 +50,7 @@
 #include "thread_pool.h"
 #include "trampolines/trampoline_compiler.h"
 #include "verifier/method_verifier.h"
+#include "verifier/method_verifier-inl.h"
 
 #if defined(ART_USE_PORTABLE_COMPILER)
 #include "elf_writer_mclinker.h"
@@ -995,6 +997,30 @@
                                                 class_loader, NULL, type);
 }
 
+bool CompilerDriver::ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put,
+                                                verifier::MethodVerifier* verifier,
+                                                InlineIGetIPutData* result) {
+  mirror::DexCache* dex_cache = verifier->GetDexCache();
+  uint32_t method_idx = verifier->GetMethodReference().dex_method_index;
+  mirror::ArtMethod* method = dex_cache->GetResolvedMethod(method_idx);
+  mirror::ArtField* field = dex_cache->GetResolvedField(field_idx);
+  if (method == nullptr || field == nullptr) {
+    return false;
+  }
+  mirror::Class* method_class = method->GetDeclaringClass();
+  mirror::Class* field_class = field->GetDeclaringClass();
+  if (!method_class->CanAccessResolvedField(field_class, field, dex_cache, field_idx) ||
+      (is_put && field->IsFinal() && method_class != field_class)) {
+    return false;
+  }
+  DCHECK_GE(field->GetOffset().Int32Value(), 0);
+  result->method_is_static = method->IsStatic();
+  result->field_idx = field_idx;
+  result->field_offset = field->GetOffset().Int32Value();
+  result->is_volatile = field->IsVolatile();
+  return true;
+}
+
 bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
                                               bool is_put, int* field_offset, bool* is_volatile) {
   ScopedObjectAccess soa(Thread::Current());
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 4307212..ea43e4f 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -38,10 +38,15 @@
 
 namespace art {
 
+namespace verifier {
+class MethodVerifier;
+}  // namespace verifier
+
 class AOTCompilationStats;
 class ParallelCompilationManager;
 class DexCompilationUnit;
 class DexFileToMethodInlinerMap;
+class InlineIGetIPutData;
 class OatWriter;
 class TimingLogger;
 class VerificationResults;
@@ -194,6 +199,13 @@
                           bool* is_type_initialized, bool* use_direct_type_ptr,
                           uintptr_t* direct_type_ptr);
 
+  // Can we fast path instance field access in a verified accessor?
+  // If yes, computes field's offset and volatility and whether the method is static or not.
+  static bool ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put,
+                                         verifier::MethodVerifier* verifier,
+                                         InlineIGetIPutData* result)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // Can we fast path instance field access? Computes field's offset and volatility.
   bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
                                 int* field_offset, bool* is_volatile)