From bfb21589a6490769690b44aaf8e6a0021a1261b7 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Tue, 28 Oct 2014 13:57:04 -0700 Subject: [PATCH] Fill resolved static fields during class initialization Previously everytime we resolved static fields we linear searched the class to find the field with the specified field id. Now we eagerly set these fields in the dex cache when we initialize classes. FB launch timings before: WaitTime: 2903 WaitTime: 2953 WaitTime: 2918 WaitTime: 2940 WaitTime: 2879 WaitTime: 2792 Timings after: WaitTime: 2699 WaitTime: 2791 WaitTime: 2653 WaitTime: 2929 WaitTime: 2651 WaitTime: 2971 Perf before: 2.94% art::mirror::Class::FindDeclaredStaticField(art::mirror::DexCache const*, unsigned int) After: 0.00% art::mirror::Class::FindDeclaredStaticField(art::mirror::DexCache const*, unsigned int) Bug: 18054905 Bug: 16828525 Change-Id: I33255f85d10c29cae085584880196c45ac0ea230 --- runtime/class_linker.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 13be590dc..8052c3f4f 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4149,13 +4149,28 @@ bool ClassLinker::InitializeClass(Handle klass, bool can_init_sta } } - if (klass->NumStaticFields() > 0) { + const size_t num_static_fields = klass->NumStaticFields(); + if (num_static_fields > 0) { const DexFile::ClassDef* dex_class_def = klass->GetClassDef(); CHECK(dex_class_def != nullptr); const DexFile& dex_file = klass->GetDexFile(); StackHandleScope<2> hs(self); Handle class_loader(hs.NewHandle(klass->GetClassLoader())); Handle dex_cache(hs.NewHandle(klass->GetDexCache())); + + // Eagerly fill in static fields so that the we don't have to do as many expensive + // Class::FindStaticField in ResolveField. + for (size_t i = 0; i < num_static_fields; ++i) { + mirror::ArtField* field = klass->GetStaticField(i); + const uint32_t field_idx = field->GetDexFieldIndex(); + mirror::ArtField* resolved_field = dex_cache->GetResolvedField(field_idx); + if (resolved_field == nullptr) { + dex_cache->SetResolvedField(field_idx, field); + } else if (kIsDebugBuild) { + CHECK_EQ(field, resolved_field); + } + } + EncodedStaticFieldValueIterator it(dex_file, &dex_cache, &class_loader, this, *dex_class_def); if (it.HasNext()) { -- 2.11.0