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

(cherry picked from commit bfb21589a6490769690b44aaf8e6a0021a1261b7)

Change-Id: I33255f85d10c29cae085584880196c45ac0ea230
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a6ff530..e637aa1 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4209,13 +4209,28 @@
     }
   }
 
-  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<3> hs(self);
     Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
     Handle<mirror::DexCache> 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 value_it(dex_file, &dex_cache, &class_loader,
                                              this, *dex_class_def);
     const uint8_t* class_data = dex_file.GetClassData(*dex_class_def);