Move ArtField to native
Add linear alloc. Moved ArtField to be native object. Changed image
writer to put ArtFields after the mirror section.
Savings:
2MB on low ram devices
4MB on normal devices
Total PSS measurements before (normal N5, 95s after shell start):
Image size: 7729152 bytes
23112 kB: .NonMoving
23212 kB: .NonMoving
22868 kB: .NonMoving
23072 kB: .NonMoving
22836 kB: .NonMoving
19618 kB: .Zygote
19850 kB: .Zygote
19623 kB: .Zygote
19924 kB: .Zygote
19612 kB: .Zygote
Avg: 42745.4 kB
After:
Image size: 7462912 bytes
17440 kB: .NonMoving
16776 kB: .NonMoving
16804 kB: .NonMoving
17812 kB: .NonMoving
16820 kB: .NonMoving
18788 kB: .Zygote
18856 kB: .Zygote
19064 kB: .Zygote
18841 kB: .Zygote
18629 kB: .Zygote
3499 kB: .LinearAlloc
3408 kB: .LinearAlloc
3424 kB: .LinearAlloc
3600 kB: .LinearAlloc
3436 kB: .LinearAlloc
Avg: 39439.4 kB
No reflection performance changes.
Bug: 19264997
Bug: 17643507
Change-Id: I10c73a37913332080aeb978c7c94713bdfe4fe1c
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 577fec2..2427462 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -70,12 +70,10 @@
kJavaLangString,
kJavaLangDexCache,
kJavaLangRefReference,
- kJavaLangReflectArtField,
kJavaLangReflectArtMethod,
kJavaLangReflectField,
kJavaLangReflectProxy,
kJavaLangStringArrayClass,
- kJavaLangReflectArtFieldArrayClass,
kJavaLangReflectArtMethodArrayClass,
kJavaLangReflectFieldArrayClass,
kJavaLangClassLoader,
@@ -201,7 +199,7 @@
mirror::Class* ResolveType(uint16_t type_idx, mirror::ArtMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::Class* ResolveType(uint16_t type_idx, mirror::ArtField* referrer)
+ mirror::Class* ResolveType(uint16_t type_idx, ArtField* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a type with the given ID from the DexFile, storing the
@@ -232,10 +230,11 @@
InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class)
+ ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
- bool is_static)
+ ArtField* GetResolvedField(uint32_t field_idx, mirror::DexCache* dex_cache)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a field with a given ID from the DexFile, storing the
@@ -243,7 +242,7 @@
// in ResolveType. What is unique is the is_static argument which is
// used to determine if we are resolving a static or non-static
// field.
- mirror::ArtField* ResolveField(const DexFile& dex_file,
+ ArtField* ResolveField(const DexFile& dex_file,
uint32_t field_idx,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader,
@@ -254,7 +253,7 @@
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. No is_static argument is provided so that Java
// field resolution semantics are followed.
- mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
+ ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -354,7 +353,7 @@
mirror::IfTable* AllocIfTable(Thread* self, size_t ifcount)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ObjectArray<mirror::ArtField>* AllocArtFieldArray(Thread* self, size_t length)
+ ArtField* AllocArtFieldArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ObjectArray<mirror::StackTraceElement>* AllocStackTraceElementArray(Thread* self,
@@ -485,7 +484,6 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::DexCache* AllocDexCache(Thread* self, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* AllocArtField(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -507,15 +505,21 @@
uint32_t SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def);
+ // Setup the classloader, class def index, type idx so that we can insert this class in the class
+ // table.
+ void SetupClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
+ Handle<mirror::Class> klass, mirror::ClassLoader* class_loader)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
void LoadClass(Thread* self, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- Handle<mirror::Class> klass, mirror::ClassLoader* class_loader)
+ Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void LoadClassMembers(Thread* self, const DexFile& dex_file, const uint8_t* class_data,
Handle<mirror::Class> klass, const OatFile::OatClass* oat_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it,
- Handle<mirror::Class> klass, Handle<mirror::ArtField> dst)
+ void LoadField(const ClassDataItemIterator& it, Handle<mirror::Class> klass,
+ ArtField* dst)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* LoadMethod(Thread* self, const DexFile& dex_file,