Move static field storage to end of Class instance
Change-Id: I90061999c9eef9d900e4269508b983a61f48b264
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index 8541f76..179d954 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -126,8 +126,24 @@
// Scans instance fields.
void MarkSweep::ScanInstanceFields(const Object* obj) {
DCHECK(obj != NULL);
- DCHECK(obj->GetClass() != NULL);
- uint32_t ref_offsets = obj->GetClass()->GetReferenceOffsets();
+ Class* klass = obj->GetClass();
+ DCHECK(klass != NULL);
+ ScanFields(obj,
+ klass->GetReferenceInstanceOffsets(),
+ false);
+}
+
+// Scans static storage on a Class.
+void MarkSweep::ScanStaticFields(const Class* klass) {
+ DCHECK(klass != NULL);
+ ScanFields(klass,
+ klass->GetReferenceStaticOffsets(),
+ true);
+}
+
+void MarkSweep::ScanFields(const Object* obj,
+ uint32_t ref_offsets,
+ bool is_static) {
if (ref_offsets != CLASS_WALK_SUPER) {
// Found a reference offset bitmap. Mark the specified offsets.
while (ref_offsets != 0) {
@@ -138,14 +154,21 @@
ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
}
} else {
- // There is no reference offset bitmap for this class. Walk up
- // the class inheritance hierarchy and find reference offsets the
- // hard way.
- for (Class *klass = obj->GetClass();
+ // There is no reference offset bitmap. In the non-static case,
+ // walk up the class inheritance hierarchy and find reference
+ // offsets the hard way. In the static case, just consider this
+ // class.
+ for (const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
klass != NULL;
- klass = klass->GetSuperClass()) {
- for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
- size_t field_offset = klass->GetInstanceField(i)->GetOffset();
+ klass = is_static ? NULL : klass->GetSuperClass()) {
+ size_t num_reference_fields = (is_static
+ ? klass->NumReferenceStaticFields()
+ : klass->NumReferenceInstanceFields());
+ for (size_t i = 0; i < num_reference_fields; ++i) {
+ Field* field = (is_static
+ ? klass->GetStaticField(i)
+ : klass->GetInstanceField(i));
+ size_t field_offset = field->GetOffset();
const Object* ref = obj->GetFieldObject(field_offset);
MarkObject(ref);
}
@@ -153,19 +176,6 @@
}
}
-// Scans the static fields of a class object.
-void MarkSweep::ScanStaticFields(const Class* klass) {
- DCHECK(klass != NULL);
- for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
- const Field* static_field = klass->GetStaticField(i);
- char ch = static_field->GetType();
- if (ch == '[' || ch == 'L') {
- const Object* obj = static_field->GetObject();
- MarkObject(obj);
- }
- }
-}
-
void MarkSweep::ScanInterfaces(const Class* klass) {
DCHECK(klass != NULL);
for (size_t i = 0; i < klass->NumInterfaces(); ++i) {
@@ -198,7 +208,7 @@
// Scans the header of all array objects. If the array object is
// specialized to a reference type, scans the array data as well.
-void MarkSweep::ScanArray(const Object *obj) {
+void MarkSweep::ScanArray(const Object* obj) {
DCHECK(obj != NULL);
DCHECK(obj->GetClass() != NULL);
MarkObject(obj->GetClass());
@@ -219,7 +229,7 @@
ref->SetFieldObject(offset, ref);
*list = ref;
} else {
- Object *head = (*list)->GetFieldObject(offset);
+ Object* head = (*list)->GetFieldObject(offset);
ref->SetFieldObject(offset, head);
(*list)->SetFieldObject(offset, ref);
}
@@ -235,7 +245,7 @@
ref = *list;
*list = NULL;
} else {
- Object *next = head->GetFieldObject(offset);
+ Object* next = head->GetFieldObject(offset);
(*list)->SetFieldObject(offset, next);
ref = head;
}
@@ -253,7 +263,7 @@
Object* pending = obj->GetFieldObject(reference_pendingNext_offset_);
Object* referent = obj->GetFieldObject(reference_referent_offset_);
if (pending == NULL && referent != NULL && !IsMarked(referent)) {
- Object **list = NULL;
+ Object** list = NULL;
if (obj->IsSoftReference()) {
list = &soft_reference_list_;
} else if (obj->IsWeakReference()) {
@@ -300,7 +310,7 @@
// anymore, so use a finger that points past the end of them.
void MarkSweep::ProcessMarkStack() {
while (!mark_stack_->IsEmpty()) {
- const Object *obj = mark_stack_->Pop();
+ const Object* obj = mark_stack_->Pop();
ScanObject(obj);
}
}
@@ -367,8 +377,8 @@
DCHECK(list != NULL);
size_t offset = reference_referent_offset_;
while (*list != NULL) {
- Object *ref = DequeuePendingReference(list);
- Object *referent = ref->GetFieldObject(offset);
+ Object* ref = DequeuePendingReference(list);
+ Object* referent = ref->GetFieldObject(offset);
if (referent != NULL && !IsMarked(referent)) {
// Referent is white, clear it.
ClearReference(ref);
@@ -456,7 +466,7 @@
// TODO: Method *meth = gDvm.methJavaLangRefReferenceQueueAdd;
// DCHECK(meth != NULL);
// JValue unused;
- // Object *reference = *cleared;
+ // Object* reference = *cleared;
// TODO: dvmCallMethod(self, meth, NULL, &unused, reference);
UNIMPLEMENTED(FATAL);
*cleared = NULL;