mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
sketch of finalizer/weak reference overhaul; type generator bugfixes involving array member layout
This commit is contained in:
parent
a77693fb29
commit
b70e4b368f
@ -83,8 +83,8 @@ arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sl = cast<uint32_t>(s, offset * BytesPerWord);
|
||||
int32_t dl = cast<uint32_t>(d, offset * BytesPerWord);
|
||||
intptr_t sl = cast<uintptr_t>(s, offset * BytesPerWord);
|
||||
intptr_t dl = cast<uintptr_t>(d, offset * BytesPerWord);
|
||||
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
|
||||
dstOffset >= 0 and dstOffset + length < dl))
|
||||
{
|
||||
|
25
src/heap.cpp
25
src/heap.cpp
@ -1412,6 +1412,31 @@ makeHeap(System* system)
|
||||
}
|
||||
}
|
||||
|
||||
virtual Status status(void* p) {
|
||||
p = mask(p);
|
||||
|
||||
if (c.nextGen1.contains(p)) {
|
||||
return Reachable;
|
||||
} else if (c.nextGen2.contains(p)
|
||||
or (c.gen2.contains(p)
|
||||
and c.gen2.indexOf(p) >= c.gen2Base))
|
||||
{
|
||||
return Tenured;
|
||||
} else if (wasCollected(&c, p)) {
|
||||
return Reachable;
|
||||
} else {
|
||||
return Unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
virtual CollectionType collectionType() {
|
||||
if (c.mode == ::MinorCollection) {
|
||||
return MinorCollection;
|
||||
} else {
|
||||
return MajorCollection;
|
||||
}
|
||||
}
|
||||
|
||||
Context c;
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,12 @@ class Heap {
|
||||
MajorCollection
|
||||
};
|
||||
|
||||
enum Status {
|
||||
Reachable,
|
||||
Unreachable,
|
||||
Tenured
|
||||
};
|
||||
|
||||
class Visitor {
|
||||
public:
|
||||
virtual ~Visitor() { }
|
||||
@ -39,6 +45,8 @@ class Heap {
|
||||
virtual bool needsMark(void** p) = 0;
|
||||
virtual void mark(void** p) = 0;
|
||||
virtual void* follow(void* p) = 0;
|
||||
virtual Status status(void* p) = 0;
|
||||
virtual CollectionType collectionType() = 0;
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
|
189
src/machine.cpp
189
src/machine.cpp
@ -127,6 +127,145 @@ visitRoots(Thread* t, Heap::Visitor* v)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
postVisit(Thread* t, Heap::Visitor* v)
|
||||
{
|
||||
Machine* m = t->vm;
|
||||
|
||||
object firstNewTenuredFinalizer = 0;
|
||||
object lastNewTenuredFinalizer = 0;
|
||||
|
||||
for (object* p = &(m->finalizers); *p;) {
|
||||
v->visit(p);
|
||||
|
||||
if (m->heap->status(finalizerTarget(t, *p)) == Heap::Unreachable) {
|
||||
// target is unreachable - queue it up for finalization
|
||||
|
||||
v->visit(&finalizerTarget(t, *p));
|
||||
|
||||
object finalizer = *p;
|
||||
*p = finalizerNext(t, finalizer);
|
||||
finalizerNext(t, finalizer) = m->finalizeQueue;
|
||||
m->finalizeQueue = finalizer;
|
||||
} else {
|
||||
// target is reachable
|
||||
|
||||
v->visit(&finalizerTarget(t, *p));
|
||||
|
||||
if (m->heap->status(*p) == Heap::Tenured) {
|
||||
// the finalizer is tenured, so we remove it from
|
||||
// m->finalizers and later add it to m->tenuredFinalizers
|
||||
|
||||
if (lastNewTenuredFinalizer == 0) {
|
||||
lastNewTenuredFinalizer = *p;
|
||||
}
|
||||
|
||||
object finalizer = *p;
|
||||
*p = finalizerNext(t, finalizer);
|
||||
finalizerNext(t, finalizer) = firstNewTenuredFinalizer;
|
||||
firstNewTenuredFinalizer = finalizer;
|
||||
} else {
|
||||
p = &finalizerNext(t, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object firstNewTenuredWeakReference = 0;
|
||||
object lastNewTenuredWeakReference = 0;
|
||||
|
||||
for (object* p = &(m->weakReferences); *p;) {
|
||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||
// reference is unreachable - remove it from the list
|
||||
|
||||
*p = jreferenceNext(t, *p);
|
||||
} else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) {
|
||||
// target is unreachable - clear the reference and remove it
|
||||
// from the list
|
||||
|
||||
jreferenceTarget(t, *p) = 0;
|
||||
*p = jreferenceNext(t, *p);
|
||||
} else {
|
||||
// both reference and target are reachable
|
||||
|
||||
v->visit(&jreferenceTarget(t, *p));
|
||||
v->visit(p);
|
||||
|
||||
if (m->heap->status(*p) == Heap::Tenured) {
|
||||
// the reference is tenured, so we remove it from
|
||||
// m->weakReferences and later add it to
|
||||
// m->tenuredWeakReferences
|
||||
|
||||
if (lastNewTenuredWeakReference == 0) {
|
||||
lastNewTenuredWeakReference = *p;
|
||||
}
|
||||
|
||||
object reference = *p;
|
||||
*p = jreferenceNext(t, reference);
|
||||
jreferenceNext(t, reference) = firstNewTenuredWeakReference;
|
||||
firstNewTenuredWeakReference = reference;
|
||||
} else {
|
||||
p = &jreferenceNext(t, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m->heap->collectionType() == Heap::MajorCollection) {
|
||||
for (object* p = &(m->tenuredFinalizers); *p;) {
|
||||
v->visit(p);
|
||||
|
||||
if (m->heap->status(finalizerTarget(t, *p)) == Heap::Unreachable) {
|
||||
// target is unreachable - queue it up for finalization
|
||||
|
||||
v->visit(&finalizerTarget(t, *p));
|
||||
|
||||
object finalizer = *p;
|
||||
*p = finalizerNext(t, finalizer);
|
||||
finalizerNext(t, finalizer) = m->finalizeQueue;
|
||||
m->finalizeQueue = finalizer;
|
||||
} else {
|
||||
// target is reachable
|
||||
|
||||
v->visit(&finalizerTarget(t, *p));
|
||||
|
||||
p = &finalizerNext(t, *p);
|
||||
}
|
||||
}
|
||||
|
||||
for (object* p = &(m->tenuredWeakReferences); *p;) {
|
||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||
// reference is unreachable - remove it from the list
|
||||
|
||||
*p = jreferenceNext(t, *p);
|
||||
} else if (m->heap->status(jreferenceTarget(t, *p))
|
||||
== Heap::Unreachable)
|
||||
{
|
||||
// target is unreachable - clear the reference and remove it
|
||||
// from the list
|
||||
|
||||
jreferenceTarget(t, *p) = 0;
|
||||
*p = jreferenceNext(t, *p);
|
||||
} else {
|
||||
// target is reachable
|
||||
|
||||
v->visit(&jreferenceTarget(t, *p));
|
||||
v->visit(p);
|
||||
|
||||
p = &jreferenceNext(t, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastNewTenuredFinalizer) {
|
||||
finalizerNext(t, lastNewTenuredFinalizer) = m->tenuredFinalizers;
|
||||
m->tenuredFinalizers = lastNewTenuredFinalizer;
|
||||
}
|
||||
|
||||
if (lastNewTenuredWeakReference) {
|
||||
jreferenceNext(t, lastNewTenuredWeakReference) = m->tenuredWeakReferences;
|
||||
m->tenuredWeakReferences = lastNewTenuredWeakReference;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
postCollect(Thread* t)
|
||||
{
|
||||
@ -160,37 +299,7 @@ collect(Thread* t, Heap::CollectionType type)
|
||||
::visitRoots(t, v);
|
||||
}
|
||||
|
||||
Thread* t = m->rootThread;
|
||||
for (object* f = &(m->finalizers); *f;) {
|
||||
object o = finalizerTarget(t, *f);
|
||||
if (m->heap->follow(o) == o) {
|
||||
// object has not been collected
|
||||
object x = *f;
|
||||
*f = finalizerNext(t, x);
|
||||
finalizerNext(t, x) = m->doomed;
|
||||
m->doomed = x;
|
||||
} else {
|
||||
f = &finalizerNext(t, *f);
|
||||
}
|
||||
}
|
||||
|
||||
v->visit(&(m->finalizers));
|
||||
v->visit(&(m->doomed));
|
||||
|
||||
for (object p = m->weakReferences; p;) {
|
||||
object o = jreferenceTarget(t, p);
|
||||
object followed = m->heap->follow(o);
|
||||
if (followed == o) {
|
||||
// object has not been collected
|
||||
jreferenceTarget(t, p) = 0;
|
||||
} else {
|
||||
jreferenceTarget(t, p) = followed;
|
||||
}
|
||||
|
||||
object last = p;
|
||||
p = jreferenceNext(t, p);
|
||||
jreferenceNext(t, last) = 0;
|
||||
}
|
||||
postVisit(m->rootThread, v);
|
||||
}
|
||||
|
||||
virtual unsigned sizeInWords(object o) {
|
||||
@ -256,7 +365,8 @@ collect(Thread* t, Heap::CollectionType type)
|
||||
unsigned fixedSize = classFixedSize(t, class_);
|
||||
unsigned arrayElementSize = classArrayElementSize(t, class_);
|
||||
unsigned arrayLength
|
||||
= (arrayElementSize ? cast<uint32_t>(p, fixedSize - 4) : 0);
|
||||
= (arrayElementSize ?
|
||||
cast<uintptr_t>(p, fixedSize - BytesPerWord) : 0);
|
||||
|
||||
int mask[intArrayLength(t, objectMask)];
|
||||
memcpy(mask, &intArrayBody(t, objectMask, 0),
|
||||
@ -317,13 +427,11 @@ collect(Thread* t, Heap::CollectionType type)
|
||||
|
||||
postCollect(m->rootThread);
|
||||
|
||||
for (object f = m->doomed; f; f = finalizerNext(t, f)) {
|
||||
for (object f = m->finalizeQueue; f; f = finalizerNext(t, f)) {
|
||||
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
|
||||
(t, finalizerTarget(t, f));
|
||||
}
|
||||
m->doomed = 0;
|
||||
|
||||
m->weakReferences = 0;
|
||||
m->finalizeQueue = 0;
|
||||
|
||||
killZombies(t, m->rootThread);
|
||||
}
|
||||
@ -372,8 +480,9 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
||||
monitorMap(0),
|
||||
types(0),
|
||||
finalizers(0),
|
||||
doomed(0),
|
||||
weakReferences(0),
|
||||
tenuredFinalizers(0),
|
||||
finalizeQueue(0),
|
||||
tenuredWeakReferences(0),
|
||||
unsafe(false)
|
||||
{
|
||||
jni::populate(&jniEnvVTable);
|
||||
@ -912,6 +1021,10 @@ objectMonitor(Thread* t, object o)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
noop()
|
||||
{ }
|
||||
|
||||
#include "type-constructors.cpp"
|
||||
|
||||
} // namespace vm
|
||||
|
@ -1076,6 +1076,9 @@ strcmp(const int8_t* a, const int8_t* b)
|
||||
reinterpret_cast<const char*>(b));
|
||||
}
|
||||
|
||||
void
|
||||
noop();
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
enum {
|
||||
@ -1108,8 +1111,10 @@ class Machine {
|
||||
object monitorMap;
|
||||
object types;
|
||||
object finalizers;
|
||||
object doomed;
|
||||
object tenuredFinalizers;
|
||||
object finalizeQueue;
|
||||
object weakReferences;
|
||||
object tenuredWeakReferences;
|
||||
bool unsafe;
|
||||
JNIEnvVTable jniEnvVTable;
|
||||
};
|
||||
@ -1639,9 +1644,16 @@ hash(const int8_t* s, unsigned length)
|
||||
inline unsigned
|
||||
baseSize(Thread* t, object o, object class_)
|
||||
{
|
||||
if (classArrayElementSize(t, class_)) {
|
||||
noop();
|
||||
if (cast<uintptr_t>(o, classFixedSize(t, class_) - BytesPerWord)) {
|
||||
noop();
|
||||
}
|
||||
}
|
||||
|
||||
return divide(classFixedSize(t, class_), BytesPerWord)
|
||||
+ divide(classArrayElementSize(t, class_)
|
||||
* cast<uint32_t>(o, classFixedSize(t, class_) - 4),
|
||||
* cast<uintptr_t>(o, classFixedSize(t, class_) - BytesPerWord),
|
||||
BytesPerWord);
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ addMember(Object* o, Object* member)
|
||||
case Object::Type: case Object::Pod:
|
||||
if (member->type == Object::Array) {
|
||||
static_cast<Type*>(o)->members.append
|
||||
(Scalar::make(o, 0, "uint32_t", "length", sizeof(uint32_t)));
|
||||
(Scalar::make(o, 0, "uintptr_t", "length", sizeof(uintptr_t)));
|
||||
}
|
||||
static_cast<Type*>(o)->members.append(member);
|
||||
break;
|
||||
@ -1390,7 +1390,7 @@ typeFixedSize(Object* type)
|
||||
Object* m = it.next();
|
||||
switch (m->type) {
|
||||
case Object::Scalar: {
|
||||
length = pad(it.offset() + it.space());
|
||||
length = pad(it.offset() + it.size());
|
||||
} break;
|
||||
|
||||
case Object::Array: break;
|
||||
@ -1521,7 +1521,7 @@ writeInitializations(Output* out, Object* declarations)
|
||||
|
||||
out->write("t->vm->types = allocate(t, pad((");
|
||||
out->write(count);
|
||||
out->write(" * sizeof(void*)) + 4 + sizeof(void*)));\n");
|
||||
out->write(" * sizeof(void*)) + sizeof(uintptr_t) + sizeof(void*)));\n");
|
||||
out->write("cast<object>(t->vm->types, 0) = 0;\n");
|
||||
out->write("arrayLength(t, t->vm->types) = ");
|
||||
out->write(count);
|
||||
|
@ -80,9 +80,9 @@
|
||||
(object third))
|
||||
|
||||
(type finalizer
|
||||
(object target)
|
||||
(void* target)
|
||||
(void* finalize)
|
||||
(object next))
|
||||
(void* next))
|
||||
|
||||
(type hashMap
|
||||
(uint32_t size)
|
||||
|
Loading…
Reference in New Issue
Block a user