Add an ImtConflictTable to better resolve IMT conflicts.
- Attach a ImtConflictTable to conflict runtime ArtMethod.
- Initially 0, a new one will be created at the first hit of
the conflict method.
- If the assembly code does not find a target method in the table,
we will create a new one again, copying the data from the previous
table and adding the new mapping.
Implemented for arm/arm64/x86/x64.
bug:27556801
bug:24769046
Change-Id: Ie74d1c77cf73d451a1142bdc5e3683f9f84bb4e7
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1d64d6d..941217f 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1596,8 +1596,10 @@
}
}
-ArtMethod* Runtime::CreateImtConflictMethod() {
- auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
+static ImtConflictTable::Entry empty_entry = { nullptr, nullptr };
+
+ArtMethod* Runtime::CreateImtConflictMethod(LinearAlloc* linear_alloc) {
+ auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod(linear_alloc);
// When compiling, the code pointer will get set later when the image is loaded.
if (IsAotCompiler()) {
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
@@ -1605,6 +1607,7 @@
} else {
method->SetEntryPointFromQuickCompiledCode(GetQuickImtConflictStub());
}
+ method->SetImtConflictTable(reinterpret_cast<ImtConflictTable*>(&empty_entry));
return method;
}
@@ -1612,10 +1615,11 @@
CHECK(method != nullptr);
CHECK(method->IsRuntimeMethod());
imt_conflict_method_ = method;
+ method->SetImtConflictTable(reinterpret_cast<ImtConflictTable*>(&empty_entry));
}
ArtMethod* Runtime::CreateResolutionMethod() {
- auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
+ auto* method = GetClassLinker()->CreateRuntimeMethod(GetLinearAlloc());
// When compiling, the code pointer will get set later when the image is loaded.
if (IsAotCompiler()) {
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
@@ -1627,7 +1631,7 @@
}
ArtMethod* Runtime::CreateCalleeSaveMethod() {
- auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
+ auto* method = GetClassLinker()->CreateRuntimeMethod(GetLinearAlloc());
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
DCHECK_NE(instruction_set_, kNone);
@@ -1929,6 +1933,7 @@
CHECK(method != nullptr);
CHECK(method->IsRuntimeMethod());
imt_unimplemented_method_ = method;
+ method->SetImtConflictTable(reinterpret_cast<ImtConflictTable*>(&empty_entry));
}
bool Runtime::IsVerificationEnabled() const {