Improve performance of invokevirtual/invokeinterface with embedded imt/vtable

Add an embedded version of imt/vtable into class object. Both tables start at
fixed offset within class object so method/entry point can be loaded directly
from class object for invokeinterface/invokevirtual.

Bug: 8142917
Change-Id: I4240d58cfbe9250107c95c0708c036854c455968
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 8fcacc2..a5b5df6 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -21,14 +21,29 @@
 
 #include "dex_file.h"
 #include "entrypoints/entrypoint_utils.h"
+#include "object-inl.h"
 #include "object_array.h"
+#include "object_utils.h"
 #include "oat.h"
 #include "quick/quick_method_frame_info.h"
+#include "read_barrier-inl.h"
 #include "runtime-inl.h"
 
 namespace art {
 namespace mirror {
 
+inline uint32_t ArtMethod::ClassSize() {
+  uint32_t vtable_entries = Object::kVTableLength + 8;
+  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0);
+}
+
+template<ReadBarrierOption kReadBarrierOption>
+inline Class* ArtMethod::GetJavaLangReflectArtMethod() {
+  DCHECK(java_lang_reflect_ArtMethod_ != nullptr);
+  return ReadBarrier::BarrierForRoot<mirror::Class, kReadBarrierOption>(
+      &java_lang_reflect_ArtMethod_);
+}
+
 inline Class* ArtMethod::GetDeclaringClass() {
   Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_));
   DCHECK(result != NULL) << this;
@@ -122,8 +137,8 @@
     return;
   }
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  if (code == GetQuickResolutionTrampoline(class_linker) ||
-      code == GetQuickToInterpreterBridgeTrampoline(class_linker)) {
+  if (code == class_linker->GetQuickResolutionTrampoline() ||
+      code == class_linker->GetQuickToInterpreterBridgeTrampoline()) {
     return;
   }
   DCHECK(IsWithinQuickCode(pc))
@@ -162,7 +177,7 @@
   // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method
   // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline)
   // for non-native methods.
-  DCHECK(entry_point != GetQuickToInterpreterBridgeTrampoline(runtime->GetClassLinker()));
+  DCHECK(entry_point != runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline());
   if (UNLIKELY(entry_point == GetQuickToInterpreterBridge()) ||
       UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) {
     return nullptr;
@@ -289,7 +304,7 @@
   // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method
   // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline)
   // for non-native methods. And we really shouldn't see a failure for non-native methods here.
-  DCHECK(entry_point != GetQuickToInterpreterBridgeTrampoline(runtime->GetClassLinker()));
+  DCHECK(entry_point != runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline());
   CHECK(entry_point != GetQuickToInterpreterBridge());
 
   if (UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) {