mirror of
https://github.com/corda/corda.git
synced 2025-02-05 02:29:20 +00:00
various GC bugfixes
This commit is contained in:
parent
8d0c5f4186
commit
31e2da3e05
83
src/heap.cpp
83
src/heap.cpp
@ -8,10 +8,12 @@ namespace {
|
||||
|
||||
// an object must survive TenureThreshold + 2 garbage collections
|
||||
// before being copied to gen2:
|
||||
static const unsigned TenureThreshold = 3;
|
||||
const unsigned TenureThreshold = 3;
|
||||
|
||||
static const unsigned MinimumGen1Size = 64 * 1024;
|
||||
static const unsigned MinimumGen2Size = 128 * 1024;
|
||||
const unsigned MinimumGen1Size = 64 * 1024;
|
||||
const unsigned MinimumGen2Size = 128 * 1024;
|
||||
|
||||
void* const Top = reinterpret_cast<void*>(~static_cast<uintptr_t>(0));
|
||||
|
||||
class Context;
|
||||
|
||||
@ -19,12 +21,6 @@ System* system(Context*);
|
||||
void NO_RETURN abort(Context*);
|
||||
void assert(Context*, bool);
|
||||
|
||||
void
|
||||
indent(unsigned /*i*/)
|
||||
{
|
||||
//for (; i > 0; --i) fprintf(stderr, " ");
|
||||
}
|
||||
|
||||
class Segment {
|
||||
public:
|
||||
class Map {
|
||||
@ -42,12 +38,12 @@ class Segment {
|
||||
assert(map->segment->context, map->bitsPerRecord == 1);
|
||||
assert(map->segment->context, map->segment);
|
||||
|
||||
index = map->indexOf(map->segment->data + start);
|
||||
index = map->indexOf(start);
|
||||
assert(map->segment->context, index == 0 or start != 0);
|
||||
|
||||
if (end > map->segment->position) end = map->segment->position;
|
||||
|
||||
limit = map->indexOf(map->segment->data + end);
|
||||
limit = map->indexOf(end);
|
||||
if (end - start % map->scale) ++ limit;
|
||||
|
||||
// printf("iterating from %p (index %d) to %p (index %d) "
|
||||
@ -147,6 +143,10 @@ class Segment {
|
||||
return size(max(segment->capacity, 1));
|
||||
}
|
||||
|
||||
unsigned indexOf(unsigned segmentIndex) {
|
||||
return (segmentIndex / scale) * bitsPerRecord;
|
||||
}
|
||||
|
||||
unsigned indexOf(void* p) {
|
||||
assert(segment->context,
|
||||
segment->position
|
||||
@ -154,9 +154,8 @@ class Segment {
|
||||
and p <= segment->data + segment->position);
|
||||
assert(segment->context, segment->data);
|
||||
|
||||
return ((static_cast<void**>(p)
|
||||
- reinterpret_cast<void**>(segment->data))
|
||||
/ scale) * bitsPerRecord;
|
||||
return indexOf(static_cast<void**>(p)
|
||||
- reinterpret_cast<void**>(segment->data));
|
||||
}
|
||||
|
||||
void update(uintptr_t* segmentData) {
|
||||
@ -180,14 +179,18 @@ class Segment {
|
||||
data()[wordOf(i)] |= static_cast<uintptr_t>(1) << bitOf(i);
|
||||
}
|
||||
|
||||
void clearOnly(unsigned index) {
|
||||
void clearOnlyIndex(unsigned index) {
|
||||
for (unsigned i = index, limit = index + bitsPerRecord; i < limit; ++i) {
|
||||
clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
void clearOnly(unsigned segmentIndex) {
|
||||
clearOnlyIndex(indexOf(segmentIndex));
|
||||
}
|
||||
|
||||
void clearOnly(void* p) {
|
||||
clearOnly(indexOf(p));
|
||||
clearOnlyIndex(indexOf(p));
|
||||
}
|
||||
|
||||
void clear(void* p) {
|
||||
@ -195,7 +198,7 @@ class Segment {
|
||||
if (child) child->clear(p);
|
||||
}
|
||||
|
||||
void setOnly(unsigned index, unsigned v = 1) {
|
||||
void setOnlyIndex(unsigned index, unsigned v = 1) {
|
||||
unsigned i = index + bitsPerRecord - 1;
|
||||
while (true) {
|
||||
if (v & 1) set(i); else clear(i);
|
||||
@ -205,8 +208,12 @@ class Segment {
|
||||
}
|
||||
}
|
||||
|
||||
void setOnly(unsigned segmentIndex, unsigned v = 1) {
|
||||
setOnlyIndex(indexOf(segmentIndex), v);
|
||||
}
|
||||
|
||||
void setOnly(void* p, unsigned v = 1) {
|
||||
setOnly(indexOf(p), v);
|
||||
setOnlyIndex(indexOf(p), v);
|
||||
}
|
||||
|
||||
void set(void* p, unsigned v = 1) {
|
||||
@ -396,6 +403,8 @@ class Context {
|
||||
Segment gen2;
|
||||
Segment nextGen2;
|
||||
|
||||
void* gen2Base;
|
||||
|
||||
Segment::Map ageMap;
|
||||
Segment::Map nextAgeMap;
|
||||
Segment::Map pointerMap;
|
||||
@ -403,8 +412,6 @@ class Context {
|
||||
Segment::Map heapMap;
|
||||
|
||||
CollectionMode mode;
|
||||
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
inline System*
|
||||
@ -468,14 +475,18 @@ initNextGen2(Context* c)
|
||||
c->gen2.map = 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
fresh(Context* c, object o)
|
||||
{
|
||||
return c->nextGen1.contains(o)
|
||||
or c->nextGen2.contains(o)
|
||||
or (o >= c->gen2Base and c->gen2.contains(o));
|
||||
}
|
||||
|
||||
inline bool
|
||||
wasCollected(Context* c, object o)
|
||||
{
|
||||
return o and
|
||||
(not c->nextGen1.contains(o)) and
|
||||
(not c->nextGen2.contains(o)) and
|
||||
(c->nextGen1.contains(cast<object>(o, 0)) or
|
||||
c->nextGen2.contains(cast<object>(o, 0)));
|
||||
return o and (not fresh(c, o)) and fresh(c, cast<object>(o, 0));
|
||||
}
|
||||
|
||||
inline object
|
||||
@ -526,6 +537,10 @@ copy2(Context* c, object o)
|
||||
if (c->gen2.data == 0) initGen2(c);
|
||||
|
||||
if (c->gen2.remaining() >= size) {
|
||||
if (c->gen2Base == Top) {
|
||||
c->gen2Base = c->gen2.data + c->gen2.position;
|
||||
}
|
||||
|
||||
return copyTo(c, &(c->gen2), o, size);
|
||||
} else {
|
||||
c->mode = OverflowCollection;
|
||||
@ -557,7 +572,6 @@ copy(Context* c, object o)
|
||||
{
|
||||
object r = copy2(c, o);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "copy %p to %p\n", o, r);
|
||||
|
||||
// leave a pointer to the copy in the original
|
||||
@ -737,13 +751,11 @@ collect(Context* c, void** p)
|
||||
object original = *p;
|
||||
object parent = 0;
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "update %p at %p\n", *p, p);
|
||||
|
||||
bool needsVisit;
|
||||
*p = update(c, p, &needsVisit);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " result: %p (visit? %d)\n", *p, needsVisit);
|
||||
|
||||
if (not needsVisit) return;
|
||||
@ -765,7 +777,6 @@ collect(Context* c, void** p)
|
||||
{ }
|
||||
|
||||
virtual bool visit(unsigned offset) {
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " update %p at %p - offset %d from %p\n",
|
||||
cast<object>(copy, offset * BytesPerWord),
|
||||
&cast<object>(copy, offset * BytesPerWord),
|
||||
@ -776,7 +787,6 @@ collect(Context* c, void** p)
|
||||
object childCopy = update
|
||||
(c, &cast<object>(copy, offset * BytesPerWord), &needsVisit);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " result: %p (visit? %d)\n", childCopy, needsVisit);
|
||||
|
||||
++ total;
|
||||
@ -824,14 +834,12 @@ collect(Context* c, void** p)
|
||||
unsigned total;
|
||||
} walker(c, copy, bitset(c, original));
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "walk %p\n", copy);
|
||||
|
||||
c->client->walk(copy, &walker);
|
||||
|
||||
if (walker.visits) {
|
||||
// descend
|
||||
++ c->depth;
|
||||
if (walker.visits > 1) {
|
||||
::parent(c, original) = parent;
|
||||
parent = original;
|
||||
@ -842,7 +850,6 @@ collect(Context* c, void** p)
|
||||
goto visit;
|
||||
} else {
|
||||
// ascend
|
||||
-- c->depth;
|
||||
original = parent;
|
||||
}
|
||||
}
|
||||
@ -883,7 +890,6 @@ collect(Context* c, void** p)
|
||||
unsigned total;
|
||||
} walker(c, bitset(c, original));
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "scan %p\n", copy);
|
||||
|
||||
c->client->walk(copy, &walker);
|
||||
@ -896,7 +902,6 @@ collect(Context* c, void** p)
|
||||
parent = ::parent(c, original);
|
||||
}
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " next is %p at %p - offset %d from %p\n",
|
||||
cast<object>(copy, walker.next * BytesPerWord),
|
||||
&cast<object>(copy, walker.next * BytesPerWord),
|
||||
@ -1037,6 +1042,8 @@ collect(Context* c)
|
||||
{
|
||||
if (c->gen1.data == 0) initGen1(c);
|
||||
|
||||
c->gen2Base = Top;
|
||||
|
||||
switch (c->mode) {
|
||||
case MinorCollection: {
|
||||
initNextGen1(c);
|
||||
@ -1045,6 +1052,9 @@ collect(Context* c)
|
||||
|
||||
if (c->mode == OverflowCollection) {
|
||||
c->mode = Gen2Collection;
|
||||
|
||||
c->gen2Base = Top;
|
||||
|
||||
collect2(c);
|
||||
|
||||
c->gen2.replaceWith(&(c->nextGen2));
|
||||
@ -1094,7 +1104,6 @@ makeHeap(System* system)
|
||||
}
|
||||
|
||||
c.client = client;
|
||||
c.depth = 0;
|
||||
|
||||
::collect(&c);
|
||||
}
|
||||
@ -1114,12 +1123,10 @@ makeHeap(System* system)
|
||||
|
||||
virtual void* follow(void* p) {
|
||||
if (wasCollected(&c, p)) {
|
||||
indent(c.depth);
|
||||
fprintf(stderr, "follow: %p: %p\n", p, ::follow(&c, p));
|
||||
|
||||
return ::follow(&c, p);
|
||||
} else {
|
||||
//indent(c.depth);
|
||||
//fprintf(stderr, "follow: %p: %p\n", p, p);
|
||||
|
||||
return p;
|
||||
|
Loading…
x
Reference in New Issue
Block a user