GC stress fixes

This commit is contained in:
Joel Dice 2007-07-19 17:45:44 -06:00
parent c94e70060f
commit 32dff71994
6 changed files with 61 additions and 42 deletions

View File

@ -16,7 +16,7 @@ src = src
classpath = classpath classpath = classpath
test = test test = test
input = $(cls)/Threads.class input = $(cls)/Exceptions.class
cxx = g++ cxx = g++
cc = gcc cc = gcc

View File

@ -124,20 +124,20 @@ class Segment {
unsigned scale; unsigned scale;
bool clearNewData; bool clearNewData;
Map(Segment* segment = 0, unsigned bitsPerRecord = 1, Map(Segment* segment, unsigned bitsPerRecord = 1, unsigned scale = 1,
unsigned scale = 1, Map* child = 0, bool clearNewData = true): Map* child = 0, bool clearNewData = true):
segment(segment), segment(segment),
child(child), child(child),
bitsPerRecord(bitsPerRecord), bitsPerRecord(bitsPerRecord),
scale(scale), scale(scale),
clearNewData(clearNewData) clearNewData(clearNewData)
{ { }
if (segment) {
void check() {
assert(segment->context, bitsPerRecord); assert(segment->context, bitsPerRecord);
assert(segment->context, scale); assert(segment->context, scale);
assert(segment->context, powerOfTwo(scale)); assert(segment->context, powerOfTwo(scale));
} }
}
void replaceWith(Map* m) { void replaceWith(Map* m) {
assert(segment->context, bitsPerRecord == m->bitsPerRecord); assert(segment->context, bitsPerRecord == m->bitsPerRecord);
@ -273,12 +273,6 @@ class Segment {
if (child) n += child->footprint(capacity); if (child) n += child->footprint(capacity);
return n; return n;
} }
void setSegment(Segment* s) {
segment = s;
if (child) child->setSegment(s);
}
}; };
class Chain { class Chain {
@ -369,11 +363,11 @@ class Segment {
front = rear = Chain::make(this, minimum, desired); front = rear = Chain::make(this, minimum, desired);
if (map) { if (map) {
map->check();
if (map->clearNewData) { if (map->clearNewData) {
memset(front->data() + front->capacity, 0, memset(front->data() + front->capacity, 0,
map->footprint(front->capacity) * BytesPerWord); map->footprint(front->capacity) * BytesPerWord);
} }
map->setSegment(this);
} }
} }
} }
@ -422,11 +416,10 @@ class Segment {
if (s->map) { if (s->map) {
if (map) { if (map) {
map->replaceWith(s->map); map->replaceWith(s->map);
} else {
map = s->map;
map->setSegment(this);
}
s->map = 0; s->map = 0;
} else {
abort(context);
}
} else { } else {
map = 0; map = 0;
} }
@ -540,10 +533,23 @@ class Context {
Context(System* system): Context(System* system):
system(system), system(system),
client(0), client(0),
gen1(this, 0, 0),
nextGen1(this, 0, 0), ageMap(&gen1, log(TenureThreshold), 1, 0, false),
gen2(this, 0, 0), gen1(this, 0, 0, &ageMap),
nextGen2(this, 0, 0)
nextAgeMap(&nextGen1, log(TenureThreshold), 1, 0, false),
nextGen1(this, 0, 0, &nextAgeMap),
pointerMap(&gen2),
pageMap(&gen2, 1, LikelyPageSizeInBytes / BytesPerWord, &pointerMap),
heapMap(&gen2, 1, pageMap.scale * 1024, &pageMap),
gen2(this, 0, 0, &heapMap),
nextPointerMap(&nextGen2),
nextPageMap(&nextGen2, 1, LikelyPageSizeInBytes / BytesPerWord,
&nextPointerMap),
nextHeapMap(&nextGen2, 1, nextPageMap.scale * 1024, &nextPageMap),
nextGen2(this, 0, 0, &nextHeapMap)
{ } { }
void dispose() { void dispose() {
@ -556,23 +562,23 @@ class Context {
System* system; System* system;
Heap::Client* client; Heap::Client* client;
Segment gen1;
Segment nextGen1;
Segment gen2;
Segment nextGen2;
unsigned gen2Base;
Segment::Map ageMap; Segment::Map ageMap;
Segment gen1;
Segment::Map nextAgeMap; Segment::Map nextAgeMap;
Segment nextGen1;
Segment::Map pointerMap; Segment::Map pointerMap;
Segment::Map pageMap; Segment::Map pageMap;
Segment::Map heapMap; Segment::Map heapMap;
Segment gen2;
Segment::Map nextPointerMap; Segment::Map nextPointerMap;
Segment::Map nextPageMap; Segment::Map nextPageMap;
Segment::Map nextHeapMap; Segment::Map nextHeapMap;
Segment nextGen2;
unsigned gen2Base;
CollectionMode mode; CollectionMode mode;
}; };
@ -1350,7 +1356,9 @@ collect(Context* c)
initNextGen1(c); initNextGen1(c);
initNextGen2(c); initNextGen2(c);
if (c->gen2.position()) {
c->heapMap.clear(); c->heapMap.clear();
}
if (Verbose) { if (Verbose) {
fprintf(stderr, "major collection\n"); fprintf(stderr, "major collection\n");

View File

@ -730,6 +730,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object object
parseCode(Thread* t, Stream& s, object pool) parseCode(Thread* t, Stream& s, object pool)
{ {
PROTECT(t, pool);
unsigned maxStack = s.read2(); unsigned maxStack = s.read2();
unsigned maxLocals = s.read2(); unsigned maxLocals = s.read2();
unsigned length = s.read4(); unsigned length = s.read4();
@ -1017,6 +1019,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
s.read2(); // major version s.read2(); // major version
object pool = parsePool(t, s); object pool = parsePool(t, s);
PROTECT(t, pool);
unsigned flags = s.read2(); unsigned flags = s.read2();
unsigned name = s.read2(); unsigned name = s.read2();
@ -1728,15 +1731,17 @@ hashMapInsert(Thread* t, object map, object key, object value,
} }
unsigned index = hash(t, key) & (arrayLength(t, array) - 1); unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
object n = arrayBody(t, array, index);
if (weak) { if (weak) {
PROTECT(t, key);
PROTECT(t, value); PROTECT(t, value);
key = makeWeakReference(t, key, t->vm->weakReferences);
t->vm->weakReferences = key; t->vm->weakReferences = makeWeakReference(t, 0, t->vm->weakReferences);
jreferenceTarget(t, t->vm->weakReferences) = key;
key = t->vm->weakReferences;
} }
n = makeTriple(t, key, value, n); object n = makeTriple(t, key, value, arrayBody(t, array, index));
set(t, arrayBody(t, array, index), n); set(t, arrayBody(t, array, index), n);
} }
@ -1767,6 +1772,7 @@ hashMapRemove(Thread* t, object map, object key,
} }
if (hashMapSize(t, map) <= arrayLength(t, array) / 3) { if (hashMapSize(t, map) <= arrayLength(t, array) / 3) {
PROTECT(t, o);
hashMapResize(t, map, hash, arrayLength(t, array) / 2); hashMapResize(t, map, hash, arrayLength(t, array) / 2);
} }
} }
@ -2054,7 +2060,8 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
ACQUIRE(t, t->vm->finalizerLock); ACQUIRE(t, t->vm->finalizerLock);
t->vm->finalizers = makeFinalizer t->vm->finalizers = makeFinalizer
(t, target, reinterpret_cast<void*>(finalize), t->vm->finalizers); (t, 0, reinterpret_cast<void*>(finalize), t->vm->finalizers);
finalizerTarget(t, t->vm->finalizers) = target;
} }
System::Monitor* System::Monitor*

View File

@ -1954,8 +1954,6 @@ objectMonitor(Thread* t, object o);
inline void inline void
acquire(Thread* t, object o) acquire(Thread* t, object o)
{ {
stress(t);
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o);
if (DebugMonitors) { if (DebugMonitors) {
@ -1967,6 +1965,8 @@ acquire(Thread* t, object o)
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
m->acquire(t); m->acquire(t);
} }
stress(t);
} }
inline void inline void
@ -1985,8 +1985,6 @@ release(Thread* t, object o)
inline void inline void
wait(Thread* t, object o, int64_t milliseconds) wait(Thread* t, object o, int64_t milliseconds)
{ {
stress(t);
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o);
if (DebugMonitors) { if (DebugMonitors) {
@ -2005,6 +2003,8 @@ wait(Thread* t, object o, int64_t milliseconds)
fprintf(stderr, "thread %p wakes up on %p for %x\n", fprintf(stderr, "thread %p wakes up on %p for %x\n",
t, m, objectHash(t, o)); t, m, objectHash(t, o));
} }
stress(t);
} }
inline void inline void

View File

@ -391,6 +391,8 @@ checkStack(Thread* t, object method)
unsigned unsigned
invokeNative(Thread* t, object method) invokeNative(Thread* t, object method)
{ {
PROTECT(t, method);
object data = resolveNativeMethodData(t, method); object data = resolveNativeMethodData(t, method);
if (UNLIKELY(t->exception)) { if (UNLIKELY(t->exception)) {
return VoidField; return VoidField;
@ -2156,7 +2158,9 @@ run(Thread* t)
} }
if (catchType) { if (catchType) {
PROTECT(t, eht);
catchType = resolveClass(t, catchType); catchType = resolveClass(t, catchType);
eh = exceptionHandlerTableBody(t, eht, i);
} }
if (catchType == 0 or instanceOf(t, catchType, exception)) { if (catchType == 0 or instanceOf(t, catchType, exception)) {

View File

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
log=build/log.txt log=build/log.txt
vg="valgrind --leak-check=full --num-callers=32 --db-attach=yes \ vg="nice valgrind --leak-check=full --num-callers=32 \
--freelist-vol=100000000" --freelist-vol=100000000 --error-exitcode=1"
vm=${1}; shift vm=${1}; shift
mode=${1}; shift mode=${1}; shift