Avoid handle-less fields in ClassLinker::InitializeClass()
There were some handle-less fields in a SafeMap across GC points.
Bug: 12687968
Change-Id: Ib8c6527d4e23031f1d0074fa11d8f85499b68340
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8fc1d07..74c5c15 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3843,7 +3843,7 @@
const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
CHECK(dex_class_def != NULL);
const DexFile& dex_file = klass->GetDexFile();
- StackHandleScope<2> hs(self);
+ StackHandleScope<3> hs(self);
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
EncodedStaticFieldValueIterator it(dex_file, &dex_cache, &class_loader,
@@ -3852,13 +3852,16 @@
CHECK(can_init_statics);
// We reordered the fields, so we need to be able to map the
// field indexes to the right fields.
- SafeMap<uint32_t, mirror::ArtField*> field_map;
- ConstructFieldMap(dex_file, *dex_class_def, klass.Get(), field_map);
+ Handle<mirror::ObjectArray<mirror::ArtField>>
+ field_array(hs.NewHandle(AllocArtFieldArray(self, klass->NumStaticFields())));
+ ConstructFieldArray(dex_file, *dex_class_def, klass.Get(), field_array);
for (size_t i = 0; it.HasNext(); i++, it.Next()) {
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtField> field(hs.NewHandle(field_array->Get(i)));
if (Runtime::Current()->IsActiveTransaction()) {
- it.ReadValueToField<true>(field_map.Get(i));
+ it.ReadValueToField<true>(field);
} else {
- it.ReadValueToField<false>(field_map.Get(i));
+ it.ReadValueToField<false>(field);
}
}
}
@@ -3997,17 +4000,20 @@
return success;
}
-void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- mirror::Class* c,
- SafeMap<uint32_t, mirror::ArtField*>& field_map) {
+void ClassLinker::ConstructFieldArray(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
+ mirror::Class* c,
+ Handle<mirror::ObjectArray<mirror::ArtField>> field_array) {
const byte* class_data = dex_file.GetClassData(dex_class_def);
ClassDataItemIterator it(dex_file, class_data);
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(c->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
- CHECK(!kMovingFields);
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
- field_map.Put(i, ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true));
+ if (Runtime::Current()->IsActiveTransaction()) {
+ field_array->Set<true>(i, ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true));
+ } else {
+ field_array->Set<false>(i, ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true));
+ }
}
}