Add a collection implementation.
Change-Id: I47330dc14dd2ecee052b6a5165c6d48bd6c89dc4
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index d2e7b66..196c83c 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -3,10 +3,15 @@
#include "mark_sweep.h"
+#include <climits>
+#include <vector>
+
+#include "heap.h"
#include "logging.h"
#include "macros.h"
#include "mark_stack.h"
#include "object.h"
+#include "space.h"
#include "thread.h"
#define CLZ(x) __builtin_clz(x)
@@ -19,6 +24,22 @@
size_t MarkSweep::reference_pendingNext_offset_ = 0; // TODO
size_t MarkSweep::finalizer_reference_zombie_offset_ = 0; // TODO
+bool MarkSweep::Init() {
+ mark_stack_ = MarkStack::Create(Heap::GetMaximumSize());
+ if (mark_stack_ == NULL) {
+ return false;
+ }
+
+ mark_bitmap_ = Heap::GetMarkBits();
+ live_bitmap_ = Heap::GetLiveBits();
+
+ // TODO: if concurrent, clear the card table.
+
+ // TODO: check that the mark bitmap is entirely clear.
+
+ return true;
+}
+
void MarkSweep::MarkObject0(const Object* obj, bool check_finger) {
DCHECK(obj != NULL);
if (obj < condemned_) {
@@ -52,11 +73,59 @@
LOG(FATAL) << "Unimplemented";
}
-void MarkSweep::ReMarkRoots()
-{
+void MarkSweep::ScanBitmapCallback(Object* obj, void* finger, void* arg) {
+ MarkSweep* mark_sweep = reinterpret_cast<MarkSweep*>(arg);
+ mark_sweep->finger_ = reinterpret_cast<Object*>(finger);
+ mark_sweep->ScanObject(obj);
+}
+
+// Populates the mark stack based on the set of marked objects and
+// recursively marks until the mark stack is emptied.
+void MarkSweep::RecursiveMark() {
+ void* arg = reinterpret_cast<void*>(this);
+ const std::vector<Space*>& spaces = Heap::GetSpaces();
+ for (size_t i = 0; i < spaces.size(); ++i) {
+ if (spaces[i]->IsCondemned()) {
+ uintptr_t base = reinterpret_cast<uintptr_t>(spaces[i]->GetBase());
+ uintptr_t limit = reinterpret_cast<uintptr_t>(spaces[i]->GetLimit());
+ mark_bitmap_->ScanWalk(base, limit, &MarkSweep::ScanBitmapCallback, arg);
+ }
+ }
+ finger_ = reinterpret_cast<Object*>(~0);
+ ProcessMarkStack();
+}
+
+void MarkSweep::ReMarkRoots() {
LOG(FATAL) << "Unimplemented";
}
+void MarkSweep::SweepSystemWeaks() {
+ LOG(FATAL) << "Unimplemented";
+}
+
+void MarkSweep::SweepCallback(size_t num_ptrs, void **ptrs, void *arg) {
+ // TODO, lock heap if concurrent
+ Space* space = static_cast<Space*>(arg);
+ for (size_t i = 0; i < num_ptrs; ++i) {
+ Object* obj = static_cast<Object*>(ptrs[i]);
+ space->Free(obj);
+ }
+ // TODO, unlock heap if concurrent
+}
+
+void MarkSweep::Sweep() {
+ const std::vector<Space*>& spaces = Heap::GetSpaces();
+ for (size_t i = 0; i < spaces.size(); ++i) {
+ if (spaces[i]->IsCondemned()) {
+ uintptr_t base = reinterpret_cast<uintptr_t>(spaces[i]->GetBase());
+ uintptr_t limit = reinterpret_cast<uintptr_t>(spaces[i]->GetLimit());
+ void* arg = static_cast<void*>(spaces[i]);
+ HeapBitmap::SweepWalk(*live_bitmap_, *mark_bitmap_, base, limit,
+ &MarkSweep::SweepCallback, arg);
+ }
+ }
+}
+
// Scans instance fields.
void MarkSweep::ScanInstanceFields(const Object* obj) {
DCHECK(obj != NULL);
@@ -91,12 +160,9 @@
void MarkSweep::ScanStaticFields(const Class* klass) {
DCHECK(klass != NULL);
for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
- // char ch = clazz->sfields[i].signature[0];
const StaticField* static_field = klass->GetStaticField(i);
char ch = static_field->GetType();
if (ch == '[' || ch == 'L') {
- // Object *obj = clazz->sfields[i].value.l;
- // markObject(obj, ctx);
const Object* obj = static_field->GetObject();
MarkObject(obj);
}
@@ -186,7 +252,7 @@
void MarkSweep::DelayReferenceReferent(Object* obj) {
DCHECK(obj != NULL);
DCHECK(obj->GetClass() != NULL);
- //DCHECK(IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE));
+ DCHECK(obj->IsReference());
Object* pending = obj->GetFieldObject(reference_pendingNext_offset_);
Object* referent = obj->GetFieldObject(reference_referent_offset_);
if (pending == NULL && referent != NULL && !IsMarked(referent)) {
@@ -208,7 +274,7 @@
// Scans the header and field references of a data object. If the
// scanned object is a reference subclass, it is scheduled for later
// processing
-void MarkSweep::ScanDataObject(const Object *obj) {
+void MarkSweep::ScanOther(const Object* obj) {
DCHECK(obj != NULL);
DCHECK(obj->GetClass() != NULL);
MarkObject(obj->GetClass());
@@ -229,7 +295,7 @@
} else if (obj->IsArray()) {
ScanArray(obj);
} else {
- ScanDataObject(obj);
+ ScanOther(obj);
}
}
@@ -344,9 +410,7 @@
DCHECK(*list == NULL);
}
-/*
- * Process reference class instances and schedule finalizations.
- */
+// Process reference class instances and schedule finalizations.
void MarkSweep::ProcessReferences(Object** soft_references, bool clear_soft,
Object** weak_references,
Object** finalizer_references,
@@ -403,6 +467,7 @@
}
MarkSweep::~MarkSweep() {
+ delete mark_stack_;
mark_bitmap_->Clear();
}