Move ArtFields and ArtMethods to be a length prefixed array
Fixes race conditions between changing method and fields arrays
being seen in the wrong order by the GC.
Bug: 22832610
Change-Id: Ia21d6698f73ba207a6392c3d6b9be2658933073f
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index 7914b66..b43f77f 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -195,11 +195,9 @@
WalkInstanceFields(visited, callback, obj, super, arg);
}
// Walk instance fields
- auto* fields = klass->GetIFields();
- for (size_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
- ArtField* field = &fields[i];
- if (!field->IsPrimitiveType()) {
- mirror::Object* value = field->GetObj(obj);
+ for (ArtField& field : klass->GetIFields()) {
+ if (!field.IsPrimitiveType()) {
+ mirror::Object* value = field.GetObj(obj);
if (value != nullptr) {
WalkFieldsInOrder(visited, callback, value, arg);
}
@@ -222,11 +220,9 @@
WalkInstanceFields(visited, callback, obj, klass, arg);
// Walk static fields of a Class
if (obj->IsClass()) {
- auto* sfields = klass->GetSFields();
- for (size_t i = 0, count = klass->NumStaticFields(); i < count; ++i) {
- ArtField* field = &sfields[i];
- if (!field->IsPrimitiveType()) {
- mirror::Object* value = field->GetObj(nullptr);
+ for (ArtField& field : klass->GetSFields()) {
+ if (!field.IsPrimitiveType()) {
+ mirror::Object* value = field.GetObj(nullptr);
if (value != nullptr) {
WalkFieldsInOrder(visited, callback, value, arg);
}
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 5f617bd..59e39df 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2912,14 +2912,10 @@
if (!obj->IsObjectArray()) {
mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass();
CHECK(klass != nullptr);
- auto* fields = is_static ? klass->GetSFields() : klass->GetIFields();
- auto num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
- CHECK_EQ(fields == nullptr, num_fields == 0u);
- for (size_t i = 0; i < num_fields; ++i) {
- ArtField* cur = &fields[i];
- if (cur->GetOffset().Int32Value() == offset.Int32Value()) {
+ for (ArtField& field : is_static ? klass->GetSFields() : klass->GetIFields()) {
+ if (field.GetOffset().Int32Value() == offset.Int32Value()) {
LOG(ERROR) << (is_static ? "Static " : "") << "field in the live stack is "
- << PrettyField(cur);
+ << PrettyField(&field);
break;
}
}