diff options
author | Mingyao Yang <mingyao@google.com> | 2014-05-15 17:02:16 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-07-11 17:17:10 -0700 |
commit | 98d1cc8033251c93786e2fa8c59a2e555a9493be (patch) | |
tree | f0a76b8fff060ee484af09028da65a8339d57057 /runtime/class_linker.h | |
parent | aebf3cda094f34cf846d19a7724bdc8005267c95 (diff) | |
download | art-98d1cc8033251c93786e2fa8c59a2e555a9493be.zip art-98d1cc8033251c93786e2fa8c59a2e555a9493be.tar.gz art-98d1cc8033251c93786e2fa8c59a2e555a9493be.tar.bz2 |
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
Diffstat (limited to 'runtime/class_linker.h')
-rw-r--r-- | runtime/class_linker.h | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 60dad7b..d9b3d25 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -31,6 +31,7 @@ #include "read_barrier.h" namespace art { + namespace gc { namespace space { class ImageSpace; @@ -56,11 +57,6 @@ enum VisitRootFlags : uint8_t; class ClassLinker { public: - // Interface method table size. Increasing this value reduces the chance of two interface methods - // colliding in the interface method table but increases the size of classes that implement - // (non-marker) interfaces. - static constexpr size_t kImtSize = 64; - explicit ClassLinker(InternTable* intern_table); ~ClassLinker(); @@ -385,6 +381,14 @@ class ClassLinker { // Special code to allocate an art method, use this instead of class->AllocObject. mirror::ArtMethod* AllocArtMethod(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + mirror::ObjectArray<mirror::Class>* GetClassRoots() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + mirror::ObjectArray<mirror::Class>* class_roots = + ReadBarrier::BarrierForRoot<mirror::ObjectArray<mirror::Class>, kWithReadBarrier>( + &class_roots_); + DCHECK(class_roots != NULL); + return class_roots; + } + private: const OatFile::OatMethod GetOatMethodFor(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -427,8 +431,10 @@ class ClassLinker { mirror::Class* c, SafeMap<uint32_t, mirror::ArtField*>& field_map) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - uint32_t SizeOfClass(const DexFile& dex_file, - const DexFile::ClassDef& dex_class_def); + // Precomputes size needed for Class, in the case of a non-temporary class this size must be + // sufficient to hold all static fields. + uint32_t SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file, + const DexFile::ClassDef& dex_class_def); void LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, @@ -481,8 +487,9 @@ class ClassLinker { mirror::Class* klass2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkClass(Thread* self, Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) + bool LinkClass(Thread* self, const char* descriptor, Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces, + mirror::Class** new_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool LinkSuperClass(Handle<mirror::Class> klass) @@ -502,17 +509,16 @@ class ClassLinker { Handle<mirror::ObjectArray<mirror::Class>> interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkStaticFields(Handle<mirror::Class> klass) + bool LinkStaticFields(Handle<mirror::Class> klass, size_t* class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool LinkInstanceFields(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkFields(Handle<mirror::Class> klass, bool is_static) + bool LinkFields(Handle<mirror::Class> klass, bool is_static, size_t* class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatClass* oat_class, const DexFile& dex_file, uint32_t dex_method_index, uint32_t method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CreateReferenceStaticOffsets(Handle<mirror::Class> klass) @@ -612,11 +618,27 @@ class ClassLinker { size_t hash) SHARED_LOCKS_REQUIRED(Locks::classlinker_classes_lock_, Locks::mutator_lock_); + mirror::Class* UpdateClass(const char* descriptor, mirror::Class* klass, size_t hash) + LOCKS_EXCLUDED(Locks::classlinker_classes_lock_) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void MoveImageClassesToClassTable() LOCKS_EXCLUDED(Locks::classlinker_classes_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::Class* LookupClassFromImage(const char* descriptor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // EnsureResolved is called to make sure that a class in the class_table_ has been resolved + // before returning it to the caller. Its the responsibility of the thread that placed the class + // in the table to make it resolved. The thread doing resolution must notify on the class' lock + // when resolution has occurred. This happens in mirror::Class::SetStatus. As resolution may + // retire a class, the version of the class in the table is returned and this may differ from + // the class passed in. + mirror::Class* EnsureResolved(Thread* self, const char* descriptor, mirror::Class* klass) + __attribute__((warn_unused_result)) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + void FixupTemporaryDeclaringClass(mirror::Class* temp_class, mirror::Class* new_class) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // indexes into class_roots_. // needs to be kept in sync with class_roots_descriptors_. enum ClassRoot { @@ -664,14 +686,6 @@ class ClassLinker { void SetClassRoot(ClassRoot class_root, mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ObjectArray<mirror::Class>* GetClassRoots() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - mirror::ObjectArray<mirror::Class>* class_roots = - ReadBarrier::BarrierForRoot<mirror::ObjectArray<mirror::Class>, kWithReadBarrier>( - &class_roots_); - DCHECK(class_roots != NULL); - return class_roots; - } - static const char* class_roots_descriptors_[]; const char* GetClassRootDescriptor(ClassRoot class_root) { @@ -695,6 +709,8 @@ class ClassLinker { InternTable* intern_table_; + // Trampolines within the image the bounce to runtime entrypoints. Done so that there is a single + // patch point within the image. TODO: make these proper relocations. const void* portable_resolution_trampoline_; const void* quick_resolution_trampoline_; const void* portable_imt_conflict_trampoline_; |