diff --git a/classpath/java/lang/Thread.java b/classpath/java/lang/Thread.java index 0606f51377..2d321193a0 100644 --- a/classpath/java/lang/Thread.java +++ b/classpath/java/lang/Thread.java @@ -239,12 +239,12 @@ public class Thread implements Runnable { } public synchronized void setDaemon(boolean v) { - if (v != daemon) { - setDaemon(this, v); + if (getState() != State.NEW) { + throw new IllegalStateException(); } - } - private static native void setDaemon(Thread t, boolean increment); + daemon = v; + } public static native void yield(); diff --git a/src/builtin.cpp b/src/builtin.cpp index 3c0365ea7b..dd8ece531a 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -40,8 +40,7 @@ search(Thread* t, object loader, object name, return reinterpret_cast(r); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return 0; } } @@ -93,8 +92,7 @@ Avian_avian_SystemClassLoader_resourceExists return r; } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return 0; } } @@ -126,8 +124,7 @@ Avian_avian_Machine_dumpHeap fclose(out); } else { object message = makeString(t, "file not found: %s", n); - t->exception = t->m->classpath->makeThrowable - (t, Machine::RuntimeExceptionType, message); + t->exception = makeThrowable(t, Machine::RuntimeExceptionType, message); } } @@ -183,8 +180,7 @@ Avian_avian_resource_Handler_00024ResourceInputStream_open return reinterpret_cast(r); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return 0; } } diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index 8bc2560086..51f5058713 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -65,27 +65,6 @@ class MyClasspath : public Classpath { } } - virtual object - makeThrowable - (Thread* t, Machine::Type type, object message, object trace, object cause) - { - PROTECT(t, message); - PROTECT(t, trace); - PROTECT(t, cause); - - if (trace == 0) { - trace = makeTrace(t); - } - - object result = make(t, vm::type(t, type)); - - set(t, result, ThrowableMessage, message); - set(t, result, ThrowableTrace, trace); - set(t, result, ThrowableCause, cause); - - return result; - } - virtual void boot(Thread*) { @@ -330,7 +309,7 @@ Avian_java_lang_reflect_Method_invoke object v = t->m->processor->invokeArray(t, method, instance, args); if (t->exception) { - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::InvocationTargetExceptionType, 0, 0, t->exception); } return reinterpret_cast(v); @@ -348,12 +327,10 @@ Avian_java_lang_reflect_Array_getLength if (LIKELY(elementSize)) { return cast(array, BytesPerWord); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalArgumentExceptionType); + t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType); } } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); } return 0; } @@ -462,8 +439,7 @@ Avian_java_lang_System_identityHashCode if (LIKELY(o)) { return objectHash(t, o); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return 0; } } @@ -604,16 +580,6 @@ Avian_java_lang_Thread_enumerate return count; } -extern "C" JNIEXPORT void JNICALL -Avian_java_lang_Thread_setDaemon -(Thread* t, object, uintptr_t* arguments) -{ - object thread = reinterpret_cast(arguments[0]); - bool daemon = arguments[1] != 0; - - setDaemon(t, thread, daemon); -} - extern "C" JNIEXPORT void JNICALL Avian_avian_Classes_acquireClassLock (Thread* t, object, uintptr_t*) @@ -682,8 +648,7 @@ Avian_avian_Classes_isAssignableFrom if (LIKELY(that)) { return vm::isAssignableFrom(t, this_, that); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return 0; } } diff --git a/src/classpath-common.h b/src/classpath-common.h index 3ca61210a0..7d17a74673 100644 --- a/src/classpath-common.h +++ b/src/classpath-common.h @@ -101,7 +101,7 @@ arrayCopy(Thread* t, object src, int32_t srcOffset, object dst, return; } else { - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::IndexOutOfBoundsExceptionType); return; } @@ -111,13 +111,11 @@ arrayCopy(Thread* t, object src, int32_t srcOffset, object dst, } } } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); return; } - t->exception = t->m->classpath->makeThrowable - (t, Machine::ArrayStoreExceptionType); + t->exception = makeThrowable(t, Machine::ArrayStoreExceptionType); } void @@ -223,7 +221,7 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName, } } else { object message = makeString(t, "library not found: %s", name); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::UnsatisfiedLinkErrorType, message); } diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index eda7ac90de..c18445d298 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -330,27 +330,6 @@ class MyClasspath : public Classpath { release(t, t->javaThread); } - virtual object - makeThrowable - (Thread* t, Machine::Type type, object message, object trace, object cause) - { - PROTECT(t, message); - PROTECT(t, trace); - PROTECT(t, cause); - - if (trace == 0) { - trace = makeTrace(t); - } - - object result = make(t, vm::type(t, type)); - - set(t, result, ThrowableMessage, message); - set(t, result, ThrowableTrace, trace); - set(t, result, ThrowableCause, cause); - - return result; - } - virtual void boot(Thread* t) { @@ -709,22 +688,19 @@ openFile(Thread* t, object method, uintptr_t* arguments) EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path)); if (ef.jar) { if (ef.jarLength == 0 or ef.pathLength == 0) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::FileNotFoundExceptionType); + t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType); return; } Finder* finder = getFinder(t, ef.jar, ef.jarLength); if (finder == 0) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::FileNotFoundExceptionType); + t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType); return; } System::Region* r = finder->find(ef.path); if (r == 0) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::FileNotFoundExceptionType); + t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType); return; } @@ -792,8 +768,7 @@ readByteFromFile(Thread* t, object method, uintptr_t* arguments) return -1; } } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IoExceptionType); + t->exception = makeThrowable(t, Machine::IoExceptionType); return 0; } } else { @@ -847,8 +822,7 @@ readBytesFromFile(Thread* t, object method, uintptr_t* arguments) return length; } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IoExceptionType); + t->exception = makeThrowable(t, Machine::IoExceptionType); return 0; } } else { @@ -892,8 +866,7 @@ skipBytesInFile(Thread* t, object method, uintptr_t* arguments) return count; } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IoExceptionType); + t->exception = makeThrowable(t, Machine::IoExceptionType); return 0; } } else { @@ -927,8 +900,7 @@ availableBytesInFile(Thread* t, object method, uintptr_t* arguments) return static_cast(regionRegion(t, region))->length() - regionPosition(t, region); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IoExceptionType); + t->exception = makeThrowable(t, Machine::IoExceptionType); return 0; } } else { @@ -1735,8 +1707,7 @@ Avian_sun_misc_Unsafe_allocateMemory if (p) { return reinterpret_cast(p); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::OutOfMemoryErrorType); + t->exception = makeThrowable(t, Machine::OutOfMemoryErrorType); return 0; } } @@ -2474,8 +2445,7 @@ EXPORT(JVM_FindPrimitiveClass)(Thread* t, const char* name) return makeLocalReference (t, getJClass(t, type(t, Machine::JvoidType))); default: - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalArgumentExceptionType); + t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType); return 0; } } @@ -2494,7 +2464,7 @@ EXPORT(JVM_FindClassFromClassLoader)(Thread* t, const char* name, (t, loader ? *loader : root(t, Machine::BootLoader), name); if (t->exception) { if (throwError) { - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::NoClassDefFoundErrorType, throwableMessage(t, t->exception), throwableTrace(t, t->exception), diff --git a/src/compile.cpp b/src/compile.cpp index 3bafb38eff..6cdd70f5e7 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2150,8 +2150,7 @@ findInterfaceMethodFromInstance(MyThread* t, object method, object instance) return methodAddress(t, target); } } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); unwind(t); } } @@ -2422,7 +2421,7 @@ makeBlankObjectArray(MyThread* t, object class_, int32_t length) return reinterpret_cast(makeObjectArray(t, class_, length)); } else { object message = makeString(t, "%d", length); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); unwind(t); } @@ -2472,7 +2471,7 @@ makeBlankArray(MyThread* t, unsigned type, int32_t length) return reinterpret_cast(constructor(t, length)); } else { object message = makeString(t, "%d", length); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); unwind(t); } @@ -2507,8 +2506,7 @@ setMaybeNull(MyThread* t, object o, unsigned offset, object value) if (LIKELY(o)) { set(t, o, offset, value); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); unwind(t); } } @@ -2519,8 +2517,7 @@ acquireMonitorForObject(MyThread* t, object o) if (LIKELY(o)) { acquire(t, o); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); unwind(t); } } @@ -2531,8 +2528,7 @@ releaseMonitorForObject(MyThread* t, object o) if (LIKELY(o)) { release(t, o); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); unwind(t); } } @@ -2548,7 +2544,7 @@ makeMultidimensionalArray2(MyThread* t, object class_, uintptr_t* countStack, RUNTIME_ARRAY_BODY(counts)[i] = countStack[dimensions - i - 1]; if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) { object message = makeString(t, "%d", RUNTIME_ARRAY_BODY(counts)[i]); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); return 0; } @@ -2603,7 +2599,7 @@ throwArrayIndexOutOfBounds(MyThread* t) { if (ensure(t, FixedSizeOfArrayIndexOutOfBoundsException + traceSize(t))) { atomicOr(&(t->flags), Thread::TracingFlag); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType); atomicAnd(&(t->flags), ~Thread::TracingFlag); } else { @@ -2621,8 +2617,7 @@ throw_(MyThread* t, object o) if (LIKELY(o)) { t->exception = o; } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); } // printTrace(t, t->exception); @@ -2638,8 +2633,7 @@ checkCast(MyThread* t, object class_, object o) (t, "%s as %s", &byteArrayBody(t, className(t, objectClass(t, o)), 0), &byteArrayBody(t, className(t, class_), 0)); - t->exception = t->m->classpath->makeThrowable - (t, Machine::ClassCastExceptionType, message); + t->exception = makeThrowable(t, Machine::ClassCastExceptionType, message); unwind(t); } } @@ -6837,7 +6831,7 @@ callContinuation(MyThread* t, object continuation, object result, action = Call; } } else { - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::IncompatibleContinuationExceptionType); action = Throw; } @@ -7175,8 +7169,7 @@ class SegFaultHandler: public System::SignalHandler { if (ensure(t, FixedSizeOfNullPointerException + traceSize(t))) { atomicOr(&(t->flags), Thread::TracingFlag); - t->exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + t->exception = makeThrowable(t, Machine::NullPointerExceptionType); atomicAnd(&(t->flags), ~Thread::TracingFlag); } else { // not enough memory available for a new NPE and stack trace diff --git a/src/interpret.cpp b/src/interpret.cpp index 1634463ea1..e9d4c418c1 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -438,8 +438,7 @@ checkStack(Thread* t, object method) + codeMaxStack(t, methodCode(t, method)) > Thread::StackSizeInWords / 2)) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::StackOverflowErrorType); + t->exception = makeThrowable(t, Machine::StackOverflowErrorType); } } @@ -864,13 +863,12 @@ interpret(Thread* t) } else { object message = makeString (t, "%d not in [0,%d)", index, objectArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -888,13 +886,12 @@ interpret(Thread* t) } else { object message = makeString (t, "%d not in [0,%d)", index, objectArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -935,7 +932,7 @@ interpret(Thread* t) pushObject(t, makeObjectArray(t, class_, count)); } else { object message = makeString(t, "%d", count); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); goto throw_; } @@ -957,8 +954,7 @@ interpret(Thread* t) if (LIKELY(array)) { pushInt(t, cast(array, BytesPerWord)); } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -986,8 +982,7 @@ interpret(Thread* t) case athrow: { exception = popObject(t); if (UNLIKELY(exception == 0)) { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); } } goto throw_; @@ -1005,7 +1000,7 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, booleanArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } @@ -1019,14 +1014,13 @@ interpret(Thread* t) object message = makeString(t, "%d not in [0,%d)", index, byteArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1046,7 +1040,7 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, booleanArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } @@ -1058,14 +1052,13 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, byteArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1086,13 +1079,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, charArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1110,13 +1102,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, charArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1134,7 +1125,7 @@ interpret(Thread* t) &byteArrayBody (t, className(t, objectClass(t, peekObject(t, sp - 1))), 0), &byteArrayBody(t, className(t, class_), 0)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ClassCastExceptionType, message); goto throw_; } @@ -1172,13 +1163,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, doubleArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1196,13 +1186,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, doubleArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1376,13 +1365,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, floatArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1400,13 +1388,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, floatArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1518,8 +1505,7 @@ interpret(Thread* t) } } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1611,13 +1597,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, intArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1642,13 +1627,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, intArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1915,8 +1899,7 @@ interpret(Thread* t) (t, method, objectClass(t, peekObject(t, sp - parameterFootprint))); goto invoke; } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1941,8 +1924,7 @@ interpret(Thread* t) goto invoke; } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -1973,8 +1955,7 @@ interpret(Thread* t) code = findVirtualMethod(t, method, class_); goto invoke; } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2110,13 +2091,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, longArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2141,13 +2121,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, longArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2373,8 +2352,7 @@ interpret(Thread* t) if (LIKELY(o)) { acquire(t, o); } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2384,8 +2362,7 @@ interpret(Thread* t) if (LIKELY(o)) { release(t, o); } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2403,7 +2380,7 @@ interpret(Thread* t) counts[i] = popInt(t); if (UNLIKELY(counts[i] < 0)) { object message = makeString(t, "%d", counts[i]); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); goto throw_; } @@ -2477,7 +2454,7 @@ interpret(Thread* t) pushObject(t, array); } else { object message = makeString(t, "%d", count); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::NegativeArraySizeExceptionType, message); goto throw_; } @@ -2540,8 +2517,7 @@ interpret(Thread* t) break; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); } } break; @@ -2552,8 +2528,7 @@ interpret(Thread* t) if (LIKELY(o)) { cast(o, fieldOffset(t, field)) = value; } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); } } break; @@ -2563,8 +2538,7 @@ interpret(Thread* t) if (LIKELY(o)) { set(t, o, fieldOffset(t, field), value); } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); } } break; @@ -2694,13 +2668,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, shortArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -2718,13 +2691,12 @@ interpret(Thread* t) } else { object message = makeString(t, "%d not in [0,%d)", index, shortArrayLength(t, array)); - exception = t->m->classpath->makeThrowable + exception = makeThrowable (t, Machine::ArrayIndexOutOfBoundsExceptionType, message); goto throw_; } } else { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); goto throw_; } } goto loop; @@ -3166,8 +3138,7 @@ class MyProcessor: public Processor { if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 > Thread::StackSizeInWords / 2)) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::StackOverflowErrorType); + t->exception = makeThrowable(t, Machine::StackOverflowErrorType); return 0; } @@ -3192,8 +3163,7 @@ class MyProcessor: public Processor { if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 > Thread::StackSizeInWords / 2)) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::StackOverflowErrorType); + t->exception = makeThrowable(t, Machine::StackOverflowErrorType); return 0; } @@ -3217,8 +3187,7 @@ class MyProcessor: public Processor { if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false) > Thread::StackSizeInWords / 2)) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::StackOverflowErrorType); + t->exception = makeThrowable(t, Machine::StackOverflowErrorType); return 0; } diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 7579b9891e..38598a385a 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -31,26 +31,17 @@ AttachCurrentThread(Machine* m, Thread** t, void*) { *t = static_cast(m->localThread->get()); if (*t == 0) { - *t = m->processor->makeThread(m, 0, m->rootThread); - m->system->attach(&((*t)->runnable)); - - enter(*t, Thread::ActiveState); - enter(*t, Thread::IdleState); - - m->localThread->set(*t); + *t = attachThread(m, false); } return 0; } jint JNICALL -AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void* parameters) +AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void*) { *t = static_cast(m->localThread->get()); if (*t == 0) { - AttachCurrentThread(m, t, parameters); - - ENTER(*t, Thread::ActiveState); - setDaemon(*t, (*t)->javaThread, true); + *t = attachThread(m, true); } return 0; } @@ -2040,13 +2031,12 @@ boot(Thread* t) enter(t, Thread::ActiveState); if (t->exception == 0) { - setRoot(t, Machine::NullPointerException, t->m->classpath->makeThrowable + setRoot(t, Machine::NullPointerException, makeThrowable (t, Machine::NullPointerExceptionType)); if (t->exception == 0) { setRoot(t, Machine::ArrayIndexOutOfBoundsException, - t->m->classpath->makeThrowable - (t, Machine::ArrayIndexOutOfBoundsExceptionType)); + makeThrowable(t, Machine::ArrayIndexOutOfBoundsExceptionType)); } } diff --git a/src/machine.cpp b/src/machine.cpp index ec1c06ae61..ddf27487b1 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1731,11 +1731,13 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec, PROTECT(t, spec); PROTECT(t, elementClass); + // Load java.lang.Object if present so we can use its vtable, but + // don't throw an exception if we can't find it. This way, we + // avoid infinite recursion due to trying to create an array to + // make a stack trace for a ClassNotFoundException. resolveSystemClass (t, root(t, Machine::BootLoader), - className(t, type(t, Machine::JobjectType))); - - if (UNLIKELY(t->exception)) return 0; + className(t, type(t, Machine::JobjectType)), false); } object vtable = classVirtualTable(t, type(t, Machine::JobjectType)); @@ -2324,18 +2326,16 @@ Thread::init() setRoot(this, Machine::JNIMethodTable, makeVector(this, 0, 0)); m->localThread->set(this); + + javaThread = m->classpath->makeThread(this, 0); + + threadPeer(this, javaThread) = reinterpret_cast(this); } else { peer = parent->child; parent->child = this; } expect(this, m->system->success(m->system->make(&lock))); - - if (javaThread == 0) { - this->javaThread = m->classpath->makeThread(this, parent); - } - - threadPeer(this, javaThread) = reinterpret_cast(this); } void @@ -2494,36 +2494,6 @@ enter(Thread* t, Thread::State s) } break; case Thread::IdleState: - // The java.lang.Thread implementation may or may not notify the - // VM when the daemon field in the Java object changes, so we sync - // up the native field whenever the thread transitions to idle: - - // todo: this won't always help if some other thread sets the - // daemon field. The thread trying to shut down the VM really - // just needs to count from scratch every time any thread makes a - // transition (i.e. eliminate Machine::daemonCount). - - if (UNLIKELY(((t->flags & Thread::DaemonFlag) != 0) - != threadDaemon(t, t->javaThread))) - { - ACQUIRE_LOCK; - - if (threadDaemon(t, t->javaThread)) { - atomicOr(&(t->flags), Thread::DaemonFlag); - } else { - atomicAnd(&(t->flags), ~Thread::DaemonFlag); - } - - if (t->flags & Thread::DaemonFlag) { - ++ t->m->daemonCount; - } else { - expect(t, t->m->daemonCount); - -- t->m->daemonCount; - } - - t->m->stateLock->notifyAll(t->systemThread); - } - if (LIKELY(t->state == Thread::ActiveState)) { // fast path assert(t, t->m->activeCount > 0); @@ -2563,7 +2533,7 @@ enter(Thread* t, Thread::State s) assert(t, t->m->liveCount > 0); -- t->m->liveCount; - if (threadDaemon(t, t->javaThread)) { + if (t->flags & Thread::DaemonFlag) { -- t->m->daemonCount; } } @@ -3239,7 +3209,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_) hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash); } else if (throw_ and t->exception == 0) { object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::ClassNotFoundExceptionType, message); } } @@ -3334,7 +3304,7 @@ resolveClass(Thread* t, object loader, object spec, bool throw_) } else { if (t->exception == 0) { object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::ClassNotFoundExceptionType, message); } @@ -3361,8 +3331,7 @@ resolveMethod(Thread* t, object class_, const char* methodName, (t, "%s %s not found in %s", methodName, methodSpec, &byteArrayBody(t, className(t, class_), 0)); - t->exception = t->m->classpath->makeThrowable - (t, Machine::NoSuchMethodErrorType, message); + t->exception = makeThrowable(t, Machine::NoSuchMethodErrorType, message); return 0; } else { return method; @@ -3395,8 +3364,7 @@ resolveField(Thread* t, object class_, const char* fieldName, (t, "%s %s not found in %s", fieldName, fieldSpec, &byteArrayBody(t, className(t, class_), 0)); - t->exception = t->m->classpath->makeThrowable - (t, Machine::NoSuchFieldErrorType, message); + t->exception = makeThrowable(t, Machine::NoSuchFieldErrorType, message); return 0; } else { return field; @@ -3449,7 +3417,7 @@ preInitClass(Thread* t, object c) object message = makeString (t, "%s", &byteArrayBody(t, className(t, c), 0)); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::NoClassDefFoundErrorType, message); } else { classVmFlags(t, c) |= InitFlag; @@ -3467,7 +3435,7 @@ postInitClass(Thread* t, object c) ACQUIRE(t, t->m->classLock); if (t->exception) { - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::ExceptionInInitializerErrorType, 0, 0, t->exception); classVmFlags(t, c) |= NeedInitFlag | InitErrorFlag; @@ -3527,6 +3495,7 @@ resolveObjectArrayClass(Thread* t, object loader, object elementClass) } object arrayClass = resolveClass(t, loader, spec); + if (UNLIKELY(t->exception)) return 0; set(t, getClassRuntimeData(t, elementClass), ClassRuntimeDataArrayClass, arrayClass); @@ -3539,6 +3508,8 @@ makeObjectArray(Thread* t, object elementClass, unsigned count) { object arrayClass = resolveObjectArrayClass (t, classLoader(t, elementClass), elementClass); + if (UNLIKELY(t->exception)) return 0; + PROTECT(t, arrayClass); object array = makeArray(t, count); @@ -3760,13 +3731,12 @@ collect(Thread* t, Heap::CollectionType type) } if (root(t, Machine::ObjectsToFinalize) and m->finalizeThread == 0) { - m->finalizeThread = m->processor->makeThread - (m, t->m->classpath->makeThread(t, m->rootThread), m->rootThread); + object javaThread = t->m->classpath->makeThread(t, m->rootThread); + threadDaemon(t, javaThread) = true; - if (not t->m->system->success - (m->system->start(&(m->finalizeThread->runnable)))) - { - m->finalizeThread->exit(); + m->finalizeThread = m->processor->makeThread(m, javaThread, m->rootThread); + + if (not startThread(t, m->finalizeThread)) { m->finalizeThread = 0; } } @@ -3849,8 +3819,7 @@ void printTrace(Thread* t, object exception) { if (exception == 0) { - exception = t->m->classpath->makeThrowable - (t, Machine::NullPointerExceptionType); + exception = makeThrowable(t, Machine::NullPointerExceptionType); } for (object e = exception; e; e = throwableCause(t, e)) { @@ -3956,8 +3925,6 @@ makeTrace(Thread* t, Thread* target) void runFinalizeThread(Thread* t) { - setDaemon(t, t->javaThread, true); - object list = 0; PROTECT(t, list); diff --git a/src/machine.h b/src/machine.h index 4c65230095..984d4e54db 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1282,6 +1282,9 @@ runJavaThread(Thread* t); void runFinalizeThread(Thread* t); +void +checkDaemon(Thread* t); + class Thread { public: enum State { @@ -1361,6 +1364,8 @@ class Thread { t->m->localThread->set(t); + checkDaemon(t); + if (t == t->m->finalizeThread) { runFinalizeThread(t); } else if (t->javaThread) { @@ -1429,11 +1434,6 @@ class Classpath { virtual void runThread(Thread* t) = 0; - virtual object - makeThrowable - (Thread* t, Machine::Type type, object message = 0, object trace = 0, - object cause = 0) = 0; - virtual void boot(Thread* t) = 0; @@ -1709,19 +1709,6 @@ setObjectClass(Thread*, object o, object value) | (reinterpret_cast(cast(o, 0)) & (~PointerMask))); } -inline Thread* -startThread(Thread* t, object javaThread) -{ - Thread* p = t->m->processor->makeThread(t->m, javaThread, t); - - if (t->m->system->success(t->m->system->start(&(p->runnable)))) { - return p; - } else { - p->exit(); - return 0; - } -} - inline const char* findProperty(Machine* m, const char* name) { @@ -1759,6 +1746,69 @@ runJavaThread(Thread* t) t->m->classpath->runThread(t); } +inline bool +startThread(Thread* t, Thread* p) +{ + return t->m->system->success(t->m->system->start(&(p->runnable))); +} + +inline Thread* +startThread(Thread* t, object javaThread) +{ + Thread* p = t->m->processor->makeThread(t->m, javaThread, t); + + if (startThread(t, p)) { + return p; + } else { + return 0; + } +} + +inline void +registerDaemon(Thread* t) +{ + ACQUIRE_RAW(t, t->m->stateLock); + + atomicOr(&(t->flags), Thread::DaemonFlag); + + ++ t->m->daemonCount; + + t->m->stateLock->notifyAll(t->systemThread); +} + +inline void +checkDaemon(Thread* t) +{ + if (threadDaemon(t, t->javaThread)) { + registerDaemon(t); + } +} + +inline Thread* +attachThread(Machine* m, bool daemon) +{ + Thread* t = m->processor->makeThread(m, 0, m->rootThread); + m->system->attach(&(t->runnable)); + + enter(t, Thread::ActiveState); + + t->javaThread = m->classpath->makeThread(t, m->rootThread); + + threadPeer(t, t->javaThread) = reinterpret_cast(t); + + if (daemon) { + threadDaemon(t, t->javaThread) = true; + + registerDaemon(t); + } + + enter(t, Thread::IdleState); + + m->localThread->set(t); + + return t; +} + inline object& root(Thread* t, Machine::Root root) { @@ -2237,6 +2287,28 @@ findMethodInClass(Thread* t, object class_, object name, object spec) (t, classMethodTable(t, class_), name, spec, methodName, methodSpec); } +inline object +makeThrowable +(Thread* t, Machine::Type type, object message = 0, object trace = 0, + object cause = 0) +{ + PROTECT(t, message); + PROTECT(t, trace); + PROTECT(t, cause); + + if (trace == 0) { + trace = makeTrace(t); + } + + object result = make(t, vm::type(t, type)); + + set(t, result, ThrowableMessage, message); + set(t, result, ThrowableTrace, trace); + set(t, result, ThrowableCause, cause); + + return result; +} + object findInHierarchyOrNull(Thread* t, object class_, object name, object spec, object (*find)(Thread*, object, object, object)); @@ -2254,7 +2326,7 @@ findInHierarchy(Thread* t, object class_, object name, object spec, &byteArrayBody(t, name, 0), &byteArrayBody(t, spec, 0), &byteArrayBody(t, className(t, class_), 0)); - t->exception = t->m->classpath->makeThrowable(t, errorType, message); + t->exception = makeThrowable(t, errorType, message); } return o; @@ -2707,12 +2779,10 @@ wait(Thread* t, object o, int64_t milliseconds) bool interrupted = monitorWait(t, m, milliseconds); if (interrupted) { - t->exception = t->m->classpath->makeThrowable - (t, Machine::InterruptedExceptionType); + t->exception = makeThrowable(t, Machine::InterruptedExceptionType); } } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalMonitorStateExceptionType); + t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType); } if (DebugMonitors) { @@ -2741,8 +2811,7 @@ notify(Thread* t, object o) if (m and monitorOwner(t, m) == t) { monitorNotify(t, m); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalMonitorStateExceptionType); + t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType); } } @@ -2759,8 +2828,7 @@ notifyAll(Thread* t, object o) if (m and monitorOwner(t, m) == t) { monitorNotifyAll(t, m); } else { - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalMonitorStateExceptionType); + t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType); } } @@ -2803,34 +2871,6 @@ interrupt(Thread* t, Thread* target) } } -inline void -setDaemon(Thread* t, object thread, bool daemon) -{ - ACQUIRE_RAW(t, t->m->stateLock); - - if ((threadDaemon(t, thread) != 0) != daemon) { - threadDaemon(t, thread) = daemon; - - Thread* p = reinterpret_cast(threadPeer(t, thread)); - if (p) { - if (daemon) { - atomicOr(&(p->flags), Thread::DaemonFlag); - } else { - atomicAnd(&(p->flags), ~Thread::DaemonFlag); - } - } - - if (daemon) { - ++ t->m->daemonCount; - } else { - expect(t, t->m->daemonCount); - -- t->m->daemonCount; - } - - t->m->stateLock->notifyAll(t->systemThread); - } -} - object intern(Thread* t, object s); @@ -3157,8 +3197,7 @@ primitiveClass(Thread* t, char name) case 'V': return type(t, Machine::JvoidType); case 'Z': return type(t, Machine::JbooleanType); default: - t->exception = t->m->classpath->makeThrowable - (t, Machine::IllegalArgumentExceptionType); + t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType); return 0; } } diff --git a/src/process.cpp b/src/process.cpp index cab5fb8b4f..00edbe66b7 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -243,7 +243,7 @@ resolveNative(Thread* t, object method) &byteArrayBody(t, methodName(t, method), 0), &byteArrayBody(t, methodSpec(t, method), 0)); - t->exception = t->m->classpath->makeThrowable + t->exception = makeThrowable (t, Machine::UnsatisfiedLinkErrorType, message); return; }