Don't pre-initialize Class.name fields in boot images
The Class.name field is normally allocated and set dynamically when
required. We were pre-initializing it for non-app-images in order to
reduce dirty pages. It turns out that without this very few classes
would ever get this field initialized (~2% according to tests while
running a few apps). No longer pre-initializing the field reduces the
size of each boot image by ~600kb.
This partially reverts commit d418edaf4d.
Prior to the change the smaps entry for an art file look like this:
701cd000-70303000 rw-p 00000000 103:1d 5505036 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
Size: 1240 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 720 kB
Pss: 190 kB
Shared_Clean: 548 kB
Shared_Dirty: 0 kB
Private_Clean: 44 kB
Private_Dirty: 128 kB
Referenced: 720 kB
Anonymous: 128 kB
With this change running the same program gives us the following smaps
entry:
6fc83000-6fdae000 rw-p 00000000 103:1d 6684684 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
Size: 1196 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 672 kB
Pss: 195 kB
Shared_Clean: 496 kB
Shared_Dirty: 0 kB
Private_Clean: 48 kB
Private_Dirty: 128 kB
Referenced: 672 kB
Anonymous: 128 kB
All relevant measures of memory use are either improved or remain
unchanged. (NB private_clean is the amount of memory that another process
could cause to be dirtied by writing to it. It is not relevant to this
change.)
Bug: 32635074
Test: ./tools/field-null-percent/check-null-fields.py 'Ljava/lang/Class;.name:Ljava/lang/String;'
Test: Builds and boots
Test: Examine smaps for both old and new version.
Change-Id: I96aaeb782715db5c1e035bdf76331b4253c74ce6
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 6a13454..685174d 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -213,10 +213,6 @@
// since the cookie field contains long pointers to DexFiles which are not deterministic.
// b/34090128
ClearDexFileCookies();
- } else {
- TimingLogger::ScopedTiming t("ComputeLazyFieldsForImageClasses", timings);
- // Avoid for app image since this may increase RAM and image size.
- ComputeLazyFieldsForImageClasses(); // Add useful information
}
}
{
@@ -753,21 +749,6 @@
return true;
}
-class ImageWriter::ComputeLazyFieldsForClassesVisitor : public ClassVisitor {
- public:
- bool operator()(ObjPtr<Class> c) override REQUIRES_SHARED(Locks::mutator_lock_) {
- StackHandleScope<1> hs(Thread::Current());
- mirror::Class::ComputeName(hs.NewHandle(c));
- return true;
- }
-};
-
-void ImageWriter::ComputeLazyFieldsForImageClasses() {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ComputeLazyFieldsForClassesVisitor visitor;
- class_linker->VisitClassesWithoutClassesLock(&visitor);
-}
-
static bool IsBootClassLoaderClass(ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_) {
return klass->GetClassLoader() == nullptr;
diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h
index e45023e..f455746 100644
--- a/dex2oat/linker/image_writer.h
+++ b/dex2oat/linker/image_writer.h
@@ -429,10 +429,6 @@
// Debug aid that list of requested image classes.
void DumpImageClasses();
- // Preinitializes some otherwise lazy fields (such as Class name) to avoid runtime image dirtying.
- void ComputeLazyFieldsForImageClasses()
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Visit all class loaders.
void VisitClassLoaders(ClassLoaderVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);