mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
GC stress fixes
This commit is contained in:
parent
c94e70060f
commit
32dff71994
2
makefile
2
makefile
@ -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
|
||||||
|
62
src/heap.cpp
62
src/heap.cpp
@ -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");
|
||||||
|
@ -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*
|
||||||
|
@ -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
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user