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())) {