start rough sketch of GC code in heap.cpp

This commit is contained in:
Joel Dice 2007-06-19 20:28:31 -06:00
parent 36152603f4
commit caac00e5ff
4 changed files with 235 additions and 3 deletions

215
src/heap.cpp Normal file
View 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;
}

View File

@ -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

View File

@ -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");
}

16
src/vm.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef VM_H
#define VM_H
#include "system.h"
#include "heap.h"
#include "class_finder.h"
namespace vm {
void
run(System* sys, Heap* heap, ClassFinder* classFinder,
const char* className, int argc, const char** argv);
}
#endif//VM_H