From 38cea04322bbab59997533c234fbb0cfbbe748e8 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 1 Jul 2007 15:34:22 -0600 Subject: [PATCH] progress towards thread support This includes support for using the least significant bits of the class pointer to indicate object state, which we'll use to indicate the presence of a monitor pointer, among other things. --- classpath/TestExceptions.java | 4 +- classpath/{Test.java => TestGC.java} | 2 +- makefile | 2 +- src/common.h | 10 ++ src/heap.cpp | 95 ++++++++++------ src/main.cpp | 158 +++++++++++++++++++++++---- src/system.h | 2 +- src/type-generator.cpp | 11 +- src/vm.cpp | 101 ++++++++++------- 9 files changed, 282 insertions(+), 103 deletions(-) rename classpath/{Test.java => TestGC.java} (96%) diff --git a/classpath/TestExceptions.java b/classpath/TestExceptions.java index c37e685879..9627ba282c 100644 --- a/classpath/TestExceptions.java +++ b/classpath/TestExceptions.java @@ -5,7 +5,9 @@ public class TestExceptions { } private static void moreDangerous() { - evenMoreDangerous(); + // synchronized (TestExceptions.class) { + evenMoreDangerous(); + // } } private static void dangerous() { diff --git a/classpath/Test.java b/classpath/TestGC.java similarity index 96% rename from classpath/Test.java rename to classpath/TestGC.java index f161db1aab..f6db02a03e 100644 --- a/classpath/Test.java +++ b/classpath/TestGC.java @@ -1,4 +1,4 @@ -public class Test { +public class TestGC { private static void small() { for (int i = 0; i < 1024; ++i) { diff --git a/makefile b/makefile index 81d9ae93cf..21f9663942 100644 --- a/makefile +++ b/makefile @@ -127,7 +127,7 @@ fast-cflags = $(fast) $(cflags) classpath-sources = $(shell find $(classpath)/java -name '*.java') classpath-classes = $(call java-classes,$(classpath-sources),$(classpath)) -input = $(bld)/classes/TestExceptions.class +input = $(bld)/classes/Test.class input-depends = \ $(classpath-classes) \ $(jni-library) diff --git a/src/common.h b/src/common.h index 8e94fe7a61..53d9243d32 100644 --- a/src/common.h +++ b/src/common.h @@ -26,6 +26,9 @@ typedef void* object; const unsigned BytesPerWord = sizeof(uintptr_t); const unsigned BitsPerWord = BytesPerWord * 8; +const uintptr_t PointerMask += ((~static_cast(0)) / BytesPerWord) * BytesPerWord; + const unsigned LikelyPageSizeInBytes = 4 * 1024; inline unsigned @@ -109,6 +112,13 @@ cast(object p, unsigned offset) return *reinterpret_cast(static_cast(p) + offset); } +template +inline T* +mask(T* p) +{ + return reinterpret_cast(reinterpret_cast(p) & PointerMask); +} + } #endif//COMMON_H diff --git a/src/heap.cpp b/src/heap.cpp index 2610ed66a4..dfc8790df4 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -26,6 +26,32 @@ System* system(Context*); void NO_RETURN abort(Context*); void assert(Context*, bool); +inline object +get(object o, unsigned offsetInWords) +{ + return mask(cast(o, offsetInWords * BytesPerWord)); +} + +inline object* +getp(object o, unsigned offsetInWords) +{ + return &cast(o, offsetInWords * BytesPerWord); +} + +inline void +set(object* o, object value) +{ + *o = reinterpret_cast + (reinterpret_cast(value) + | reinterpret_cast(*o) & (~PointerMask)); +} + +inline void +set(object o, unsigned offsetInWords, object value) +{ + set(getp(o, offsetInWords), value); +} + class Segment { public: class Map { @@ -662,7 +688,7 @@ fresh(Context* c, object o) inline bool wasCollected(Context* c, object o) { - return o and (not fresh(c, o)) and fresh(c, cast(o, 0)); + return o and (not fresh(c, o)) and fresh(c, get(o, 0)); } inline object @@ -779,55 +805,55 @@ copy(Context* c, object o) } object -update3(Context* c, object* p, bool* needsVisit) +update3(Context* c, object o, bool* needsVisit) { - if (wasCollected(c, *p)) { + if (wasCollected(c, o)) { *needsVisit = false; - return follow(c, *p); + return follow(c, o); } else { *needsVisit = true; - return copy(c, *p); + return copy(c, o); } } object -update2(Context* c, object* p, bool* needsVisit) +update2(Context* c, object o, bool* needsVisit) { switch (c->mode) { case MinorCollection: case OverflowCollection: - if (c->gen2.contains(*p)) { + if (c->gen2.contains(o)) { *needsVisit = false; - return *p; + return o; } break; case Gen2Collection: - if (c->gen2.contains(*p)) { - return update3(c, p, needsVisit); + if (c->gen2.contains(o)) { + return update3(c, o, needsVisit); } else { - assert(c, c->nextGen1.contains(*p) or c->nextGen2.contains(*p)); + assert(c, c->nextGen1.contains(o) or c->nextGen2.contains(o)); *needsVisit = false; - return *p; + return o; } break; default: break; } - return update3(c, p, needsVisit); + return update3(c, o, needsVisit); } object update(Context* c, object* p, bool* needsVisit) { - if (*p == 0) { + if (mask(*p) == 0) { *needsVisit = false; - return *p; + return 0; } - object r = update2(c, p, needsVisit); + object r = update2(c, mask(*p), needsVisit); // update heap map. if (r) { @@ -956,22 +982,22 @@ bitsetNext(Context* c, uintptr_t* p) } void -collect(Context* c, void** p) +collect(Context* c, object* p) { - object original = *p; + object original = mask(*p); object parent = 0; if (Debug) { fprintf(stderr, "update %p (%s) at %p (%s)\n", - *p, segment(c, *p), p, segment(c, p)); + mask(*p), segment(c, *p), p, segment(c, p)); } bool needsVisit; - *p = update(c, p, &needsVisit); + set(p, update(c, mask(p), &needsVisit)); if (Debug) { fprintf(stderr, " result: %p (%s) (visit? %d)\n", - *p, segment(c, *p), needsVisit); + mask(*p), segment(c, *p), needsVisit); } if (not needsVisit) return; @@ -995,17 +1021,16 @@ collect(Context* c, void** p) virtual bool visit(unsigned offset) { if (Debug) { fprintf(stderr, " update %p (%s) at %p - offset %d from %p (%s)\n", - cast(copy, offset * BytesPerWord), - segment(c, cast(copy, offset * BytesPerWord)), - &cast(copy, offset * BytesPerWord), + get(copy, offset), + segment(c, get(copy, offset)), + getp(copy, offset), offset, copy, segment(c, copy)); } bool needsVisit; - object childCopy = update - (c, &cast(copy, offset * BytesPerWord), &needsVisit); + object childCopy = update(c, getp(copy, offset), &needsVisit); if (Debug) { fprintf(stderr, " result: %p (%s) (visit? %d)\n", @@ -1027,7 +1052,7 @@ collect(Context* c, void** p) second = offset; } } else { - cast(copy, offset * BytesPerWord) = childCopy; + set(copy, offset, childCopy); } if (visits > 1 and total > 2 and (second or needsVisit)) { @@ -1070,8 +1095,8 @@ collect(Context* c, void** p) parent = original; } - original = cast(copy, walker.first * BytesPerWord); - cast(copy, walker.first * BytesPerWord) = follow(c, original); + original = get(copy, walker.first); + set(copy, walker.first, follow(c, original)); goto visit; } else { // ascend @@ -1131,16 +1156,16 @@ collect(Context* c, void** p) if (Debug) { fprintf(stderr, " next is %p (%s) at %p - offset %d from %p (%s)\n", - cast(copy, walker.next * BytesPerWord), - segment(c, cast(copy, walker.next * BytesPerWord)), - &cast(copy, walker.next * BytesPerWord), + get(copy, walker.next), + segment(c, get(copy, walker.next)), + getp(copy, walker.next), walker.next, copy, segment(c, copy)); } - original = cast(copy, walker.next * BytesPerWord); - cast(copy, walker.next * BytesPerWord) = follow(c, original); + original = get(copy, walker.next); + set(copy, walker.next, follow(c, original)); goto visit; } else { return; @@ -1236,7 +1261,7 @@ collect(Context* c, Segment* s, unsigned limit) Walker(Context* c, object p): c(c), p(p) { } virtual bool visit(unsigned offset) { - collect(c, &cast(p, offset * BytesPerWord)); + collect(c, getp(p, offset)); return true; } diff --git a/src/main.cpp b/src/main.cpp index 6c54616694..5c66f63896 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,12 @@ #include "sys/mman.h" #include "sys/types.h" #include "sys/stat.h" +#include +#include #include "fcntl.h" #include "dlfcn.h" +#include "errno.h" +#include "pthread.h" #include "common.h" #include "system.h" #include "heap.h" @@ -86,6 +90,22 @@ dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes, namespace { +void* +run(void* t) +{ + static_cast(t)->run(); + return 0; +} + +int64_t +now() +{ + timeval tv = { 0, 0 }; + gettimeofday(&tv, 0); + return (static_cast(tv.tv_sec) * 1000) + + (static_cast(tv.tv_usec) / 1000); +} + const char* append(vm::System* s, const char* a, const char* b, const char* c, const char* d) @@ -108,17 +128,95 @@ class System: public vm::System { public: class Monitor: public vm::System::Monitor { public: - Monitor(vm::System* s): s(s) { } + Monitor(vm::System* s): s(s), context(0), depth(0) { + pthread_mutex_init(&mutex, 0); + pthread_cond_init(&condition, 0); + } - virtual bool tryAcquire(void*) { return true; } - virtual void acquire(void*) { } - virtual void release(void*) { } - virtual void wait(void*) { } - virtual void notify(void*) { } - virtual void notifyAll(void*) { } - virtual void dispose() { s->free(this); } + virtual bool tryAcquire(void* context) { + if (this->context == context) { + ++ depth; + return true; + } else { + switch (pthread_mutex_trylock(&mutex)) { + case EBUSY: + return false; + + case 0: + this->context = context; + ++ depth; + return true; + + default: + vm::abort(s); + } + } + } + + virtual void acquire(void* context) { + if (this->context != context) { + pthread_mutex_lock(&mutex); + this->context = context; + } + ++ depth; + } + + virtual void release(void* context) { + if (this->context == context) { + if (-- depth == 0) { + this->context = 0; + pthread_mutex_unlock(&mutex); + } + } else { + vm::abort(s); + } + } + + virtual void wait(void* context, int64_t time) { + if (this->context == context) { + if (time) { + int64_t then = now() + time; + timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 }; + int rv = pthread_cond_timedwait(&condition, &mutex, &ts); + assert(s, rv == 0); + } else { + int rv = pthread_cond_wait(&condition, &mutex); + assert(s, rv == 0); + } + } else { + vm::abort(s); + } + } + + virtual void notify(void* context) { + if (this->context == context) { + int rv = pthread_cond_signal(&condition); + assert(s, rv == 0); + } else { + vm::abort(s); + } + } + + virtual void notifyAll(void* context) { + if (this->context == context) { + int rv = pthread_cond_broadcast(&condition); + assert(s, rv == 0); + } else { + vm::abort(s); + } + } + + virtual void dispose() { + pthread_mutex_destroy(&mutex); + pthread_cond_destroy(&condition); + s->free(this); + } vm::System* s; + pthread_mutex_t mutex; + pthread_cond_t condition; + void* context; + unsigned depth; }; class Library: public vm::System::Library { @@ -149,14 +247,20 @@ class System: public vm::System { vm::System::Library* next_; }; - System(unsigned limit): limit(limit), count(0) { } + System(unsigned limit): limit(limit), count(0) { + pthread_mutex_init(&mutex, 0); + } + + ~System() { + pthread_mutex_destroy(&mutex); + } virtual bool success(Status s) { return s == 0; } virtual void* tryAllocate(unsigned size) { - // todo: synchronize access + pthread_mutex_lock(&mutex); if (Verbose) { fprintf(stderr, "try %d; count: %d; limit: %d\n", @@ -164,20 +268,26 @@ class System: public vm::System { } if (count + size > limit) { + pthread_mutex_unlock(&mutex); return 0; + } else { + uintptr_t* up = static_cast + (malloc(size + sizeof(uintptr_t))); + if (up == 0) { + pthread_mutex_unlock(&mutex); + vm::abort(this); + } else { + *up = size; + count += *up; + + pthread_mutex_unlock(&mutex); + return up + 1; + } } - - uintptr_t* up = static_cast(malloc(size + sizeof(uintptr_t))); - if (up == 0) abort(); - - *up = size; - count += *up; - - return up + 1; } virtual void free(const void* p) { - // todo: synchronize access + pthread_mutex_lock(&mutex); if (p) { const uintptr_t* up = static_cast(p) - 1; @@ -193,10 +303,15 @@ class System: public vm::System { ::free(const_cast(up)); } + + pthread_mutex_unlock(&mutex); } - virtual Status start(Thread*) { - return 1; + virtual Status start(Thread* t) { + pthread_t thread; + int rv = pthread_create(&thread, 0, run, t); + assert(this, rv == 0); + return 0; } virtual Status make(vm::System::Monitor** m) { @@ -232,6 +347,7 @@ class System: public vm::System { ::abort(); } + pthread_mutex_t mutex; unsigned limit; unsigned count; }; diff --git a/src/system.h b/src/system.h index edd1d48176..c5b35d89b7 100644 --- a/src/system.h +++ b/src/system.h @@ -21,7 +21,7 @@ class System { virtual bool tryAcquire(void* id) = 0; virtual void acquire(void* id) = 0; virtual void release(void* id) = 0; - virtual void wait(void* id) = 0; + virtual void wait(void* id, int64_t time) = 0; virtual void notify(void* id) = 0; virtual void notifyAll(void* id) = 0; virtual void dispose() = 0; diff --git a/src/type-generator.cpp b/src/type-generator.cpp index e71c3a77cc..ba261bce6a 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -995,7 +995,7 @@ writeSubtypeAssertions(Output* out, Object* o) { for (Object* p = typeSubtypes(o); p; p = cdr(p)) { Object* st = car(p); - out->write(" or objectClass(o) == arrayBodyUnsafe"); + out->write(" or objectClass(t, o) == arrayBodyUnsafe"); out->write("(t, t->vm->types, Machine::"); out->write(capitalize(typeName(st))); out->write("Type)"); @@ -1035,8 +1035,8 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) if (unsafe) { out->write(" assert(t, true);"); } else { - out->write(" assert(t, t->vm->unsafe or objectClass(o) == 0 or "); - out->write("objectClass(o) == arrayBodyUnsafe"); + out->write(" assert(t, t->vm->unsafe or "); + out->write("objectClass(t, o) == arrayBodyUnsafe"); out->write("(t, t->vm->types, Machine::"); out->write(capitalize(::typeName(memberOwner(member)))); out->write("Type)"); @@ -1320,7 +1320,8 @@ writeConstructors(Output* out, Object* declarations) writeOffset(out, typeOffset(o), true); out->write(");\n"); - out->write(" objectClass(o) = arrayBody(t, t->vm->types, Machine::"); + out->write(" cast(o, 0) "); + out->write("= arrayBody(t, t->vm->types, Machine::"); out->write(capitalize(typeName(o))); out->write("Type);\n"); @@ -1538,7 +1539,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("objectClass(t->vm->types) = 0;\n"); + out->write("cast(t->vm->types, 0) = 0;\n"); out->write("arrayLength(t, t->vm->types) = "); out->write(count); out->write(";\n"); diff --git a/src/vm.cpp b/src/vm.cpp index f3c4a3de87..7235b52ad4 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -33,12 +33,6 @@ void set(Thread*, object&, object); object makeString(Thread*, const char*, ...); object makeByteArray(Thread*, const char*, ...); -object& -objectClass(object o) -{ - return cast(o, 0); -} - enum FieldCode { VoidField, ByteField, @@ -163,6 +157,12 @@ class Thread : public JNIEnv { object heap[HeapSizeInWords]; }; +inline object +objectClass(Thread*, object o) +{ + return mask(cast(o, 0)); +} + #include "type-declarations.cpp" #include "type-constructors.cpp" @@ -489,8 +489,8 @@ collect(Machine* m, Heap::CollectionType type) virtual unsigned sizeInWords(void* p) { Thread* t = m->rootThread; - p = m->heap->follow(p); - object class_ = m->heap->follow(objectClass(p)); + p = m->heap->follow(mask(p)); + object class_ = m->heap->follow(objectClass(t, p)); unsigned n = divide(classFixedSize(t, class_), BytesPerWord); @@ -505,8 +505,8 @@ collect(Machine* m, Heap::CollectionType type) virtual void walk(void* p, Heap::Walker* w) { Thread* t = m->rootThread; - p = m->heap->follow(p); - object class_ = m->heap->follow(objectClass(p)); + p = m->heap->follow(mask(p)); + object class_ = m->heap->follow(objectClass(t, p)); object objectMask = m->heap->follow(classObjectMask(t, class_)); if (objectMask) { @@ -599,7 +599,7 @@ enter(Thread* t, Thread::State s) t->vm->exclusive = t; while (t->vm->activeCount > 1) { - t->vm->stateLock->wait(t); + t->vm->stateLock->wait(t, 0); } } break; @@ -639,7 +639,7 @@ enter(Thread* t, Thread::State s) case Thread::NoState: case Thread::IdleState: { while (t->vm->exclusive) { - t->vm->stateLock->wait(t); + t->vm->stateLock->wait(t, 0); } ++ t->vm->activeCount; @@ -669,7 +669,7 @@ enter(Thread* t, Thread::State s) t->state = s; while (t->vm->liveCount > 1) { - t->vm->stateLock->wait(t); + t->vm->stateLock->wait(t, 0); } } break; @@ -762,7 +762,7 @@ make(Thread* t, object class_) unsigned objectSize(Thread* t, object o) { - object class_ = objectClass(o); + object class_ = objectClass(t, o); unsigned n = divide(classFixedSize(t, class_), BytesPerWord); @@ -921,8 +921,8 @@ makeUnsatisfiedLinkError(Thread* t, object message) inline bool isLongOrDouble(Thread* t, object o) { - return objectClass(o) == arrayBody(t, t->vm->types, Machine::LongType) - or objectClass(o) == arrayBody(t, t->vm->types, Machine::DoubleType); + return objectClass(t, o) == arrayBody(t, t->vm->types, Machine::LongType) + or objectClass(t, o) == arrayBody(t, t->vm->types, Machine::DoubleType); } unsigned @@ -1139,10 +1139,10 @@ instanceOf(Thread* t, object class_, object o) return false; } - if (objectClass(class_) + if (objectClass(t, class_) == arrayBody(t, t->vm->types, Machine::InterfaceType)) { - for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { + for (object oc = objectClass(t, o); oc; oc = classSuper(t, oc)) { object itable = classInterfaceTable(t, oc); for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { if (arrayBody(t, itable, i) == class_) { @@ -1151,7 +1151,7 @@ instanceOf(Thread* t, object class_, object o) } } } else { - for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { + for (object oc = objectClass(t, o); oc; oc = classSuper(t, oc)) { if (oc == class_) { return true; } @@ -1165,7 +1165,7 @@ object findInterfaceMethod(Thread* t, object method, object o) { object interface = methodClass(t, method); - object itable = classInterfaceTable(t, objectClass(o)); + object itable = classInterfaceTable(t, objectClass(t, o)); for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { if (arrayBody(t, itable, i) == interface) { return arrayBody(t, arrayBody(t, itable, i + 1), @@ -1185,7 +1185,7 @@ findMethod(Thread* t, object method, object class_) inline object findVirtualMethod(Thread* t, object method, object o) { - return findMethod(t, method, objectClass(o)); + return findMethod(t, method, objectClass(t, o)); } bool @@ -1336,7 +1336,8 @@ parsePool(Thread* t, Stream& s) for (unsigned i = 0; i < poolCount; ++i) { object o = arrayBody(t, pool, i); - if (objectClass(o) == arrayBody(t, t->vm->types, Machine::IntArrayType)) { + if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::IntArrayType)) + { switch (intArrayBody(t, o, 0)) { case CONSTANT_Class: { set(t, arrayBody(t, pool, i), @@ -1361,7 +1362,8 @@ parsePool(Thread* t, Stream& s) for (unsigned i = 0; i < poolCount; ++i) { object o = arrayBody(t, pool, i); - if (objectClass(o) == arrayBody(t, t->vm->types, Machine::IntArrayType)) { + if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::IntArrayType)) + { switch (intArrayBody(t, o, 0)) { case CONSTANT_Fieldref: case CONSTANT_Methodref: @@ -2064,7 +2066,8 @@ inline object resolveClass(Thread* t, object pool, unsigned index) { object o = arrayBody(t, pool, index); - if (objectClass(o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) { + if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + { PROTECT(t, pool); o = resolveClass(t, o); @@ -2079,7 +2082,8 @@ inline object resolveClass(Thread* t, object container, object& (*class_)(Thread*, object)) { object o = class_(t, container); - if (objectClass(o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) { + if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + { PROTECT(t, container); o = resolveClass(t, o); @@ -2095,7 +2099,8 @@ resolve(Thread* t, object pool, unsigned index, object (*find)(Thread*, object, object)) { object o = arrayBody(t, pool, index); - if (objectClass(o) == arrayBody(t, t->vm->types, Machine::ReferenceType)) { + if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ReferenceType)) + { PROTECT(t, pool); object class_ = resolveClass(t, o, referenceClass); @@ -2179,7 +2184,7 @@ makeNativeMethodData(Thread* t, object method, void* function, bool builtin) inline object resolveNativeMethodData(Thread* t, object method) { - if (objectClass(methodCode(t, method)) + if (objectClass(t, methodCode(t, method)) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) { object data = 0; @@ -2333,7 +2338,7 @@ toString(JNIEnv* e, jobject this_) object s = makeString (t, "%s@%p", - &byteArrayBody(t, className(t, objectClass(*this_)), 0), + &byteArrayBody(t, className(t, objectClass(t, *this_)), 0), *this_); pushSafe(t, s); @@ -2493,13 +2498,13 @@ Thread::Thread(Machine* m): #include "type-initializations.cpp" object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType); - set(t, objectClass(t->vm->types), arrayClass); + set(t, cast(t->vm->types, 0), arrayClass); object classClass = arrayBody(t, m->types, Machine::ClassType); - set(t, objectClass(classClass), classClass); + set(t, cast(classClass, 0), classClass); object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType); - set(t, objectClass(intArrayClass), classClass); + set(t, cast(intArrayClass, 0), classClass); m->unsafe = false; @@ -2668,7 +2673,7 @@ run(Thread* t) case arraylength: { object array = pop(t); if (LIKELY(array)) { - if (objectClass(array) + if (objectClass(t, array) == arrayBody(t, t->vm->types, Machine::ObjectArrayType)) { push(t, makeInt(t, objectArrayLength(t, array))); @@ -2832,7 +2837,7 @@ run(Thread* t) if (not instanceOf(t, class_, stack[sp - 1])) { object message = makeString (t, "%s as %s", - &byteArrayBody(t, className(t, objectClass(stack[sp - 1])), 0), + &byteArrayBody(t, className(t, objectClass(t, stack[sp - 1])), 0), &byteArrayBody(t, className(t, class_), 0)); exception = makeClassCastException(t, message); goto throw_; @@ -3639,6 +3644,26 @@ run(Thread* t) push(t, makeLong(t, longValue(t, a) ^ longValue(t, b))); } goto loop; +// case monitorenter: { +// object o = pop(t); +// if (LIKELY(o)) { +// objectMonitor(t, o)->acquire(t); +// } else { +// exception = makeNullPointerException(t); +// goto throw_; +// } +// } goto loop; + +// case monitorexit: { +// object o = pop(t); +// if (LIKELY(o)) { +// objectMonitor(t, o)->release(t); +// } else { +// exception = makeNullPointerException(t); +// goto throw_; +// } +// } goto loop; + case new_: { uint8_t index1 = codeBody(t, code, ip++); uint8_t index2 = codeBody(t, code, ip++); @@ -3948,7 +3973,7 @@ run(Thread* t) arrayBody(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1); if (catchType == 0 or - (objectClass(catchType) + (objectClass(t, catchType) == arrayBody(t, t->vm->types, Machine::ClassType) and instanceOf(t, catchType, exception))) { @@ -3970,7 +3995,7 @@ run(Thread* t) } fprintf(stderr, "%s", &byteArrayBody - (t, className(t, objectClass(exception)), 0)); + (t, className(t, objectClass(t, exception)), 0)); if (throwableMessage(t, exception)) { object m = throwableMessage(t, exception); @@ -3994,17 +4019,17 @@ run(Thread* t) int line = lineNumber (t, stackTraceElementMethod(t, e), stackTraceElementIp(t, e)); - fprintf(stderr, " at %s.%s", class_, method); + fprintf(stderr, " at %s.%s ", class_, method); switch (line) { case NativeLine: fprintf(stderr, "(native)\n"); break; case UnknownLine: - fprintf(stderr, "(unknown)\n"); + fprintf(stderr, "(unknown line)\n"); break; default: - fprintf(stderr, "(%d)\n", line); + fprintf(stderr, "(line %d)\n", line); } } }