mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
start rough sketch of GC code in heap.cpp
This commit is contained in:
parent
36152603f4
commit
caac00e5ff
215
src/heap.cpp
Normal file
215
src/heap.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
#include "heap.h"
|
||||
#include "system.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
class Context {
|
||||
public:
|
||||
};
|
||||
|
||||
void
|
||||
collect(Context* c, void** p)
|
||||
{
|
||||
object original = *p;
|
||||
object parent = 0;
|
||||
|
||||
bool needsVisit;
|
||||
*p = update(c, p, &needsVisit);
|
||||
|
||||
if (not needsVisit) return;
|
||||
|
||||
visit: {
|
||||
object copy = follow(original);
|
||||
|
||||
class Walker : public Heap::Walker {
|
||||
public:
|
||||
Walker(Context* c, object copy, uintptr_t* bitset):
|
||||
c(c),
|
||||
copy(copy),
|
||||
bitset(bitset),
|
||||
first(0),
|
||||
last(0),
|
||||
visits(0),
|
||||
total(0)
|
||||
{ }
|
||||
|
||||
virtual bool visit(unsigned offset) {
|
||||
bool needsVisit;
|
||||
object childCopy = update
|
||||
(c, &cast<object>(copy, offset * sizeof(void*)), &needsVisit);
|
||||
|
||||
++ total;
|
||||
|
||||
if (total == 3) {
|
||||
bitsetInit(bitset);
|
||||
}
|
||||
|
||||
if (needsVisit) {
|
||||
++ visits;
|
||||
|
||||
if (visits == 1) {
|
||||
first = offset;
|
||||
}
|
||||
|
||||
if (total >= 3) {
|
||||
bitsetClear(bitset, last, offset);
|
||||
last = offset;
|
||||
|
||||
bitsetSet(bitset, offset, true);
|
||||
}
|
||||
} else {
|
||||
cast<object>(copy, offset * sizeof(void*)) = childCopy;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Context* c;
|
||||
object copy;
|
||||
uintptr_t* bitset;
|
||||
unsigned first;
|
||||
unsigned last;
|
||||
unsigned visits;
|
||||
unsigned total;
|
||||
} walker(c, copy, bitset(original));
|
||||
|
||||
c->client->walk(copy, &walker);
|
||||
|
||||
if (walker.visits) {
|
||||
// descend
|
||||
if (walker.visits > 1) {
|
||||
::parent(original) = parent;
|
||||
|
||||
parent = original;
|
||||
}
|
||||
|
||||
original = cast<object>(copy, walker.first * sizeof(void*));
|
||||
cast<object>(copy, walker.first * sizeof(void*)) = follow(original);
|
||||
goto visit;
|
||||
} else {
|
||||
// ascend
|
||||
original = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (original) {
|
||||
object copy = follow(original);
|
||||
|
||||
class Walker : public Heap::Walker {
|
||||
public:
|
||||
Walker(uintptr_t* bitset):
|
||||
bitset(bitset),
|
||||
next(0),
|
||||
total(0)
|
||||
{ }
|
||||
|
||||
virtual bool visit(unsigned offset) {
|
||||
switch (++ total) {
|
||||
case 1:
|
||||
return true;
|
||||
|
||||
case 2:
|
||||
next = offset;
|
||||
return true;
|
||||
|
||||
case 3:
|
||||
next = bitsetNext(bitset);
|
||||
return false;
|
||||
|
||||
default:
|
||||
abort(c);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t* bitset;
|
||||
unsigned next;
|
||||
unsigned total;
|
||||
} walker(c, copy, bitset(original));
|
||||
|
||||
assert(c, walker.total > 1);
|
||||
|
||||
if (walker.total == 3 and bitsetHasMore(bitset(original))) {
|
||||
parent = original;
|
||||
} else {
|
||||
parent = ::parent(original);
|
||||
}
|
||||
|
||||
original = cast<object>(copy, walker.next * sizeof(void*));
|
||||
cast<object>(copy, walker.next * sizeof(void*)) = follow(original);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
collect2(Context* c)
|
||||
{
|
||||
if (c->mode == MinorCollection and c->gen2.position()) {
|
||||
unsigned start = 0;
|
||||
unsigned end = start + c->gen2.position();
|
||||
bool dirty;
|
||||
collect(m, &(c->map), start, end, &dirty, false);
|
||||
} else if (c->mode == Gen2Collection) {
|
||||
unsigned ng2Position = c->nextGen2.position();
|
||||
collect(m, &(c->nextGen1), c->nextGen1.position());
|
||||
collect(m, &(c->nextGen2), ng2Position);
|
||||
}
|
||||
|
||||
class Visitor : public Heap::Visitor {
|
||||
public:
|
||||
Visitor(Context* c): c(c) { }
|
||||
|
||||
virtual void visit(void** p) {
|
||||
collect(c, p);
|
||||
}
|
||||
} v(c);
|
||||
|
||||
c->iterator->iterate(&v);
|
||||
}
|
||||
|
||||
void
|
||||
collect1(Context* c)
|
||||
{
|
||||
switch (c->mode) {
|
||||
case MinorCollection: {
|
||||
initNextGen1(c);
|
||||
|
||||
collect2(c);
|
||||
|
||||
if (c->mode == OverflowCollection) {
|
||||
c->mode = Gen2Collection;
|
||||
collect2(c);
|
||||
|
||||
c->gen2.replaceWith(&(c->nextGen2));
|
||||
}
|
||||
|
||||
c->gen1.replaceWith(&(c->nextGen1));
|
||||
} break;
|
||||
|
||||
case MajorCollection: {
|
||||
initNextGen1(c);
|
||||
initNextGen2(c);
|
||||
|
||||
c->map.clear();
|
||||
|
||||
collect2(c);
|
||||
|
||||
c->gen1.replaceWith(&(c->nextGen1));
|
||||
c->gen2.replaceWith(&(c->nextGen2));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Heap*
|
||||
makeHeap(System* system)
|
||||
{
|
||||
|
||||
|
||||
HeapImp* h = static_cast<HeapImp*>(system->allocate(sizeof(HeapImp)));
|
||||
init(h, system);
|
||||
return h;
|
||||
}
|
@ -25,7 +25,8 @@ class Heap {
|
||||
virtual ~Heap() { }
|
||||
virtual void collect(CollectionType type, Iterator* it) = 0;
|
||||
virtual bool needsMark(void** p) = 0;
|
||||
virtual void mark(void** p);
|
||||
virtual void mark(void** p) = 0;
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
} // namespace vm
|
||||
|
@ -1489,7 +1489,7 @@ typeCount(Object* declarations)
|
||||
void
|
||||
writeInitializations(Output* out, Object* declarations)
|
||||
{
|
||||
out->write(" t->vm->types = makeArray(t, ");
|
||||
out->write("t->vm->types = makeArray(t, ");
|
||||
out->write(typeCount(declarations));
|
||||
out->write(");\n\n");
|
||||
|
||||
@ -1500,7 +1500,7 @@ writeInitializations(Output* out, Object* declarations)
|
||||
}
|
||||
}
|
||||
|
||||
out->write(" set(t, objectClass(t->vm->types), ");
|
||||
out->write("set(t, objectClass(t->vm->types), ");
|
||||
out->write("arrayBody(t, t->vm->types, Machine::ArrayType));\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user