summaryrefslogtreecommitdiff
path: root/runtime/art_method.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/art_method.h')
-rw-r--r--runtime/art_method.h83
1 files changed, 80 insertions, 3 deletions
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 5ca362ce2c..3dbcd58f05 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -44,6 +44,76 @@ class Class;
class PointerArray;
} // namespace mirror
+// 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 {
+ 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) {
+ size_t index = 0;
+ while (other->entries_[index].interface_method != nullptr) {
+ entries_[index] = other->entries_[index];
+ index++;
+ }
+ entries_[index].interface_method = interface_method;
+ entries_[index].implementation_method = implementation_method;
+ // Add the null marker.
+ entries_[index + 1].interface_method = nullptr;
+ entries_[index + 1].implementation_method = nullptr;
+ }
+
+ // Lookup the implementation ArtMethod associated to `interface_method`. Return null
+ // if not found.
+ ArtMethod* Lookup(ArtMethod* interface_method) const {
+ uint32_t table_index = 0;
+ ArtMethod* current_interface_method;
+ while ((current_interface_method = entries_[table_index].interface_method) != nullptr) {
+ if (current_interface_method == interface_method) {
+ return entries_[table_index].implementation_method;
+ }
+ table_index++;
+ }
+ return nullptr;
+ }
+
+ // Compute the size in bytes taken by this table.
+ size_t ComputeSize() const {
+ uint32_t table_index = 0;
+ size_t total_size = 0;
+ while ((entries_[table_index].interface_method) != nullptr) {
+ total_size += sizeof(Entry);
+ table_index++;
+ }
+ // Add the end marker.
+ return total_size + sizeof(Entry);
+ }
+
+ // Compute the size in bytes needed for copying the given `table` and add
+ // one more entry.
+ static size_t ComputeSizeWithOneMoreEntry(ImtConflictTable* table) {
+ return table->ComputeSize() + sizeof(Entry);
+ }
+
+ struct Entry {
+ ArtMethod* interface_method;
+ ArtMethod* implementation_method;
+ };
+
+ private:
+ // 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.
+ Entry entries_[0];
+
+ DISALLOW_COPY_AND_ASSIGN(ImtConflictTable);
+};
+
class ArtMethod FINAL {
public:
ArtMethod() : access_flags_(0), dex_code_item_offset_(0), dex_method_index_(0),
@@ -338,6 +408,15 @@ class ArtMethod FINAL {
return reinterpret_cast<ProfilingInfo*>(GetEntryPointFromJniPtrSize(pointer_size));
}
+ ImtConflictTable* GetImtConflictTable(size_t pointer_size) {
+ DCHECK(IsRuntimeMethod());
+ return reinterpret_cast<ImtConflictTable*>(GetEntryPointFromJniPtrSize(pointer_size));
+ }
+
+ ALWAYS_INLINE void SetImtConflictTable(ImtConflictTable* table) {
+ SetEntryPointFromJniPtrSize(table, sizeof(void*));
+ }
+
ALWAYS_INLINE void SetProfilingInfo(ProfilingInfo* info) {
SetEntryPointFromJniPtrSize(info, sizeof(void*));
}
@@ -376,8 +455,6 @@ class ArtMethod FINAL {
bool IsResolutionMethod() SHARED_REQUIRES(Locks::mutator_lock_);
- bool IsImtConflictMethod() SHARED_REQUIRES(Locks::mutator_lock_);
-
bool IsImtUnimplementedMethod() SHARED_REQUIRES(Locks::mutator_lock_);
MethodReference ToMethodReference() SHARED_REQUIRES(Locks::mutator_lock_) {
@@ -537,7 +614,7 @@ class ArtMethod FINAL {
GcRoot<mirror::Class>* dex_cache_resolved_types_;
// Pointer to JNI function registered to this method, or a function to resolve the JNI function,
- // or the profiling data for non-native methods.
+ // or the profiling data for non-native methods, or an ImtConflictTable.
void* entry_point_from_jni_;
// Method dispatch from quick compiled code invokes this pointer which may cause bridging into