finish java/lang/ref/* support; add wrapper classes for primitives

This commit is contained in:
Joel Dice 2007-07-19 21:18:25 -06:00
parent faf9b63798
commit de9213ce30
21 changed files with 218 additions and 28 deletions

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Boolean {
private final boolean value;
public Boolean(boolean value) {
this.value = value;
}
public boolean booleanValue() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Byte {
private final byte value;
public Byte(byte value) {
this.value = value;
}
public byte byteValue() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Character {
private final char value;
public Character(char value) {
this.value = value;
}
public char charValue() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Double {
private final double value;
public Double(double value) {
this.value = value;
}
public double doubleValue() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Float {
private final float value;
public Float(float value) {
this.value = value;
}
public float floatValue() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Integer {
private final int value;
public Integer(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}

View File

@ -1,6 +1,6 @@
package java.lang;
public class Long {
public final class Long {
private final long value;
public Long(long value) {

View File

@ -0,0 +1,13 @@
package java.lang;
public final class Short {
private final short value;
public Short(short value) {
this.value = value;
}
public short shortValue() {
return value;
}
}

View File

@ -10,14 +10,16 @@ public class StringBuilder {
return this;
}
public StringBuilder append(Object o) {
return append(o == null ? "null" : o.toString());
}
public StringBuilder append(int v) {
append(String.valueOf(v));
return this;
return append(String.valueOf(v));
}
public StringBuilder append(long v) {
append(String.valueOf(v));
return this;
return append(String.valueOf(v));
}
public String toString() {

View File

@ -15,6 +15,8 @@ public abstract class System {
public static native String getProperty(String name);
public static native void gc();
public static class Output {
public synchronized native void print(String s);

View File

@ -0,0 +1,5 @@
package java.lang;
public final class Void {
}

View File

@ -4,7 +4,7 @@ public abstract class Reference<T> {
private T target;
private ReferenceQueue<? super T> queue;
private Object vmNext;
Reference<? extends T> next;
Reference next;
protected Reference(T target, ReferenceQueue<? super T> queue) {
this.target = target;
@ -16,7 +16,7 @@ public abstract class Reference<T> {
}
public void clear() {
target = 0;
target = null;
}
public boolean isEnqueued() {

View File

@ -1,6 +1,6 @@
package java.lang.ref;
public abstract class ReferenceQueue<T> {
public class ReferenceQueue<T> {
private Reference<? extends T> front;
private Reference<? extends T> rear;

View File

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

View File

@ -106,6 +106,14 @@ arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
t->exception = makeArrayStoreException(t);
}
void
gc(Thread* t)
{
ENTER(t, Thread::ExclusiveState);
collect(t, Heap::MajorCollection);
}
jobject
trace(Thread* t, jint skipCount)
{
@ -217,6 +225,8 @@ populate(Thread* t, object map)
reinterpret_cast<void*>(arraycopy) },
{ "Java_java_lang_System_loadLibrary",
reinterpret_cast<void*>(loadLibrary) },
{ "Java_java_lang_System_gc",
reinterpret_cast<void*>(gc) },
{ "Java_java_lang_Thread_start",
reinterpret_cast<void*>(start) },

View File

@ -1438,7 +1438,9 @@ makeHeap(System* system)
virtual Status status(void* p) {
p = mask(p);
if (c.nextGen1.contains(p)) {
if (p == 0) {
return Null;
} else if (c.nextGen1.contains(p)) {
return Reachable;
} else if (c.nextGen2.contains(p)
or (c.gen2.contains(p)

View File

@ -13,6 +13,7 @@ class Heap {
};
enum Status {
Null,
Reachable,
Unreachable,
Tenured

View File

@ -142,7 +142,9 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
v->visit(p);
jreferenceTarget(t, *p) = 0;
if (t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) {
if (jreferenceQueue(t, *p)
and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable)
{
// queue is reachable - add the reference
v->visit(&jreferenceQueue(t, *p));
@ -161,6 +163,17 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
}
}
void
referenceUnreachable(Thread* t, object* p, Heap::Visitor* v)
{
if (jreferenceQueue(t, *p)
and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable)
{
// queue is reachable - add the reference
referenceTargetUnreachable(t, p, v);
}
}
void
referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v)
{
@ -222,12 +235,12 @@ postVisit(Thread* t, Heap::Visitor* v)
for (object* p = &(m->weakReferences); *p;) {
if (m->heap->status(*p) == Heap::Unreachable) {
// reference is unreachable - remove it from the list
// reference is unreachable
referenceUnreachable(t, p, v);
*p = jreferenceNext(t, *p);
} else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) {
// target is unreachable - clear the reference, remove it from
// the list, and enqueue it if it has a live reference queue
// target is unreachable
referenceTargetUnreachable(t, p, v);
*p = jreferenceNext(t, *p);
@ -279,19 +292,19 @@ postVisit(Thread* t, Heap::Visitor* v)
for (object* p = &(m->tenuredWeakReferences); *p;) {
if (m->heap->status(*p) == Heap::Unreachable) {
// reference is unreachable - remove it from the list
// reference is unreachable
referenceUnreachable(t, p, v);
*p = jreferenceNext(t, *p);
} else if (m->heap->status(jreferenceTarget(t, *p))
== Heap::Unreachable)
{
// target is unreachable - clear the reference, remove it from
// the list, and enqueue it if it has a live reference queue
// target is unreachable
referenceTargetUnreachable(t, p, v);
*p = jreferenceNext(t, *p);
} else {
// target is reachable
// both reference and target are reachable
referenceTargetReachable(t, p, v);
p = &jreferenceNext(t, *p);
@ -1106,7 +1119,9 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
// verify that the classes have the same layout
expect(t, classSuper(t, bootstrapClass) == classSuper(t, class_));
expect(t, classFixedSize(t, bootstrapClass) == classFixedSize(t, class_));
expect(t, (classObjectMask(t, bootstrapClass) == 0
expect(t,
(classVmFlags(t, bootstrapClass) & ReferenceFlag)
or (classObjectMask(t, bootstrapClass) == 0
and classObjectMask(t, class_) == 0)
or intArrayEqual(t, classObjectMask(t, bootstrapClass),
classObjectMask(t, class_)));
@ -1243,7 +1258,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
stateLock(0),
heapLock(0),
classLock(0),
finalizerLock(0),
referenceLock(0),
libraries(0),
classMap(0),
bootstrapClassMap(0),
@ -1262,7 +1277,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
if (not system->success(system->make(&stateLock)) or
not system->success(system->make(&heapLock)) or
not system->success(system->make(&classLock)) or
not system->success(system->make(&finalizerLock)))
not system->success(system->make(&referenceLock)))
{
system->abort();
}
@ -1274,7 +1289,7 @@ Machine::dispose()
stateLock->dispose();
heapLock->dispose();
classLock->dispose();
finalizerLock->dispose();
referenceLock->dispose();
if (libraries) {
libraries->dispose();
@ -1339,6 +1354,13 @@ Thread::Thread(Machine* m, Allocator* allocator, object javaThread,
m->unsafe = false;
classVmFlags(t, arrayBody(t, m->types, Machine::JreferenceType))
|= ReferenceFlag;
classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType))
|= ReferenceFlag | WeakReferenceFlag;
classVmFlags(t, arrayBody(t, m->types, Machine::PhantomReferenceType))
|= ReferenceFlag | WeakReferenceFlag;
m->bootstrapClassMap = makeHashMap(this, NormalMap, 0, 0);
#include "type-java-initializations.cpp"
@ -2090,7 +2112,7 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
{
PROTECT(t, target);
ACQUIRE(t, t->vm->finalizerLock);
ACQUIRE(t, t->vm->referenceLock);
t->vm->finalizers = makeFinalizer
(t, 0, reinterpret_cast<void*>(finalize), t->vm->finalizers);

View File

@ -61,6 +61,9 @@ enum MapType {
const int NativeLine = -1;
const int UnknownLine = -2;
const unsigned ReferenceFlag = 1 << 0;
const unsigned WeakReferenceFlag = 1 << 1;
class Thread;
typedef Thread JNIEnv;
@ -1106,7 +1109,7 @@ class Machine {
System::Monitor* stateLock;
System::Monitor* heapLock;
System::Monitor* classLock;
System::Monitor* finalizerLock;
System::Monitor* referenceLock;
System::Library* libraries;
object classMap;
object bootstrapClassMap;

View File

@ -76,6 +76,18 @@ popFrame(Thread* t)
}
}
void
registerWeakReference(Thread* t, object r)
{
PROTECT(t, r);
ACQUIRE(t, t->vm->referenceLock);
// jreferenceNext(t, r)
cast<object>(r, 3 * BytesPerWord) = t->vm->weakReferences;
t->vm->weakReferences = r;
}
inline object
make(Thread* t, object class_)
{
@ -86,6 +98,10 @@ make(Thread* t, object class_)
memset(static_cast<object*>(instance) + 1, 0,
sizeInBytes - sizeof(object));
if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) {
registerWeakReference(t, instance);
}
return instance;
}
@ -1085,8 +1101,8 @@ run(Thread* t)
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
int32_t b = popInt(t);
int32_t a = popInt(t);
object b = popObject(t);
object a = popObject(t);
if (a == b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
@ -1097,8 +1113,8 @@ run(Thread* t)
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
int32_t b = popInt(t);
int32_t a = popInt(t);
object b = popObject(t);
object a = popObject(t);
if (a != b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));

36
test/References.java Normal file
View File

@ -0,0 +1,36 @@
import java.lang.ref.ReferenceQueue;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.ref.PhantomReference;
public class References {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
Object c = new Object();
Object d = new Object();
ReferenceQueue q = new ReferenceQueue();
Reference ar = new WeakReference(a);
Reference br = new WeakReference(b, q);
Reference cr = new WeakReference(c, q);
Reference dr = new PhantomReference(d, q);
a = b = c = d = cr = null;
System.out.println("a: " + ar.get());
System.out.println("b: " + br.get());
System.out.println("d: " + dr.get());
System.gc();
System.out.println("a: " + ar.get());
System.out.println("b: " + br.get());
System.out.println("d: " + dr.get());
for (Reference r = q.poll(); r != null; r = q.poll()) {
System.out.println("polled: " + r.get());
}
}
}