mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian
This commit is contained in:
commit
68355b17cd
@ -97,8 +97,10 @@ public class WeakHashMap<K, V> implements Map<K, V> {
|
||||
public HashMap.Cell<K, V> next;
|
||||
public int hashCode;
|
||||
|
||||
public MyCell(K key, V value, HashMap.Cell<K, V> next, int hashCode) {
|
||||
super(key);
|
||||
public MyCell(K key, ReferenceQueue queue, V value,
|
||||
HashMap.Cell<K, V> next, int hashCode)
|
||||
{
|
||||
super(key, queue);
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
this.hashCode = hashCode;
|
||||
@ -129,11 +131,11 @@ public class WeakHashMap<K, V> implements Map<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyHelper<K, V>
|
||||
private class MyHelper<K, V>
|
||||
extends HashMap.MyHelper<K, V>
|
||||
{
|
||||
public HashMap.Cell<K, V> make(K key, V value, HashMap.Cell<K, V> next) {
|
||||
return new MyCell(key, value, next, hash(key));
|
||||
return new MyCell(key, queue, value, next, hash(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
and (className == 0 or strncmp(name, className, nameSize - 6) == 0))
|
||||
{
|
||||
// fprintf(stderr, "%.*s\n", nameSize - 6, name);
|
||||
object c = resolveClass
|
||||
object c = resolveSystemClass
|
||||
(t, makeByteArray(t, "%.*s", nameSize - 6, name));
|
||||
|
||||
if (t->exception) return 0;
|
||||
@ -399,7 +399,7 @@ main(int ac, const char** av)
|
||||
enter(t, Thread::ActiveState);
|
||||
enter(t, Thread::IdleState);
|
||||
|
||||
FILE* output = fopen(av[2], "wb");
|
||||
FILE* output = vm::fopen(av[2], "wb");
|
||||
if (output == 0) {
|
||||
fprintf(stderr, "unable to open %s\n", av[2]);
|
||||
return -1;
|
||||
|
@ -186,13 +186,13 @@ Avian_java_lang_ClassLoader_defineClass
|
||||
t->m->heap->free(buffer, length);
|
||||
|
||||
if (c) {
|
||||
if (classLoaderMap(t, loader) == 0) {
|
||||
if (getClassLoaderMap(t, loader) == 0) {
|
||||
PROTECT(t, c);
|
||||
object map = makeHashMap(t, 0, 0);
|
||||
set(t, loader, ClassLoaderMap, map);
|
||||
}
|
||||
|
||||
hashMapInsert(t, classLoaderMap(t, loader), className(t, c), c,
|
||||
hashMapInsert(t, getClassLoaderMap(t, loader), className(t, c), c,
|
||||
byteArrayHash);
|
||||
}
|
||||
|
||||
@ -711,7 +711,7 @@ Avian_avian_Machine_dumpHeap
|
||||
unsigned length = stringLength(t, outputFile);
|
||||
char n[length + 1];
|
||||
stringChars(t, outputFile, n);
|
||||
FILE* out = fopen(n, "wb");
|
||||
FILE* out = vm::fopen(n, "wb");
|
||||
if (out) {
|
||||
{ ENTER(t, Thread::ExclusiveState);
|
||||
dumpHeap(t, out);
|
||||
|
@ -7131,7 +7131,7 @@ fixupCode(Thread* t, uintptr_t* map, unsigned size, uint8_t* code,
|
||||
void
|
||||
fixupMethods(Thread* t, BootImage* image, uint8_t* code)
|
||||
{
|
||||
for (HashMapIterator it(t, classLoaderMap(t, t->m->loader)); it.hasMore();) {
|
||||
for (HashMapIterator it(t, t->m->classMap); it.hasMore();) {
|
||||
object c = tripleSecond(t, it.next());
|
||||
|
||||
if (classMethodTable(t, c)) {
|
||||
@ -7261,8 +7261,7 @@ boot(MyThread* t, BootImage* image)
|
||||
|
||||
syncInstructionCache(code, image->codeSize);
|
||||
|
||||
object classMap = makeClassMap(t, classTable, image->classCount, heap);
|
||||
set(t, t->m->loader, ClassLoaderMap, classMap);
|
||||
t->m->classMap = makeClassMap(t, classTable, image->classCount, heap);
|
||||
|
||||
t->m->stringMap = makeStringMap(t, stringTable, image->stringCount, heap);
|
||||
|
||||
|
@ -437,7 +437,7 @@ Avian_java_lang_VMClassLoader_findLoadedClass
|
||||
{
|
||||
object loader = reinterpret_cast<object>(arguments[0]);
|
||||
|
||||
object map = classLoaderMap(t, loader);
|
||||
object map = getClassLoaderMap(t, loader);
|
||||
if (map) {
|
||||
PROTECT(t, loader);
|
||||
|
||||
@ -452,7 +452,7 @@ Avian_java_lang_VMClassLoader_findLoadedClass
|
||||
|
||||
return reinterpret_cast<int64_t>
|
||||
(hashMapFind
|
||||
(t, classLoaderMap(t, loader), n, byteArrayHash, byteArrayEqual));
|
||||
(t, getClassLoaderMap(t, loader), n, byteArrayHash, byteArrayEqual));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
13
src/heap.cpp
13
src/heap.cpp
@ -1790,7 +1790,7 @@ class MyHeap: public Heap {
|
||||
if (c.client->isFixed(p)) {
|
||||
return fixie(p)->age >= FixieTenureThreshold;
|
||||
} else {
|
||||
return c.gen2.contains(p);
|
||||
return c.gen2.contains(p) or c.nextGen2.contains(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,6 +1802,7 @@ class MyHeap: public Heap {
|
||||
bool targetNeedsMark(void* target) {
|
||||
return target
|
||||
and not c.gen2.contains(target)
|
||||
and not c.nextGen2.contains(target)
|
||||
and not immortalHeapContains(&c, target)
|
||||
and not (c.client->isFixed(target)
|
||||
and fixie(target)->age >= FixieTenureThreshold);
|
||||
@ -1828,10 +1829,18 @@ class MyHeap: public Heap {
|
||||
|
||||
if (dirty) markDirty(&c, f);
|
||||
} else {
|
||||
Segment::Map* map;
|
||||
if (c.gen2.contains(p)) {
|
||||
map = &(c.heapMap);
|
||||
} else {
|
||||
assert(&c, c.nextGen2.contains(p));
|
||||
map = &(c.nextHeapMap);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
void** target = static_cast<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
c.heapMap.set(target);
|
||||
map->set(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
namespace local {
|
||||
|
||||
enum {
|
||||
Root,
|
||||
Size,
|
||||
@ -49,6 +51,8 @@ objectSize(Thread* t, object o)
|
||||
return extendedSize(t, o, baseSize(t, o, objectClass(t, o)));
|
||||
}
|
||||
|
||||
} // namespace local
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace vm {
|
||||
@ -61,24 +65,24 @@ dumpHeap(Thread* t, FILE* out)
|
||||
Visitor(Thread* t, FILE* out): t(t), out(out), nextNumber(1) { }
|
||||
|
||||
virtual void root() {
|
||||
write1(out, Root);
|
||||
write1(out, local::Root);
|
||||
}
|
||||
|
||||
virtual unsigned visitNew(object p) {
|
||||
if (p) {
|
||||
unsigned number = nextNumber++;
|
||||
write4(out, number);
|
||||
local::write4(out, number);
|
||||
|
||||
write1(out, Size);
|
||||
write4(out, objectSize(t, p));
|
||||
local::write1(out, local::Size);
|
||||
local::write4(out, local::objectSize(t, p));
|
||||
|
||||
if (objectClass(t, p) == arrayBody(t, t->m->types, Machine::ClassType))
|
||||
{
|
||||
object name = className(t, p);
|
||||
if (name) {
|
||||
write1(out, ClassName);
|
||||
writeString(out, &byteArrayBody(t, name, 0),
|
||||
byteArrayLength(t, name) - 1);
|
||||
local::write1(out, local::ClassName);
|
||||
local::writeString(out, &byteArrayBody(t, name, 0),
|
||||
byteArrayLength(t, name) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,15 +93,15 @@ dumpHeap(Thread* t, FILE* out)
|
||||
}
|
||||
|
||||
virtual void visitOld(object, unsigned number) {
|
||||
write4(out, number);
|
||||
local::write4(out, number);
|
||||
}
|
||||
|
||||
virtual void push(object, unsigned, unsigned) {
|
||||
write1(out, Push);
|
||||
local::write1(out, local::Push);
|
||||
}
|
||||
|
||||
virtual void pop() {
|
||||
write1(out, Pop);
|
||||
local::write1(out, local::Pop);
|
||||
}
|
||||
|
||||
Thread* t;
|
||||
|
@ -379,13 +379,15 @@ referenceTargetUnreachable(Thread* t, Heap::Visitor* v, object* p)
|
||||
void
|
||||
referenceUnreachable(Thread* t, Heap::Visitor* v, object* p)
|
||||
{
|
||||
object r = static_cast<object>(t->m->heap->follow(*p));
|
||||
|
||||
if (DebugReferences) {
|
||||
fprintf(stderr, "reference %p unreachable (target %p)\n",
|
||||
*p, jreferenceTarget(t, *p));
|
||||
*p, jreferenceTarget(t, r));
|
||||
}
|
||||
|
||||
if (jreferenceQueue(t, *p)
|
||||
and t->m->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable)
|
||||
if (jreferenceQueue(t, r)
|
||||
and t->m->heap->status(jreferenceQueue(t, r)) != Heap::Unreachable)
|
||||
{
|
||||
// queue is reachable - add the reference
|
||||
referenceTargetUnreachable(t, v, p);
|
||||
@ -458,7 +460,9 @@ postVisit(Thread* t, Heap::Visitor* v)
|
||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||
// reference is unreachable
|
||||
referenceUnreachable(t, v, p);
|
||||
} else if (m->heap->status(jreferenceTarget(t, *p))
|
||||
} else if (m->heap->status
|
||||
(jreferenceTarget
|
||||
(t, static_cast<object>(m->heap->follow(*p))))
|
||||
== Heap::Unreachable)
|
||||
{
|
||||
// target is unreachable
|
||||
@ -504,7 +508,9 @@ postVisit(Thread* t, Heap::Visitor* v)
|
||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||
// reference is unreachable
|
||||
referenceUnreachable(t, v, p);
|
||||
} else if (m->heap->status(jreferenceTarget(t, *p))
|
||||
} else if (m->heap->status
|
||||
(jreferenceTarget
|
||||
(t, static_cast<object>(m->heap->follow(*p))))
|
||||
== Heap::Unreachable)
|
||||
{
|
||||
// target is unreachable
|
||||
@ -1928,8 +1934,7 @@ boot(Thread* t)
|
||||
classVmFlags(t, arrayBody(t, m->types, Machine::JvoidType))
|
||||
|= PrimitiveFlag;
|
||||
|
||||
object classMap = makeHashMap(t, 0, 0);
|
||||
set(t, t->m->loader, ClassLoaderMap, classMap);
|
||||
m->classMap = makeHashMap(t, 0, 0);
|
||||
|
||||
m->bootstrapClassMap = makeHashMap(t, 0, 0);
|
||||
|
||||
@ -2064,6 +2069,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
||||
shutdownLock(0),
|
||||
libraries(0),
|
||||
loader(0),
|
||||
classMap(0),
|
||||
loadClassMethod(0),
|
||||
bootstrapClassMap(0),
|
||||
monitorMap(0),
|
||||
@ -2776,8 +2782,7 @@ findLoadedSystemClass(Thread* t, object spec)
|
||||
PROTECT(t, spec);
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
return hashMapFind(t, classLoaderMap(t, t->m->loader), spec, byteArrayHash,
|
||||
byteArrayEqual);
|
||||
return hashMapFind(t, t->m->classMap, spec, byteArrayHash, byteArrayEqual);
|
||||
}
|
||||
|
||||
object
|
||||
@ -2894,7 +2899,7 @@ resolveSystemClass(Thread* t, object spec)
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
object class_ = hashMapFind
|
||||
(t, classLoaderMap(t, t->m->loader), spec, byteArrayHash, byteArrayEqual);
|
||||
(t, t->m->classMap, spec, byteArrayHash, byteArrayEqual);
|
||||
|
||||
if (class_ == 0) {
|
||||
if (byteArrayBody(t, spec, 0) == '[') {
|
||||
@ -2944,8 +2949,7 @@ resolveSystemClass(Thread* t, object spec)
|
||||
if (class_) {
|
||||
PROTECT(t, class_);
|
||||
|
||||
hashMapInsert(t, classLoaderMap(t, t->m->loader), spec, class_,
|
||||
byteArrayHash);
|
||||
hashMapInsert(t, t->m->classMap, spec, class_, byteArrayHash);
|
||||
} else if (t->exception == 0) {
|
||||
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
|
||||
t->exception = makeClassNotFoundException(t, message);
|
||||
@ -3559,6 +3563,7 @@ void
|
||||
visitRoots(Machine* m, Heap::Visitor* v)
|
||||
{
|
||||
v->visit(&(m->loader));
|
||||
v->visit(&(m->classMap));
|
||||
v->visit(&(m->loadClassMethod));
|
||||
v->visit(&(m->bootstrapClassMap));
|
||||
v->visit(&(m->monitorMap));
|
||||
@ -3693,6 +3698,8 @@ runJavaThread(Thread* t)
|
||||
void
|
||||
runFinalizeThread(Thread* t)
|
||||
{
|
||||
fprintf(stderr, "run finalize thread\n");
|
||||
|
||||
setDaemon(t, t->javaThread, true);
|
||||
|
||||
object list = 0;
|
||||
@ -3707,6 +3714,8 @@ runFinalizeThread(Thread* t)
|
||||
}
|
||||
|
||||
if (t->m->finalizeThread == 0) {
|
||||
fprintf(stderr, "exit finalize thread\n");
|
||||
|
||||
return;
|
||||
} else {
|
||||
list = t->m->objectsToFinalize;
|
||||
|
@ -1189,6 +1189,7 @@ class Machine {
|
||||
System::Monitor* shutdownLock;
|
||||
System::Library* libraries;
|
||||
object loader;
|
||||
object classMap;
|
||||
object loadClassMethod;
|
||||
object bootstrapClassMap;
|
||||
object monitorMap;
|
||||
@ -1658,6 +1659,16 @@ instanceOf(Thread* t, object class_, object o);
|
||||
|
||||
#include "type-declarations.cpp"
|
||||
|
||||
inline object
|
||||
getClassLoaderMap(Thread* t, object loader)
|
||||
{
|
||||
if (loader == t->m->loader) {
|
||||
return t->m->classMap;
|
||||
} else {
|
||||
return classLoaderMap(t, loader);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
objectFixed(Thread*, object o)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@ import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class References {
|
||||
public static void main(String[] args) {
|
||||
@ -9,6 +10,8 @@ public class References {
|
||||
Object b = new Object();
|
||||
Object c = new Object();
|
||||
Object d = new Object();
|
||||
Object e = new Object();
|
||||
Object f = new Object();
|
||||
|
||||
ReferenceQueue q = new ReferenceQueue();
|
||||
|
||||
@ -16,21 +19,54 @@ public class References {
|
||||
Reference br = new WeakReference(b, q);
|
||||
Reference cr = new WeakReference(c, q);
|
||||
Reference dr = new PhantomReference(d, q);
|
||||
Reference er = new MyReference(e, q, "foo");
|
||||
|
||||
WeakHashMap<Key,Object> map = new WeakHashMap();
|
||||
map.put(new Key("foo"), f);
|
||||
|
||||
a = b = c = d = cr = null;
|
||||
a = b = c = d = e = cr = null;
|
||||
|
||||
System.out.println("a: " + ar.get());
|
||||
System.out.println("b: " + br.get());
|
||||
System.out.println("d: " + dr.get());
|
||||
System.out.println("e: " + er.get());
|
||||
System.out.println("f: " + map.get(new Key("foo")));
|
||||
|
||||
System.gc();
|
||||
|
||||
System.out.println("a: " + ar.get());
|
||||
System.out.println("b: " + br.get());
|
||||
System.out.println("d: " + dr.get());
|
||||
System.out.println("e: " + er.get());
|
||||
System.out.println("f: " + map.get(new Key("foo")));
|
||||
|
||||
for (Reference r = q.poll(); r != null; r = q.poll()) {
|
||||
System.out.println("polled: " + r.get());
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyReference extends WeakReference {
|
||||
private final Object foo;
|
||||
|
||||
public MyReference(Object target, ReferenceQueue queue, Object foo) {
|
||||
super(target, queue);
|
||||
this.foo = foo;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Key {
|
||||
private final String name;
|
||||
|
||||
public Key(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Key && ((Key) o).name.equals(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user