This commit is contained in:
Joel Dice 2007-07-07 17:47:35 -06:00
parent e5bea7a455
commit f71c77298c
18 changed files with 482 additions and 176 deletions

View File

@ -22,7 +22,7 @@ public class TestThreads implements Runnable {
try { try {
System.out.println("I'm running in a seperate thread!"); System.out.println("I'm running in a seperate thread!");
final int arrayCount = 64; final int arrayCount = 8;
final int arraySize = 4; final int arraySize = 4;
System.out.println("Allocating and discarding " + arrayCount + System.out.println("Allocating and discarding " + arrayCount +
" arrays of " + arraySize + "MB each"); " arrays of " + arraySize + "MB each");

View File

@ -0,0 +1,19 @@
package java.lang;
public class ArrayIndexOutOfBoundsException extends RuntimeException {
public ArrayIndexOutOfBoundsException(String message, Throwable cause) {
super(message, cause);
}
public ArrayIndexOutOfBoundsException(String message) {
this(message, null);
}
public ArrayIndexOutOfBoundsException(Throwable cause) {
this(null, cause);
}
public ArrayIndexOutOfBoundsException() {
this(null, null);
}
}

View File

@ -19,9 +19,9 @@ public class Object {
public native String toString(); public native String toString();
public native final void wait(); public final void wait() {
wait(0);
}
public native final void wait(long timeout); public native final void wait(long timeout);
public native final void wait(long timeout, int nanos);
} }

View File

@ -6,6 +6,20 @@ public final class String {
private int length; private int length;
private int hash; private int hash;
public String(char[] data, int offset, int length, boolean copy) {
if (copy) {
char[] c = new char[length];
System.arraycopy(data, offset, c, 0, length);
this.data = c;
this.length = length;
} else {
this.data = data;
this.offset = offset;
this.length = length;
}
}
public int length() { public int length() {
return length; return length;
} }
@ -14,8 +28,23 @@ public final class String {
return valueOf((long) v); return valueOf((long) v);
} }
public native void getChars(int offset, int length, public void getChars(int srcOffset, int srcLength,
char[] dst, int dstLength); char[] dst, int dstOffset)
{
if (srcOffset + srcLength > length) {
throw new ArrayIndexOutOfBoundsException();
}
if (data instanceof char[]) {
char[] src = (char[]) data;
System.arraycopy(src, offset + srcOffset, dst, dstOffset, srcLength);
} else {
byte[] src = (byte[]) data;
for (int i = 0; i < srcLength; ++i) {
dst[i + dstOffset] = (char) src[i + offset + srcOffset];
}
}
}
public static String valueOf(long v) { public static String valueOf(long v) {
if (v == 0) { if (v == 0) {
@ -35,7 +64,7 @@ public final class String {
array[--index] = '-'; array[--index] = '-';
} }
return vm.Strings.wrap(array, index, Max - index); return new String(array, index, Max - index, false);
} }
} }
} }

View File

@ -27,7 +27,7 @@ public class StringBuilder {
index -= c.value.length(); index -= c.value.length();
c.value.getChars(0, c.value.length(), array, index); c.value.getChars(0, c.value.length(), array, index);
} }
return vm.Strings.wrap(array, 0, array.length); return new String(array, 0, array.length, false);
} }
private static class Cell { private static class Cell {

View File

@ -1,16 +1,34 @@
#include "stdio.h" #include "stdio.h"
#include "string.h"
#include "jni.h" #include "jni.h"
#undef JNIEXPORT #undef JNIEXPORT
#define JNIEXPORT __attribute__ ((visibility("default"))) #define JNIEXPORT __attribute__ ((visibility("default")))
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_lang_System_00024Output_println(JNIEnv* e, jobject, jstring s) Java_java_lang_System_00024Output_print(JNIEnv* e, jobject, jstring s)
{ {
jboolean isCopy; jboolean isCopy;
const char* chars = e->GetStringUTFChars(s, &isCopy); const char* chars = e->GetStringUTFChars(s, &isCopy);
if (chars) { if (chars) {
printf("%s\n", chars); printf("%s", chars);
} }
e->ReleaseStringUTFChars(s, chars); e->ReleaseStringUTFChars(s, chars);
} }
extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jstring key)
{
jstring value = 0;
jboolean isCopy;
const char* chars = e->GetStringUTFChars(key, &isCopy);
if (chars) {
if (strcmp(chars, "line.separator") == 0) {
value = e->NewStringUTF("\n");
}
}
e->ReleaseStringUTFChars(key, chars);
return value;
}

View File

@ -8,14 +8,17 @@ public abstract class System {
loadLibrary("natives"); loadLibrary("natives");
} }
public static native void arraycopy(Object src, int srcOffset, Object dst,
int dstOffset, int length);
public static native void loadLibrary(String name); public static native void loadLibrary(String name);
public static native String getProperty(String name); public static native String getProperty(String name);
public static class Output { public static class Output {
public native void print(String s); public synchronized native void print(String s);
public void println(String s) { public synchronized void println(String s) {
print(s); print(s);
print(getProperty("line.separator")); print(getProperty("line.separator"));
} }

View File

@ -1,5 +0,0 @@
package vm;
public abstract class Strings {
public static native String wrap(char[] array, int offset, int length);
}

View File

@ -5,6 +5,35 @@
namespace vm { namespace vm {
namespace builtin { namespace builtin {
jstring
toString(Thread* t, jobject this_)
{
object s = makeString
(t, "%s@%p",
&byteArrayBody(t, className(t, objectClass(t, *this_)), 0),
*this_);
return pushReference(t, s);
}
void
wait(Thread* t, jobject this_, jlong milliseconds)
{
vm::wait(t, *this_, milliseconds);
}
void
notify(Thread* t, jobject this_)
{
vm::notify(t, *this_);
}
void
notifyAll(Thread* t, jobject this_)
{
vm::notifyAll(t, *this_);
}
void void
loadLibrary(Thread* t, jstring nameString) loadLibrary(Thread* t, jstring nameString)
{ {
@ -30,15 +59,53 @@ loadLibrary(Thread* t, jstring nameString)
} }
} }
jstring void
toString(Thread* t, jobject this_) arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
jint length)
{ {
object s = makeString if (LIKELY(src and dst)) {
(t, "%s@%p", object s = *src;
&byteArrayBody(t, className(t, objectClass(t, *this_)), 0), object d = *dst;
*this_);
return pushReference(t, s); if (LIKELY(objectClass(t, s) == objectClass(t, d))) {
unsigned elementSize = classArrayElementSize(t, objectClass(t, s));
if (LIKELY(elementSize)) {
unsigned offset = 0;
if (objectClass(t, s)
== arrayBody(t, t->vm->types, Machine::ObjectArrayType))
{
if (LIKELY(objectArrayElementClass(t, s)
== objectArrayElementClass(t, d)))
{
offset = 1;
} else {
t->exception = makeArrayStoreException(t);
return;
}
}
int32_t sl = cast<uint32_t>(s, offset * BytesPerWord);
int32_t dl = cast<uint32_t>(d, offset * BytesPerWord);
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length < dl))
{
uint8_t* sbody = &cast<uint8_t>(s, (offset * BytesPerWord) + 4);
uint8_t* dbody = &cast<uint8_t>(s, (offset * BytesPerWord) + 4);
memcpy(sbody + (srcOffset * elementSize),
dbody + (dstOffset * elementSize),
length * elementSize);
return;
}
}
}
} else {
t->exception = makeNullPointerException(t);
return;
}
t->exception = makeArrayStoreException(t);
} }
jarray jarray
@ -100,7 +167,6 @@ start(Thread* t, jobject this_)
} }
} }
} }
void void
populate(Thread* t, object map) populate(Thread* t, object map)
{ {
@ -110,8 +176,16 @@ populate(Thread* t, object map)
} builtins[] = { } builtins[] = {
{ "Java_java_lang_Object_toString", { "Java_java_lang_Object_toString",
reinterpret_cast<void*>(toString) }, reinterpret_cast<void*>(toString) },
{ "Java_java_lang_Object_wait",
reinterpret_cast<void*>(wait) },
{ "Java_java_lang_Object_notify",
reinterpret_cast<void*>(notify) },
{ "Java_java_lang_Object_notifyAll",
reinterpret_cast<void*>(notifyAll) },
{ "Java_java_lang_System_loadLibrary", { "Java_java_lang_System_loadLibrary",
reinterpret_cast<void*>(loadLibrary) }, reinterpret_cast<void*>(loadLibrary) },
{ "Java_java_lang_System_arraycopy",
reinterpret_cast<void*>(arraycopy) },
{ "Java_java_lang_Throwable_trace", { "Java_java_lang_Throwable_trace",
reinterpret_cast<void*>(trace) }, reinterpret_cast<void*>(trace) },
{ "Java_java_lang_Thread_start", { "Java_java_lang_Thread_start",

View File

@ -241,6 +241,7 @@ const unsigned ACC_PROTECTED = 1 << 2;
const unsigned ACC_STATIC = 1 << 3; const unsigned ACC_STATIC = 1 << 3;
const unsigned ACC_FINAL = 1 << 4; const unsigned ACC_FINAL = 1 << 4;
const unsigned ACC_SUPER = 1 << 5; const unsigned ACC_SUPER = 1 << 5;
const unsigned ACC_SYNCHRONIZED = ACC_SUPER;
const unsigned ACC_VOLATILE = 1 << 6; const unsigned ACC_VOLATILE = 1 << 6;
const unsigned ACC_TRANSIENT = 1 << 7; const unsigned ACC_TRANSIENT = 1 << 7;
const unsigned ACC_NATIVE = 1 << 8; const unsigned ACC_NATIVE = 1 << 8;

View File

@ -36,6 +36,14 @@ ReleaseStringUTFChars(Thread* t, jstring, const char* chars)
t->vm->system->free(chars); t->vm->system->free(chars);
} }
jstring
NewStringUTF(Thread* t, const char* chars)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeString(t, "%s", chars));
}
void void
populate(JNIEnvVTable* table) populate(JNIEnvVTable* table)
{ {
@ -44,6 +52,7 @@ populate(JNIEnvVTable* table)
table->GetStringUTFLength = GetStringUTFLength; table->GetStringUTFLength = GetStringUTFLength;
table->GetStringUTFChars = GetStringUTFChars; table->GetStringUTFChars = GetStringUTFChars;
table->ReleaseStringUTFChars = ReleaseStringUTFChars; table->ReleaseStringUTFChars = ReleaseStringUTFChars;
table->NewStringUTF = NewStringUTF;
} }
} // namespace jni } // namespace jni

View File

@ -6,45 +6,6 @@ using namespace vm;
namespace { namespace {
void
visitRoots(Thread* t, Heap::Visitor* v)
{
if (t->state != Thread::ZombieState) {
t->heapIndex = 0;
v->visit(&(t->javaThread));
v->visit(&(t->code));
v->visit(&(t->exception));
for (unsigned i = 0; i < t->sp; ++i) {
if (t->stack[i * 2] == ObjectTag) {
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
}
}
for (Thread::Protector* p = t->protector; p; p = p->next) {
v->visit(p->p);
}
}
for (Thread* c = t->child; c; c = c->peer) {
visitRoots(c, v);
}
}
void
postCollect(Thread* t)
{
if (t->large) {
t->vm->system->free(t->large);
t->large = 0;
}
for (Thread* c = t->child; c; c = c->peer) {
postCollect(c);
}
}
bool bool
find(Thread* t, Thread* o) find(Thread* t, Thread* o)
{ {
@ -140,6 +101,45 @@ killZombies(Thread* t, Thread* o)
} }
} }
void
visitRoots(Thread* t, Heap::Visitor* v)
{
if (t->state != Thread::ZombieState) {
t->heapIndex = 0;
v->visit(&(t->javaThread));
v->visit(&(t->code));
v->visit(&(t->exception));
for (unsigned i = 0; i < t->sp; ++i) {
if (t->stack[i * 2] == ObjectTag) {
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
}
}
for (Thread::Protector* p = t->protector; p; p = p->next) {
v->visit(p->p);
}
}
for (Thread* c = t->child; c; c = c->peer) {
visitRoots(c, v);
}
}
void
postCollect(Thread* t)
{
if (t->large) {
t->vm->system->free(t->large);
t->large = 0;
}
for (Thread* c = t->child; c; c = c->peer) {
postCollect(c);
}
}
void void
collect(Thread* t, Heap::CollectionType type) collect(Thread* t, Heap::CollectionType type)
{ {
@ -174,13 +174,8 @@ collect(Thread* t, Heap::CollectionType type)
} }
} }
for (object* f = &(m->finalizers); *f; f = &finalizerNext(t, *f)) { v->visit(&(m->finalizers));
v->visit(f); v->visit(&(m->doomed));
}
for (object* f = &(m->doomed); *f; f = &finalizerNext(t, *f)) {
v->visit(f);
}
for (object p = m->weakReferences; p;) { for (object p = m->weakReferences; p;) {
object o = jreferenceTarget(t, p); object o = jreferenceTarget(t, p);
@ -193,8 +188,8 @@ collect(Thread* t, Heap::CollectionType type)
} }
object last = p; object last = p;
p = weakReferenceNext(t, p); p = jreferenceNext(t, p);
weakReferenceNext(t, last) = 0; jreferenceNext(t, last) = 0;
} }
} }
@ -233,13 +228,16 @@ collect(Thread* t, Heap::CollectionType type)
memcpy(dst, o, n * BytesPerWord); memcpy(dst, o, n * BytesPerWord);
if (hashTaken(t, o)) { if (hashTaken(t, o)) {
extendedWord(t, dst, base) = takeHash(t, o);
cast<uintptr_t>(dst, 0) &= PointerMask; cast<uintptr_t>(dst, 0) &= PointerMask;
cast<uintptr_t>(dst, 0) |= ExtendedMark; cast<uintptr_t>(dst, 0) |= ExtendedMark;
extendedWord(t, dst, base) = takeHash(t, o);
} }
if (classVmFlags(t, class_) & WeakReferenceFlag) { if (classVmFlags(t, class_) & WeakReferenceFlag) {
weakReferenceNext(t, dst) = m->weakReferences; fprintf(stderr, "weak reference to %p at %p\n",
jreferenceTarget(t, dst),
&jreferenceTarget(t, dst));
jreferenceNext(t, dst) = m->weakReferences;
m->weakReferences = dst; m->weakReferences = dst;
} }
} }
@ -255,7 +253,6 @@ collect(Thread* t, Heap::CollectionType type)
// fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n", // fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n",
// p, class_, objectMask, intArrayLength(t, objectMask)); // p, class_, objectMask, intArrayLength(t, objectMask));
unsigned vmFlags = classVmFlags(t, class_);
unsigned fixedSize = classFixedSize(t, class_); unsigned fixedSize = classFixedSize(t, class_);
unsigned arrayElementSize = classArrayElementSize(t, class_); unsigned arrayElementSize = classArrayElementSize(t, class_);
unsigned arrayLength unsigned arrayLength
@ -275,9 +272,7 @@ collect(Thread* t, Heap::CollectionType type)
= divide(arrayElementSize, BytesPerWord); = divide(arrayElementSize, BytesPerWord);
for (unsigned i = 0; i < fixedSizeInWords; ++i) { for (unsigned i = 0; i < fixedSizeInWords; ++i) {
if ((i != 1 or (vmFlags & WeakReferenceFlag) == 0) if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) {
and mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i)))
{
if (not w->visit(i)) { if (not w->visit(i)) {
return; return;
} }
@ -322,7 +317,7 @@ collect(Thread* t, Heap::CollectionType type)
postCollect(m->rootThread); postCollect(m->rootThread);
for (object f = m->doomed; f; f = tripleThird(t, f)) { for (object f = m->doomed; f; f = finalizerNext(t, f)) {
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f)) reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
(t, finalizerTarget(t, f)); (t, finalizerTarget(t, f));
} }
@ -451,6 +446,8 @@ Thread::Thread(Machine* m, Allocator* allocator, object javaThread,
object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType); object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType);
set(t, cast<object>(intArrayClass, 0), classClass); set(t, cast<object>(intArrayClass, 0), classClass);
set(t, classSuper(t, intArrayClass),
arrayBody(t, m->types, Machine::JobjectType));
m->unsafe = false; m->unsafe = false;

View File

@ -24,7 +24,7 @@ namespace vm {
const bool Verbose = false; const bool Verbose = false;
const bool Debug = false; const bool Debug = false;
const bool DebugRun = true; const bool DebugRun = true;
const bool DebugStack = false; const bool DebugStack = true;
const uintptr_t HashTakenMark = 1; const uintptr_t HashTakenMark = 1;
const uintptr_t ExtendedMark = 2; const uintptr_t ExtendedMark = 2;
@ -1311,6 +1311,12 @@ makeIllegalStateException(Thread* t, object message)
return makeIllegalStateException(t, message, trace, 0); return makeIllegalStateException(t, message, trace, 0);
} }
inline object
makeIllegalMonitorStateException(Thread* t)
{
return makeIllegalMonitorStateException(t, 0, makeTrace(t), 0);
}
inline object inline object
makeArrayIndexOutOfBoundsException(Thread* t, object message) makeArrayIndexOutOfBoundsException(Thread* t, object message)
{ {
@ -1320,11 +1326,17 @@ makeArrayIndexOutOfBoundsException(Thread* t, object message)
} }
inline object inline object
makeNegativeArrayStoreException(Thread* t, object message) makeArrayStoreException(Thread* t)
{
return makeArrayStoreException(t, 0, makeTrace(t), 0);
}
inline object
makeNegativeArraySizeException(Thread* t, object message)
{ {
PROTECT(t, message); PROTECT(t, message);
object trace = makeTrace(t); object trace = makeTrace(t);
return makeNegativeArrayStoreException(t, message, trace, 0); return makeNegativeArraySizeException(t, message, trace, 0);
} }
inline object inline object
@ -1535,7 +1547,7 @@ pokeLong(Thread* t, unsigned index, uint64_t value)
} }
pokeInt(t, index, value >> 32); pokeInt(t, index, value >> 32);
pokeInt(t, index + 2, value & 0xFF); pokeInt(t, index + 1, value & 0xFF);
} }
inline object* inline object*
@ -1807,6 +1819,56 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o); objectMonitor(Thread* t, object o);
inline void
acquire(Thread* t, object o)
{
System::Monitor* m = objectMonitor(t, o);
if (not m->tryAcquire(t)) {
ENTER(t, Thread::IdleState);
m->acquire(t);
}
}
inline void
release(Thread* t, object o)
{
objectMonitor(t, o)->release(t);
}
inline void
wait(Thread* t, object o, int64_t milliseconds)
{
System::Monitor* m = objectMonitor(t, o);
if (m->owner() == t) {
ENTER(t, Thread::IdleState);
m->wait(t, milliseconds);
} else {
t->exception = makeIllegalMonitorStateException(t);
}
}
inline void
notify(Thread* t, object o)
{
System::Monitor* m = objectMonitor(t, o);
if (m->owner() == t) {
m->notify(t);
} else {
t->exception = makeIllegalMonitorStateException(t);
}
}
inline void
notifyAll(Thread* t, object o)
{
System::Monitor* m = objectMonitor(t, o);
if (m->owner() == t) {
m->notifyAll(t);
} else {
t->exception = makeIllegalMonitorStateException(t);
}
}
void void
exit(Thread* t); exit(Thread* t);

View File

@ -227,6 +227,10 @@ class System: public vm::System {
} }
} }
virtual void* owner() {
return context;
}
virtual void dispose() { virtual void dispose() {
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition); pthread_cond_destroy(&condition);

View File

@ -42,11 +42,30 @@ pushFrame(Thread* t, object method)
pokeInt(t, frame + FrameBaseOffset, base); pokeInt(t, frame + FrameBaseOffset, base);
pokeObject(t, frame + FrameMethodOffset, method); pokeObject(t, frame + FrameMethodOffset, method);
pokeInt(t, t->frame + FrameIpOffset, 0);
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
if (methodFlags(t, method) & ACC_STATIC) {
acquire(t, methodClass(t, method));
} else {
acquire(t, peekObject(t, base));
}
}
} }
void void
popFrame(Thread* t) popFrame(Thread* t)
{ {
object method = frameMethod(t, t->frame);
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
if (methodFlags(t, method) & ACC_STATIC) {
release(t, methodClass(t, method));
} else {
release(t, peekObject(t, frameBase(t, t->frame)));
}
}
t->sp = frameBase(t, t->frame); t->sp = frameBase(t, t->frame);
t->frame = frameNext(t, t->frame); t->frame = frameNext(t, t->frame);
if (t->frame >= 0) { if (t->frame >= 0) {
@ -1214,10 +1233,20 @@ resolveClass(Thread* t, object spec)
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash); hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
} else { } else {
class_ = hashMapFind
(t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual);
if (class_ == 0) {
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
t->exception = makeClassNotFoundException(t, message); t->exception = makeClassNotFoundException(t, message);
} }
} }
if (class_) {
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
}
}
return class_; return class_;
} }
@ -1452,6 +1481,12 @@ invokeNative(Thread* t, object method)
enter(t, Thread::IdleState); enter(t, Thread::IdleState);
} }
if (DebugRun) {
fprintf(stderr, "invoke native method %s.%s\n",
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0));
}
uint64_t result = t->vm->system->call uint64_t result = t->vm->system->call
(function, (function,
args, args,
@ -1460,6 +1495,14 @@ invokeNative(Thread* t, object method)
size, size,
returnType); returnType);
if (DebugRun) {
fprintf(stderr, "return from native method %s.%s\n",
&byteArrayBody
(t, className(t, methodClass(t, frameMethod(t, t->frame))), 0),
&byteArrayBody
(t, methodName(t, frameMethod(t, t->frame)), 0));
}
if (not builtin) { if (not builtin) {
enter(t, oldState); enter(t, oldState);
} }
@ -1477,15 +1520,26 @@ invokeNative(Thread* t, object method)
case ShortField: case ShortField:
case FloatField: case FloatField:
case IntField: case IntField:
if (DebugRun) {
fprintf(stderr, "result: " LLD "\n", result);
}
pushInt(t, result); pushInt(t, result);
break; break;
case LongField: case LongField:
case DoubleField: case DoubleField:
if (DebugRun) {
fprintf(stderr, "result: " LLD "\n", result);
}
pushLong(t, result); pushLong(t, result);
break; break;
case ObjectField: case ObjectField:
if (DebugRun) {
fprintf(stderr, "result: %p at %p\n", result == 0 ? 0 :
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)),
reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
}
pushObject(t, result == 0 ? 0 : pushObject(t, result == 0 ? 0 :
*reinterpret_cast<object*>(static_cast<uintptr_t>(result))); *reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
break; break;
@ -1622,28 +1676,19 @@ run(Thread* t)
pushObject(t, array); pushObject(t, array);
} else { } else {
object message = makeString(t, "%d", count); object message = makeString(t, "%d", count);
exception = makeNegativeArrayStoreException(t, message); exception = makeNegativeArraySizeException(t, message);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
case areturn: case areturn: {
case ireturn: object result = popObject(t);
case lreturn: {
popFrame(t); popFrame(t);
if (frame >= 0) { if (frame >= 0) {
pushObject(t, result);
goto loop; goto loop;
} else { } else {
switch (instruction) { return result;
case areturn:
return popObject(t);
case ireturn:
return makeInt(t, popInt(t));
case lreturn:
return makeLong(t, popLong(t));
}
} }
} goto loop; } goto loop;
@ -1655,14 +1700,14 @@ run(Thread* t)
{ {
pushInt(t, objectArrayLength(t, array)); pushInt(t, objectArrayLength(t, array));
} else { } else {
// for all other array types, the length follow the class pointer. // for all other array types, the length follows the class pointer.
pushInt(t, cast<uint32_t>(array, BytesPerWord)); pushInt(t, cast<uint32_t>(array, BytesPerWord));
} }
} else { } else {
exception = makeNullPointerException(t); exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} abort(t); } goto loop;
case astore: { case astore: {
setLocalObject(t, codeBody(t, code, ip++), popObject(t)); setLocalObject(t, codeBody(t, code, ip++), popObject(t));
@ -2168,7 +2213,7 @@ run(Thread* t)
int32_t b = popInt(t); int32_t b = popInt(t);
int32_t a = popInt(t); int32_t a = popInt(t);
if (a < b) { if (a <= b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2)); ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
} }
} goto loop; } goto loop;
@ -2405,6 +2450,17 @@ run(Thread* t)
pushInt(t, a % b); pushInt(t, a % b);
} goto loop; } goto loop;
case ireturn: {
int32_t result = popInt(t);
popFrame(t);
if (frame >= 0) {
pushInt(t, result);
goto loop;
} else {
return makeInt(t, result);
}
} goto loop;
case ishl: { case ishl: {
int32_t b = popInt(t); int32_t b = popInt(t);
int32_t a = popInt(t); int32_t a = popInt(t);
@ -2480,7 +2536,7 @@ run(Thread* t)
} goto loop; } goto loop;
case l2i: { case l2i: {
pushLong(t, static_cast<int32_t>(popLong(t))); pushInt(t, static_cast<int32_t>(popLong(t)));
} goto loop; } goto loop;
case ladd: { case ladd: {
@ -2649,6 +2705,17 @@ run(Thread* t)
pushLong(t, a % b); pushLong(t, a % b);
} goto loop; } goto loop;
case lreturn: {
int64_t result = popLong(t);
popFrame(t);
if (frame >= 0) {
pushLong(t, result);
goto loop;
} else {
return makeLong(t, result);
}
} goto loop;
case lshl: { case lshl: {
int64_t b = popLong(t); int64_t b = popLong(t);
int64_t a = popLong(t); int64_t a = popLong(t);
@ -2707,7 +2774,7 @@ run(Thread* t)
case monitorenter: { case monitorenter: {
object o = popObject(t); object o = popObject(t);
if (LIKELY(o)) { if (LIKELY(o)) {
objectMonitor(t, o)->acquire(t); acquire(t, o);
} else { } else {
exception = makeNullPointerException(t); exception = makeNullPointerException(t);
goto throw_; goto throw_;
@ -2717,7 +2784,7 @@ run(Thread* t)
case monitorexit: { case monitorexit: {
object o = popObject(t); object o = popObject(t);
if (LIKELY(o)) { if (LIKELY(o)) {
objectMonitor(t, o)->release(t); release(t, o);
} else { } else {
exception = makeNullPointerException(t); exception = makeNullPointerException(t);
goto throw_; goto throw_;
@ -2790,7 +2857,7 @@ run(Thread* t)
pushObject(t, array); pushObject(t, array);
} else { } else {
object message = makeString(t, "%d", count); object message = makeString(t, "%d", count);
exception = makeNegativeArrayStoreException(t, message); exception = makeNegativeArraySizeException(t, message);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;

View File

@ -40,6 +40,7 @@ class System: public Allocator {
virtual void wait(void* context, int64_t time) = 0; virtual void wait(void* context, int64_t time) = 0;
virtual void notify(void* context) = 0; virtual void notify(void* context) = 0;
virtual void notifyAll(void* context) = 0; virtual void notifyAll(void* context) = 0;
virtual void* owner() = 0;
virtual void dispose() = 0; virtual void dispose() = 0;
}; };

View File

@ -1475,42 +1475,25 @@ writeInitialization(Output* out, Object* type)
out->write(" object mask = 0;\n"); out->write(" object mask = 0;\n");
} }
if (typeJavaName(type)) { if (typeJavaName(type) and typeSuper(type)) {
if (typeObjectMask(type) != 1) {
out->write(" PROTECT(t, mask);\n");
}
out->write(" object name = ::makeByteArray(t, \"");
out->write(typeJavaName(type));
out->write("\");\n");
if (typeSuper(type)) {
out->write(" object super = arrayBody(t, t->vm->types, Machine::"); out->write(" object super = arrayBody(t, t->vm->types, Machine::");
out->write(capitalize(typeName(typeSuper(type)))); out->write(capitalize(typeName(typeSuper(type))));
out->write("Type);\n"); out->write("Type);\n");
} else { } else {
out->write(" object super = 0;\n"); out->write(" object super = 0;\n");
} }
} else {
out->write(" object name = 0;\n");
out->write(" object super = 0;\n");
}
out->write(" object class_ = makeClass"); out->write(" object class_ = makeClass");
out->write("(t, 0, 0, "); out->write("(t, 0, 0, ");
out->write(typeFixedSize(type)); out->write(typeFixedSize(type));
out->write(", "); out->write(", ");
out->write(typeArrayElementSize(type)); out->write(typeArrayElementSize(type));
out->write(", mask, name, super, 0, 0, 0, 0, 0, 0);\n"); out->write(", mask, 0, super, 0, 0, 0, 0, 0, 0);\n");
out->write(" set(t, arrayBody(t, t->vm->types, Machine::"); out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
out->write(capitalize(typeName(type))); out->write(capitalize(typeName(type)));
out->write("Type), class_);\n"); out->write("Type), class_);\n");
if (typeJavaName(type)) {
out->write(" hashMapInsert(t, t->vm->bootstrapClassMap, ");
out->write("className(t, class_), class_, byteArrayHash);\n");
}
out->write("}\n\n"); out->write("}\n\n");
} }
@ -1549,10 +1532,38 @@ writeInitializations(Output* out, Object* declarations)
for (Object* p = declarations; p; p = cdr(p)) { for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p); Object* o = car(p);
if (o->type == Object::Type and typeJavaName(o) == 0) { if (o->type == Object::Type and equal(typeName(o), "intArray")) {
writeInitialization(out, o); writeInitialization(out, o);
} }
} }
for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p);
if (o->type == Object::Type and not equal(typeName(o), "intArray")) {
writeInitialization(out, o);
}
}
}
void
writeJavaInitialization(Output* out, Object* type)
{
out->write("{\n");
out->write(" object name = ::makeByteArray(t, \"");
out->write(typeJavaName(type));
out->write("\");\n");
out->write(" object class_ = arrayBody(t, t->vm->types, Machine::");
out->write(capitalize(typeName(type)));
out->write("Type);\n");
out->write(" set(t, className(t, class_), name);\n");
out->write(" hashMapInsert(t, t->vm->bootstrapClassMap, ");
out->write("name, class_, byteArrayHash);\n");
out->write("}\n\n");
} }
void void
@ -1561,7 +1572,7 @@ writeJavaInitializations(Output* out, Object* declarations)
for (Object* p = declarations; p; p = cdr(p)) { for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p); Object* o = car(p);
if (o->type == Object::Type and typeJavaName(o)) { if (o->type == Object::Type and typeJavaName(o)) {
writeInitialization(out, o); writeJavaInitialization(out, o);
} }
} }
} }
@ -1570,7 +1581,8 @@ void
usageAndExit(const char* command) usageAndExit(const char* command)
{ {
fprintf(stderr, fprintf(stderr,
"usage: %s {enums,declarations,constructors,initializations}\n", "usage: %s {enums,declarations,constructors,initializations,"
"java-initializations}\n",
command); command);
exit(-1); exit(-1);
} }

View File

@ -1,6 +1,3 @@
(type intArray
(array int32_t body))
(type class (type class
(uint16_t flags) (uint16_t flags)
(uint16_t vmFlags) (uint16_t vmFlags)
@ -108,31 +105,6 @@
(type array (type array
(noassert array object body)) (noassert array object body))
(type objectArray
(object elementClass)
(array object body))
(type byteArray
(array int8_t body))
(type booleanArray
(array int8_t body))
(type shortArray
(array int16_t body))
(type charArray
(array uint16_t body))
(type longArray
(array int64_t body))
(type floatArray
(array uint32_t body))
(type doubleArray
(array uint64_t body))
(type jobject java/lang/Object) (type jobject java/lang/Object)
@ -166,11 +138,17 @@
(type illegalStateException java/lang/IllegalStateException (type illegalStateException java/lang/IllegalStateException
(extends runtimeException)) (extends runtimeException))
(type illegalMonitorStateException java/lang/IllegalMonitorStateException
(extends runtimeException))
(type arrayIndexOutOfBoundsException (type arrayIndexOutOfBoundsException
java/lang/ArrayIndexOutOfBoundsException java/lang/ArrayIndexOutOfBoundsException
(extends runtimeException)) (extends runtimeException))
(type negativeArrayStoreException java/lang/NegativeArrayStoreException (type arrayStoreException java/lang/arrayStoreException
(extends runtimeException))
(type negativeArraySizeException java/lang/NegativeArraySizeException
(extends runtimeException)) (extends runtimeException))
(type classCastException java/lang/ClassCastException (type classCastException java/lang/ClassCastException
@ -228,8 +206,45 @@
(type jreference java/lang/ref/Reference (type jreference java/lang/ref/Reference
(extends jobject) (extends jobject)
(object target)) (void* target)
(void* next))
(type weakReference java/lang/ref/WeakReference (type weakReference java/lang/ref/WeakReference
(extends jreference) (extends jreference))
(object next))
(type objectArray [
(extends jobject)
(object elementClass)
(array object body))
(type byteArray [B
(extends jobject)
(array int8_t body))
(type booleanArray [Z
(extends jobject)
(array int8_t body))
(type shortArray [S
(extends jobject)
(array int16_t body))
(type charArray [C
(extends jobject)
(array uint16_t body))
(type intArray [I
(extends jobject)
(array int32_t body))
(type longArray [J
(extends jobject)
(array int64_t body))
(type floatArray [F
(extends jobject)
(array uint32_t body))
(type doubleArray [D
(extends jobject)
(array uint64_t body))