// Table to resolve IMT conflicts at runtime. The table is attached to // the jni entrypoint of IMT conflict ArtMethods. // The table contains a list of pairs of { interface_method, implementation_method } // with the last entry being null to make an assembly implementation of a lookup // faster. class ImtConflictTable { enum MethodIndex {
kMethodInterface,
kMethodImplementation,
kMethodCount, // Number of elements in enum.
};
public: // Build a new table copying `other` and adding the new entry formed of // the pair { `interface_method`, `implementation_method` }
ImtConflictTable(ImtConflictTable* other,
ArtMethod* interface_method,
ArtMethod* implementation_method,
PointerSize pointer_size) { const size_t count = other->NumEntries(pointer_size); for (size_t i = 0; i < count; ++i) {
SetInterfaceMethod(i, pointer_size, other->GetInterfaceMethod(i, pointer_size));
SetImplementationMethod(i, pointer_size, other->GetImplementationMethod(i, pointer_size));
}
SetInterfaceMethod(count, pointer_size, interface_method);
SetImplementationMethod(count, pointer_size, implementation_method); // Add the null marker.
SetInterfaceMethod(count + 1, pointer_size, nullptr);
SetImplementationMethod(count + 1, pointer_size, nullptr);
}
// Return true if two conflict tables are the same. bool Equals(ImtConflictTable* other, PointerSize pointer_size) const {
size_t num = NumEntries(pointer_size); if (num != other->NumEntries(pointer_size)) { returnfalse;
} for (size_t i = 0; i < num; ++i) { if (GetInterfaceMethod(i, pointer_size) != other->GetInterfaceMethod(i, pointer_size) ||
GetImplementationMethod(i, pointer_size) !=
other->GetImplementationMethod(i, pointer_size)) { returnfalse;
}
} returntrue;
}
// Visit all of the entries. // NO_THREAD_SAFETY_ANALYSIS for calling with held locks. Visitor is passed a pair of ArtMethod* // and also returns one. The order is <interface, implementation>. template<typename Visitor> void Visit(const Visitor& visitor, PointerSize pointer_size) NO_THREAD_SAFETY_ANALYSIS {
uint32_t table_index = 0; for (;;) {
ArtMethod* interface_method = GetInterfaceMethod(table_index, pointer_size); if (interface_method == nullptr) { break;
}
ArtMethod* implementation_method = GetImplementationMethod(table_index, pointer_size); auto input = std::make_pair(interface_method, implementation_method);
std::pair<ArtMethod*, ArtMethod*> updated = visitor(input); if (input.first != updated.first) {
SetInterfaceMethod(table_index, pointer_size, updated.first);
} if (input.second != updated.second) {
SetImplementationMethod(table_index, pointer_size, updated.second);
}
++table_index;
}
}
// Lookup the implementation ArtMethod associated to `interface_method`. Return null // if not found.
ArtMethod* Lookup(ArtMethod* interface_method, PointerSize pointer_size) const {
uint32_t table_index = 0; for (;;) {
ArtMethod* current_interface_method = GetInterfaceMethod(table_index, pointer_size); if (current_interface_method == nullptr) { break;
} if (current_interface_method == interface_method) { return GetImplementationMethod(table_index, pointer_size);
}
++table_index;
} return nullptr;
}
// Compute the number of entries in this table.
size_t NumEntries(PointerSize pointer_size) const {
uint32_t table_index = 0; while (GetInterfaceMethod(table_index, pointer_size) != nullptr) {
++table_index;
} return table_index;
}
// Compute the size in bytes taken by this table.
size_t ComputeSize(PointerSize pointer_size) const { // Add the end marker. return ComputeSize(NumEntries(pointer_size), pointer_size);
}
// Compute the size in bytes needed for copying the given `table` and add // one more entry. static size_t ComputeSizeWithOneMoreEntry(ImtConflictTable* table, PointerSize pointer_size) { return table->ComputeSize(pointer_size) + EntrySize(pointer_size);
}
// Compute size with a fixed number of entries. static size_t ComputeSize(size_t num_entries, PointerSize pointer_size) { return (num_entries + 1) * EntrySize(pointer_size); // Add one for null terminator.
}
// Array of entries that the assembly stubs will iterate over. Note that this is // not fixed size, and we allocate data prior to calling the constructor // of ImtConflictTable. union {
uint32_t data32_[0];
uint64_t data64_[0];
};
DISALLOW_COPY_AND_ASSIGN(ImtConflictTable);
};
} // namespace art
#endif// ART_RUNTIME_IMT_CONFLICT_TABLE_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.