Implement Interface Method Tables (IMT).
Change-Id: Idf7fe85e1293453a8ad862ff2380dcd5db4e3a39
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 91b0188..053ea16 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -469,6 +469,11 @@
return CreateTrampoline(instruction_set_, kJniAbi, JNI_ENTRYPOINT_OFFSET(pDlsymLookup));
}
+const std::vector<uint8_t>* CompilerDriver::CreatePortableImtConflictTrampoline() const {
+ return CreateTrampoline(instruction_set_, kPortableAbi,
+ PORTABLE_ENTRYPOINT_OFFSET(pPortableImtConflictTrampoline));
+}
+
const std::vector<uint8_t>* CompilerDriver::CreatePortableResolutionTrampoline() const {
return CreateTrampoline(instruction_set_, kPortableAbi,
PORTABLE_ENTRYPOINT_OFFSET(pPortableResolutionTrampoline));
@@ -479,6 +484,11 @@
PORTABLE_ENTRYPOINT_OFFSET(pPortableToInterpreterBridge));
}
+const std::vector<uint8_t>* CompilerDriver::CreateQuickImtConflictTrampoline() const {
+ return CreateTrampoline(instruction_set_, kQuickAbi,
+ QUICK_ENTRYPOINT_OFFSET(pQuickImtConflictTrampoline));
+}
+
const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const {
return CreateTrampoline(instruction_set_, kQuickAbi,
QUICK_ENTRYPOINT_OFFSET(pQuickResolutionTrampoline));
@@ -1080,7 +1090,7 @@
}
use_dex_cache = true;
} else {
- if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) {
+ if (sharp_type != kStatic && sharp_type != kDirect) {
return;
}
// TODO: support patching on all architectures.
@@ -1101,9 +1111,7 @@
}
}
if (update_stats && method_code_in_boot) {
- if (sharp_type != kInterface) { // Interfaces always go via a trampoline until we get IMTs.
- stats_->DirectCallsToBoot(*type);
- }
+ stats_->DirectCallsToBoot(*type);
stats_->DirectMethodsToBoot(*type);
}
if (!use_dex_cache && compiling_boot) {
@@ -1145,19 +1153,15 @@
if (compiling_boot) {
*type = sharp_type;
*direct_method = -1;
- if (sharp_type != kInterface) {
- *direct_code = -1;
- }
+ *direct_code = -1;
} else {
bool method_in_image =
Runtime::Current()->GetHeap()->FindSpaceFromObject(method, false)->IsImageSpace();
if (method_in_image) {
- CHECK_EQ(method->IsAbstract(), sharp_type == kInterface);
+ CHECK(!method->IsAbstract());
*type = sharp_type;
*direct_method = reinterpret_cast<uintptr_t>(method);
- if (*type != kInterface) {
- *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode());
- }
+ *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode());
target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
target_method->dex_method_index = method->GetDexMethodIndex();
} else if (!must_use_direct_pointers) {
@@ -1187,6 +1191,8 @@
if (resolved_method != NULL) {
if (*invoke_type == kVirtual || *invoke_type == kSuper) {
*vtable_idx = resolved_method->GetMethodIndex();
+ } else if (*invoke_type == kInterface) {
+ *vtable_idx = resolved_method->GetDexMethodIndex();
}
// Don't try to fast-path if we don't understand the caller's class or this appears to be an
// Incompatible Class Change Error.
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 971021f..c791753 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -130,10 +130,14 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const std::vector<uint8_t>* CreateJniDlsymLookup() const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const std::vector<uint8_t>* CreatePortableImtConflictTrampoline() const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const std::vector<uint8_t>* CreatePortableResolutionTrampoline() const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const std::vector<uint8_t>* CreatePortableToInterpreterBridge() const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const std::vector<uint8_t>* CreateQuickImtConflictTrampoline() const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const std::vector<uint8_t>* CreateQuickResolutionTrampoline() const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const std::vector<uint8_t>* CreateQuickToInterpreterBridge() const