various bugfixes

This commit is contained in:
Joel Dice 2007-08-13 18:37:00 -06:00
parent 89609e11c9
commit ab3ca38580
9 changed files with 120 additions and 53 deletions

View File

@ -1,7 +1,7 @@
package java.lang; package java.lang;
public class Object { public class Object {
protected native Object clone(); protected native Object clone() throws CloneNotSupportedException;
public boolean equals(Object o) { public boolean equals(Object o) {
return this == o; return this == o;

View File

@ -38,7 +38,10 @@ public class Constructor<T> extends AccessibleObject implements Member {
private static native <T> T make(Class<T> c); private static native <T> T make(Class<T> c);
public T newInstance(Object ... arguments) { public T newInstance(Object ... arguments)
throws InvocationTargetException, InstantiationException,
IllegalAccessException
{
T v = make(method.getDeclaringClass()); T v = make(method.getDeclaringClass());
method.invoke(v, arguments); method.invoke(v, arguments);
return v; return v;

View File

@ -35,7 +35,8 @@ public class Field<T> extends AccessibleObject {
return Class.forCanonicalName(getName()); return Class.forCanonicalName(getName());
} }
public native Object get(Object instance); public native Object get(Object instance) throws IllegalAccessException;
public native void set(Object instance, Object value); public native void set(Object instance, Object value)
throws IllegalAccessException;
} }

View File

@ -87,5 +87,6 @@ public class Method<T> extends AccessibleObject implements Member {
return types; return types;
} }
public native Object invoke(Object instance, Object ... arguments); public native Object invoke(Object instance, Object ... arguments)
throws InvocationTargetException, IllegalAccessException;
} }

View File

@ -52,7 +52,7 @@ public class HashMap<K, V> implements Map<K, V> {
Cell<K, V> next; Cell<K, V> next;
for (Cell<K, V> c = array[i]; c != null; c = next) { for (Cell<K, V> c = array[i]; c != null; c = next) {
next = c.next(); next = c.next();
int index = c.getKey().hashCode() & (capacity - 1); int index = c.hashCode() & (capacity - 1);
c.setNext(array[index]); c.setNext(array[index]);
array[index] = c; array[index] = c;
} }

View File

@ -15,6 +15,7 @@ cls = build/classes
src = src src = src
classpath = classpath classpath = classpath
test = test test = test
jscheme = /tmp/jscheme
input = $(cls)/Switch.class input = $(cls)/Switch.class
@ -144,10 +145,20 @@ run: $(executable) $(input)
debug: $(executable) $(input) debug: $(executable) $(input)
LD_LIBRARY_PATH=$(bld) gdb --args $(<) $(args) LD_LIBRARY_PATH=$(bld) gdb --args $(<) $(args)
.PHONY: debug-jscheme
debug-jscheme: $(executable) $(input)
LD_LIBRARY_PATH=$(bld) gdb --args $(<) -cp $(cls):$(jscheme) -hs 67108864 \
jscheme/REPL
.PHONY: vg .PHONY: vg
vg: $(executable) $(input) vg: $(executable) $(input)
LD_LIBRARY_PATH=$(bld) $(vg) $(<) $(args) LD_LIBRARY_PATH=$(bld) $(vg) $(<) $(args)
.PHONY: vg-jscheme
vg-jscheme: $(executable) $(input)
LD_LIBRARY_PATH=$(bld) $(vg) $(<) -cp $(cls):$(jscheme) -hs 67108864 \
jscheme/REPL
.PHONY: test .PHONY: test
test: $(executable) $(classpath-objects) $(test-classes) test: $(executable) $(classpath-objects) $(test-classes)
LD_LIBRARY_PATH=$(bld) /bin/bash $(test)/test.sh \ LD_LIBRARY_PATH=$(bld) /bin/bash $(test)/test.sh \

View File

@ -271,7 +271,10 @@ postVisit(Thread* t, Heap::Visitor* v)
if (m->heap->status(*p) == Heap::Unreachable) { if (m->heap->status(*p) == Heap::Unreachable) {
// reference is unreachable // reference is unreachable
referenceUnreachable(t, p, v); referenceUnreachable(t, p, v);
} else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) { } else if (jreferenceTarget(t, *p) == 0
or m->heap->status(jreferenceTarget(t, *p))
== Heap::Unreachable)
{
// target is unreachable // target is unreachable
referenceTargetUnreachable(t, p, v); referenceTargetUnreachable(t, p, v);
} else { } else {
@ -315,7 +318,8 @@ postVisit(Thread* t, Heap::Visitor* v)
if (m->heap->status(*p) == Heap::Unreachable) { if (m->heap->status(*p) == Heap::Unreachable) {
// reference is unreachable // reference is unreachable
referenceUnreachable(t, p, v); referenceUnreachable(t, p, v);
} else if (m->heap->status(jreferenceTarget(t, *p)) } else if (jreferenceTarget(t, *p) == 0
or m->heap->status(jreferenceTarget(t, *p))
== Heap::Unreachable) == Heap::Unreachable)
{ {
// target is unreachable // target is unreachable
@ -685,11 +689,15 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
set(t, arrayBody(t, interfaceTable, i++), interface); set(t, arrayBody(t, interfaceTable, i++), interface);
if ((classFlags(t, class_) & ACC_INTERFACE) == 0) { if ((classFlags(t, class_) & ACC_INTERFACE) == 0) {
// we'll fill in this table in parseMethodTable(): if (classVirtualTable(t, interface)) {
object vtable = makeArray // we'll fill in this table in parseMethodTable():
(t, arrayLength(t, classVirtualTable(t, interface)), true); object vtable = makeArray
(t, arrayLength(t, classVirtualTable(t, interface)), true);
set(t, arrayBody(t, interfaceTable, i++), vtable);
set(t, arrayBody(t, interfaceTable, i), vtable);
}
++i;
} }
} }
} }
@ -772,24 +780,34 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
(t, ceiling(classFixedSize(t, class_), BitsPerWord * BytesPerWord), true); (t, ceiling(classFixedSize(t, class_), BitsPerWord * BytesPerWord), true);
intArrayBody(t, mask, 0) = 1; intArrayBody(t, mask, 0) = 1;
object superMask = 0;
if (classSuper(t, class_)) {
superMask = classObjectMask(t, classSuper(t, class_));
if (superMask) {
memcpy(&intArrayBody(t, mask, 0),
&intArrayBody(t, superMask, 0),
ceiling(classFixedSize(t, classSuper(t, class_)),
BitsPerWord * BytesPerWord)
* 4);
}
}
bool sawReferenceField = false; bool sawReferenceField = false;
for (object c = class_; c; c = classSuper(t, c)) { object fieldTable = classFieldTable(t, class_);
object fieldTable = classFieldTable(t, c); if (fieldTable) {
if (fieldTable) { for (int i = arrayLength(t, fieldTable) - 1; i >= 0; --i) {
for (int i = arrayLength(t, fieldTable) - 1; i >= 0; --i) { object field = arrayBody(t, fieldTable, i);
object field = arrayBody(t, fieldTable, i); if ((fieldFlags(t, field) & ACC_STATIC) == 0
if ((fieldFlags(t, field) & ACC_STATIC) == 0 and fieldCode(t, field) == ObjectField)
and fieldCode(t, field) == ObjectField) {
{ unsigned index = fieldOffset(t, field) / BytesPerWord;
unsigned index = fieldOffset(t, field) / BytesPerWord; intArrayBody(t, mask, (index / 32)) |= 1 << (index % 32);
intArrayBody(t, mask, (index / 32)) |= 1 << (index % 32); sawReferenceField = true;
sawReferenceField = true;
}
} }
} }
} }
if (sawReferenceField) { if (superMask or sawReferenceField) {
set(t, classObjectMask(t, class_), mask); set(t, classObjectMask(t, class_), mask);
} }
} }
@ -868,14 +886,29 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
if (classFlags(t, class_) & ACC_INTERFACE) { if (classFlags(t, class_) & ACC_INTERFACE) {
object itable = classInterfaceTable(t, class_); object itable = classInterfaceTable(t, class_);
if (itable) { if (itable) {
PROTECT(t, itable);
for (unsigned i = 0; i < arrayLength(t, itable); ++i) { for (unsigned i = 0; i < arrayLength(t, itable); ++i) {
object vtable = classVirtualTable(t, arrayBody(t, itable, i)); object vtable = classVirtualTable(t, arrayBody(t, itable, i));
for (unsigned j = 0; j < virtualCount; ++j) { if (vtable) {
object method = arrayBody(t, vtable, j); PROTECT(t, vtable);
if (hashMapInsertMaybe(t, virtualMap, method, method, methodHash, for (unsigned j = 0; j < arrayLength(t, vtable); ++j) {
methodEqual)) object method = arrayBody(t, vtable, j);
{ object n = hashMapFindNode
++ virtualCount; (t, virtualMap, method, methodHash, methodEqual);
if (n == 0) {
method = makeMethod
(t,
methodVmFlags(t, method),
methodParameterCount(t, method),
methodParameterFootprint(t, method),
methodFlags(t, method),
virtualCount++,
methodName(t, method),
methodSpec(t, method),
methodClass(t, method),
0);
hashMapInsert(t, virtualMap, method, method, methodHash);
}
} }
} }
} }
@ -1012,17 +1045,19 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} else if (virtualCount) { } else if (virtualCount) {
// generate class vtable // generate class vtable
unsigned i = 0;
object vtable = makeArray(t, virtualCount, true); object vtable = makeArray(t, virtualCount, true);
unsigned i = 0;
if (classFlags(t, class_) & ACC_INTERFACE) { if (classFlags(t, class_) & ACC_INTERFACE) {
PROTECT(t, vtable); PROTECT(t, vtable);
object it = hashMapIterator(t, virtualMap); for (object it = hashMapIterator(t, virtualMap); it;
it = hashMapIteratorNext(t, it))
for (; it; it = hashMapIteratorNext(t, it)) { {
object method = tripleFirst(t, hashMapIteratorNode(t, it)); object method = tripleFirst(t, hashMapIteratorNode(t, it));
set(t, arrayBody(t, vtable, i++), method); assert(t, arrayBody(t, vtable, methodOffset(t, method)) == 0);
set(t, arrayBody(t, vtable, methodOffset(t, method)), method);
++ i;
} }
} else { } else {
if (superVirtualTable) { if (superVirtualTable) {
@ -1039,6 +1074,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} }
} }
assert(t, arrayLength(t, vtable) == i);
set(t, classVirtualTable(t, class_), vtable); set(t, classVirtualTable(t, class_), vtable);
if ((classFlags(t, class_) & ACC_INTERFACE) == 0) { if ((classFlags(t, class_) & ACC_INTERFACE) == 0) {
@ -1050,15 +1087,17 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
object ivtable = classVirtualTable(t, arrayBody(t, itable, i)); object ivtable = classVirtualTable(t, arrayBody(t, itable, i));
object vtable = arrayBody(t, itable, i + 1); if (ivtable) {
object vtable = arrayBody(t, itable, i + 1);
for (unsigned j = 0; j < arrayLength(t, ivtable); ++j) { for (unsigned j = 0; j < arrayLength(t, ivtable); ++j) {
object method = arrayBody(t, ivtable, j); object method = arrayBody(t, ivtable, j);
method = hashMapFind method = hashMapFind
(t, virtualMap, method, methodHash, methodEqual); (t, virtualMap, method, methodHash, methodEqual);
assert(t, method); assert(t, method);
set(t, arrayBody(t, vtable, j), method); set(t, arrayBody(t, vtable, j), method);
}
} }
} }
} }
@ -1925,7 +1964,7 @@ hashMapIteratorNext(Thread* t, object it)
unsigned index = hashMapIteratorIndex(t, it); unsigned index = hashMapIteratorIndex(t, it);
if (tripleThird(t, node)) { if (tripleThird(t, node)) {
return makeHashMapIterator(t, map, tripleThird(t, node), index + 1); return makeHashMapIterator(t, map, tripleThird(t, node), index);
} else { } else {
object array = hashMapArray(t, map); object array = hashMapArray(t, map);
for (unsigned i = index; i < arrayLength(t, array); ++i) { for (unsigned i = index; i < arrayLength(t, array); ++i) {
@ -2244,9 +2283,10 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
ACQUIRE(t, t->vm->referenceLock); ACQUIRE(t, t->vm->referenceLock);
t->vm->finalizers = makeFinalizer object f = makeFinalizer(t, 0, reinterpret_cast<void*>(finalize), 0);
(t, 0, reinterpret_cast<void*>(finalize), t->vm->finalizers); finalizerTarget(t, f) = target;
finalizerTarget(t, t->vm->finalizers) = target; finalizerNext(t, f) = t->vm->finalizers;
t->vm->finalizers = f;
} }
System::Monitor* System::Monitor*

View File

@ -1320,7 +1320,7 @@ class MonitorResource {
class RawMonitorResource { class RawMonitorResource {
public: public:
RawMonitorResource(Thread* t, System::Monitor* m): t(t), m(m) { RawMonitorResource(Thread* t, System::Monitor* m): t(t), m(m) {
acquire(t, m); m->acquire(t->systemThread);
} }
~RawMonitorResource() { ~RawMonitorResource() {

View File

@ -208,8 +208,13 @@ resolve(Thread* t, object pool, unsigned index,
object class_ = resolveClass(t, o, referenceClass); object class_ = resolveClass(t, o, referenceClass);
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
for (o = 0; o == 0 and class_; class_ = classSuper(t, class_)) { if (classFlags(t, class_) & ACC_INTERFACE) {
o = find(t, class_, arrayBody(t, pool, index)); o = ::find(t, classVirtualTable(t, class_), arrayBody(t, pool, index),
methodName, methodSpec);
} else {
for (o = 0; o == 0 and class_; class_ = classSuper(t, class_)) {
o = find(t, class_, arrayBody(t, pool, index));
}
} }
if (o == 0) { if (o == 0) {
@ -217,7 +222,7 @@ resolve(Thread* t, object pool, unsigned index,
(t, "%s %s not found in %s", (t, "%s %s not found in %s",
&byteArrayBody(t, referenceName(t, reference), 0), &byteArrayBody(t, referenceName(t, reference), 0),
&byteArrayBody(t, referenceSpec(t, reference), 0), &byteArrayBody(t, referenceSpec(t, reference), 0),
&byteArrayBody(t, referenceClass(t, reference), 0)); &byteArrayBody(t, className(t, referenceClass(t, reference)), 0));
t->exception = makeError(t, message); t->exception = makeError(t, message);
} }
@ -1306,6 +1311,10 @@ run(Thread* t)
} }
} goto loop; } goto loop;
case iconst_m1: {
pushInt(t, static_cast<unsigned>(-1));
} goto loop;
case iconst_0: { case iconst_0: {
pushInt(t, 0); pushInt(t, 0);
} goto loop; } goto loop;
@ -1602,6 +1611,7 @@ run(Thread* t)
class_ = classSuper(t, class_); class_ = classSuper(t, class_);
if (classVirtualTable(t, class_) == 0) { if (classVirtualTable(t, class_) == 0) {
PROTECT(t, method);
PROTECT(t, class_); PROTECT(t, class_);
resolveClass(t, className(t, class_)); resolveClass(t, className(t, class_));
@ -1644,6 +1654,7 @@ run(Thread* t)
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint)); object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
if (classVirtualTable(t, class_) == 0) { if (classVirtualTable(t, class_) == 0) {
PROTECT(t, method);
PROTECT(t, class_); PROTECT(t, class_);
resolveClass(t, className(t, class_)); resolveClass(t, className(t, class_));