Fix GarbageCollector to work with VERIFY_OBJECT_ENABLED
There were two problems with the GC:
1.) roots were being missed for most of the C++ fields
2.) Heap::RecordFree(Object) was not being called, only Space::Free
To solve #1, added all C++ shadow fields to libcore.
This involed updating dalvik to cope with the new sizes and offsets.
This had the positive side effect of allowing a lot of special cases
in the object scanning and image writing.
To solve #2, added a call to the now public Heap::RecordFree from MarkSweep
Given the now better working GC:
- Reenabled HeapTest.GarbageCollectClassLinkerInit which is now passing.
- ImageWriter now GC's before writing an image to avoid garbage.
Change-Id: Ie7d1cc89e0bcf314cb37f0cabcb8593bf6e4d4be
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index a2f1a56..b3d21a3 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -6,6 +6,7 @@
#include <vector>
#include "class_loader.h"
+#include "dex_cache.h"
#include "heap.h"
#include "indirect_reference_table.h"
#include "intern_table.h"
@@ -148,6 +149,7 @@
Space* space = static_cast<Space*>(arg);
for (size_t i = 0; i < num_ptrs; ++i) {
Object* obj = static_cast<Object*>(ptrs[i]);
+ Heap::RecordFree(space, obj);
space->Free(obj);
}
// TODO, unlock heap if concurrent
@@ -219,13 +221,6 @@
}
}
-void MarkSweep::ScanInterfaces(const Class* klass) {
- DCHECK(klass != NULL);
- for (size_t i = 0; i < klass->NumInterfaces(); ++i) {
- MarkObject(klass->GetInterface(i));
- }
-}
-
// Scans the header, static field references, and interface pointers
// of a class object.
void MarkSweep::ScanClass(const Object* obj) {
@@ -233,6 +228,10 @@
DCHECK(obj->IsClass());
const Class* klass = obj->AsClass();
MarkObject(klass->GetClass());
+ ScanInstanceFields(obj);
+ MarkObject(klass->GetDescriptor());
+ MarkObject(klass->GetDexCache());
+ MarkObject(klass->GetVerifyErrorClass());
if (klass->IsArrayClass()) {
MarkObject(klass->GetComponentType());
}
@@ -240,13 +239,14 @@
MarkObject(klass->GetSuperClass());
}
MarkObject(klass->GetClassLoader());
- ScanInstanceFields(obj);
- ScanStaticFields(klass);
- // TODO: scan methods
- // TODO: scan instance fields
if (klass->IsLoaded()) {
- ScanInterfaces(klass);
+ MarkObject(klass->GetInterfaces());
+ MarkObject(klass->GetDirectMethods());
+ MarkObject(klass->GetVirtualMethods());
+ MarkObject(klass->GetIFields());
+ MarkObject(klass->GetSFields());
}
+ ScanStaticFields(klass);
}
// Scans the header of all array objects. If the array object is