Move mapping table and vmap table offsets to OatMethodHeader.

This change has a libcore/ companion CL
  "Remove ArtMethod's quick fields mapping table and vmap table."
  https://android-review.googlesource.com/91254

Bug: 11767815
Change-Id: I46ce2067e1ecd915da3890606498e31ffc332813
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 5d62b88..6e1f062 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -78,13 +78,11 @@
 
 inline uint32_t ArtMethod::GetCodeSize() {
   DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
-  uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
-  if (code == 0) {
-    return 0;
+  const void* code = EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode());
+  if (code == nullptr) {
+    return 0u;
   }
-  // TODO: make this Thumb2 specific
-  code &= ~0x1;
-  return reinterpret_cast<OatMethodHeader*>(code)[-1].code_size_;
+  return reinterpret_cast<const OatMethodHeader*>(code)[-1].code_size_;
 }
 
 inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
@@ -124,7 +122,8 @@
     return;
   }
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  if (code == GetQuickResolutionTrampoline(class_linker)) {
+  if (code == GetQuickResolutionTrampoline(class_linker) ||
+      code == GetQuickToInterpreterBridgeTrampoline(class_linker)) {
     return;
   }
   DCHECK(IsWithinQuickCode(pc))
@@ -154,26 +153,6 @@
   SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset));
 }
 
-inline uint32_t ArtMethod::GetOatMappingTableOffset() {
-  DCHECK(!Runtime::Current()->IsStarted());
-  return PointerToLowMemUInt32(GetMappingTable());
-}
-
-inline void ArtMethod::SetOatMappingTableOffset(uint32_t mapping_table_offset) {
-  DCHECK(!Runtime::Current()->IsStarted());
-  SetMappingTable(reinterpret_cast<const uint8_t*>(mapping_table_offset));
-}
-
-inline uint32_t ArtMethod::GetOatVmapTableOffset() {
-  DCHECK(!Runtime::Current()->IsStarted());
-  return PointerToLowMemUInt32(GetVmapTable());
-}
-
-inline void ArtMethod::SetOatVmapTableOffset(uint32_t vmap_table_offset) {
-  DCHECK(!Runtime::Current()->IsStarted());
-  SetVmapTable(reinterpret_cast<uint8_t*>(vmap_table_offset));
-}
-
 inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
   DCHECK(!Runtime::Current()->IsStarted());
   SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index ee5a0a4..8da57bd 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -374,5 +374,43 @@
   RegisterNative(self, GetJniDlsymLookupStub(), false);
 }
 
+const void* ArtMethod::GetOatCodePointer() {
+  if (IsPortableCompiled() || IsNative() || IsAbstract() || IsRuntimeMethod() || IsProxyMethod()) {
+    return nullptr;
+  }
+  Runtime* runtime = Runtime::Current();
+  const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this);
+  // On failure, instead of nullptr we get the quick-to-interpreter-bridge (but not the trampoline).
+  DCHECK(entry_point != GetQuickToInterpreterBridgeTrampoline(runtime->GetClassLinker()));
+  if (entry_point == GetQuickToInterpreterBridge()) {
+    return nullptr;
+  }
+  return EntryPointToCodePointer(entry_point);
+}
+
+const uint8_t* ArtMethod::GetMappingTable() {
+  const void* code = GetOatCodePointer();
+  if (code == nullptr) {
+    return nullptr;
+  }
+  uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].mapping_table_offset_;
+  if (UNLIKELY(offset == 0u)) {
+    return nullptr;
+  }
+  return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
+const uint8_t* ArtMethod::GetVmapTable() {
+  const void* code = GetOatCodePointer();
+  if (code == nullptr) {
+    return nullptr;
+  }
+  uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].vmap_table_offset_;
+  if (UNLIKELY(offset == 0u)) {
+    return nullptr;
+  }
+  return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
 }  // namespace mirror
 }  // namespace art
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index ee23c40..8d2c39c 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -21,6 +21,7 @@
 #include "dex_file.h"
 #include "invoke_type.h"
 #include "modifiers.h"
+#include "oat.h"
 #include "object.h"
 #include "object_callbacks.h"
 
@@ -261,7 +262,6 @@
         EntryPointFromQuickCompiledCodeOffset(), entry_point_from_quick_compiled_code, false);
   }
 
-
   uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool IsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -286,37 +286,20 @@
   void SetQuickOatCodeOffset(uint32_t code_offset);
   void SetPortableOatCodeOffset(uint32_t code_offset);
 
+  static const void* EntryPointToCodePointer(const void* entry_point) ALWAYS_INLINE {
+    uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
+    code &= ~0x1;  // TODO: Make this Thumb2 specific.
+    return reinterpret_cast<const void*>(code);
+  }
+
+  // Actual pointer to compiled oat code or nullptr.
+  const void* GetOatCodePointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
-  const uint8_t* GetMappingTable() {
-    return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_),
-        false);
-  }
-
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  void SetMappingTable(const uint8_t* mapping_table) {
-    SetFieldPtr<false, true, kVerifyFlags>(
-        OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_), mapping_table, false);
-  }
-
-  uint32_t GetOatMappingTableOffset();
-
-  void SetOatMappingTableOffset(uint32_t mapping_table_offset);
+  const uint8_t* GetMappingTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
-  const uint8_t* GetVmapTable() {
-    return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_),
-        false);
-  }
-
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  void SetVmapTable(const uint8_t* vmap_table) {
-    SetFieldPtr<false, true, kVerifyFlags>(
-        OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_), vmap_table, false);
-  }
-
-  uint32_t GetOatVmapTableOffset();
-
-  void SetOatVmapTableOffset(uint32_t vmap_table_offset);
+  const uint8_t* GetVmapTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   const uint8_t* GetNativeGcMap() {
     return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), false);
@@ -468,20 +451,6 @@
   // offsets for the quick compiler and dex PCs for the portable.
   uint64_t gc_map_;
 
-  // --- Quick compiler meta-data. ---
-  // TODO: merge and place in native heap, such as done with the code size.
-
-  // Pointer to a data structure created by the quick compiler to map between dex PCs and native
-  // PCs, and vice-versa.
-  uint64_t quick_mapping_table_;
-
-  // When a register is promoted into a register, the spill mask holds which registers hold dex
-  // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
-  // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
-  uint64_t quick_vmap_table_;
-
-  // --- End of quick compiler meta-data. ---
-
   // Access flags; low 16 bits are defined by spec.
   uint32_t access_flags_;