avoid inifinite recursion if java.lang.Object is missing; refactoring

When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc..  This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.

While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.

Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
This commit is contained in:
Joel Dice 2010-12-09 19:38:12 -07:00
parent cda1ae81c8
commit 3d49173b0b
11 changed files with 219 additions and 332 deletions

View File

@ -239,12 +239,12 @@ public class Thread implements Runnable {
} }
public synchronized void setDaemon(boolean v) { public synchronized void setDaemon(boolean v) {
if (v != daemon) { if (getState() != State.NEW) {
setDaemon(this, v); throw new IllegalStateException();
} }
}
private static native void setDaemon(Thread t, boolean increment); daemon = v;
}
public static native void yield(); public static native void yield();

View File

@ -40,8 +40,7 @@ search(Thread* t, object loader, object name,
return reinterpret_cast<int64_t>(r); return reinterpret_cast<int64_t>(r);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return 0; return 0;
} }
} }
@ -93,8 +92,7 @@ Avian_avian_SystemClassLoader_resourceExists
return r; return r;
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return 0; return 0;
} }
} }
@ -126,8 +124,7 @@ Avian_avian_Machine_dumpHeap
fclose(out); fclose(out);
} else { } else {
object message = makeString(t, "file not found: %s", n); object message = makeString(t, "file not found: %s", n);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::RuntimeExceptionType, message);
(t, Machine::RuntimeExceptionType, message);
} }
} }
@ -183,8 +180,7 @@ Avian_avian_resource_Handler_00024ResourceInputStream_open
return reinterpret_cast<int64_t>(r); return reinterpret_cast<int64_t>(r);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return 0; return 0;
} }
} }

View File

@ -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 virtual void
boot(Thread*) boot(Thread*)
{ {
@ -330,7 +309,7 @@ Avian_java_lang_reflect_Method_invoke
object v = t->m->processor->invokeArray(t, method, instance, args); object v = t->m->processor->invokeArray(t, method, instance, args);
if (t->exception) { if (t->exception) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::InvocationTargetExceptionType, 0, 0, t->exception); (t, Machine::InvocationTargetExceptionType, 0, 0, t->exception);
} }
return reinterpret_cast<int64_t>(v); return reinterpret_cast<int64_t>(v);
@ -348,12 +327,10 @@ Avian_java_lang_reflect_Array_getLength
if (LIKELY(elementSize)) { if (LIKELY(elementSize)) {
return cast<uintptr_t>(array, BytesPerWord); return cast<uintptr_t>(array, BytesPerWord);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType);
(t, Machine::IllegalArgumentExceptionType);
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
return 0; return 0;
} }
@ -462,8 +439,7 @@ Avian_java_lang_System_identityHashCode
if (LIKELY(o)) { if (LIKELY(o)) {
return objectHash(t, o); return objectHash(t, o);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return 0; return 0;
} }
} }
@ -604,16 +580,6 @@ Avian_java_lang_Thread_enumerate
return count; return count;
} }
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Thread_setDaemon
(Thread* t, object, uintptr_t* arguments)
{
object thread = reinterpret_cast<object>(arguments[0]);
bool daemon = arguments[1] != 0;
setDaemon(t, thread, daemon);
}
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Avian_avian_Classes_acquireClassLock Avian_avian_Classes_acquireClassLock
(Thread* t, object, uintptr_t*) (Thread* t, object, uintptr_t*)
@ -682,8 +648,7 @@ Avian_avian_Classes_isAssignableFrom
if (LIKELY(that)) { if (LIKELY(that)) {
return vm::isAssignableFrom(t, this_, that); return vm::isAssignableFrom(t, this_, that);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return 0; return 0;
} }
} }

View File

@ -101,7 +101,7 @@ arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
return; return;
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::IndexOutOfBoundsExceptionType); (t, Machine::IndexOutOfBoundsExceptionType);
return; return;
} }
@ -111,13 +111,11 @@ arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
} }
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
return; return;
} }
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::ArrayStoreExceptionType);
(t, Machine::ArrayStoreExceptionType);
} }
void void
@ -223,7 +221,7 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
} }
} else { } else {
object message = makeString(t, "library not found: %s", name); object message = makeString(t, "library not found: %s", name);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::UnsatisfiedLinkErrorType, message); (t, Machine::UnsatisfiedLinkErrorType, message);
} }

View File

@ -330,27 +330,6 @@ class MyClasspath : public Classpath {
release(t, t->javaThread); 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 virtual void
boot(Thread* t) 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)); EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
if (ef.jar) { if (ef.jar) {
if (ef.jarLength == 0 or ef.pathLength == 0) { if (ef.jarLength == 0 or ef.pathLength == 0) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType);
(t, Machine::FileNotFoundExceptionType);
return; return;
} }
Finder* finder = getFinder(t, ef.jar, ef.jarLength); Finder* finder = getFinder(t, ef.jar, ef.jarLength);
if (finder == 0) { if (finder == 0) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType);
(t, Machine::FileNotFoundExceptionType);
return; return;
} }
System::Region* r = finder->find(ef.path); System::Region* r = finder->find(ef.path);
if (r == 0) { if (r == 0) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::FileNotFoundExceptionType);
(t, Machine::FileNotFoundExceptionType);
return; return;
} }
@ -792,8 +768,7 @@ readByteFromFile(Thread* t, object method, uintptr_t* arguments)
return -1; return -1;
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IoExceptionType);
(t, Machine::IoExceptionType);
return 0; return 0;
} }
} else { } else {
@ -847,8 +822,7 @@ readBytesFromFile(Thread* t, object method, uintptr_t* arguments)
return length; return length;
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IoExceptionType);
(t, Machine::IoExceptionType);
return 0; return 0;
} }
} else { } else {
@ -892,8 +866,7 @@ skipBytesInFile(Thread* t, object method, uintptr_t* arguments)
return count; return count;
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IoExceptionType);
(t, Machine::IoExceptionType);
return 0; return 0;
} }
} else { } else {
@ -927,8 +900,7 @@ availableBytesInFile(Thread* t, object method, uintptr_t* arguments)
return static_cast<System::Region*>(regionRegion(t, region))->length() return static_cast<System::Region*>(regionRegion(t, region))->length()
- regionPosition(t, region); - regionPosition(t, region);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IoExceptionType);
(t, Machine::IoExceptionType);
return 0; return 0;
} }
} else { } else {
@ -1735,8 +1707,7 @@ Avian_sun_misc_Unsafe_allocateMemory
if (p) { if (p) {
return reinterpret_cast<int64_t>(p); return reinterpret_cast<int64_t>(p);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::OutOfMemoryErrorType);
(t, Machine::OutOfMemoryErrorType);
return 0; return 0;
} }
} }
@ -2474,8 +2445,7 @@ EXPORT(JVM_FindPrimitiveClass)(Thread* t, const char* name)
return makeLocalReference return makeLocalReference
(t, getJClass(t, type(t, Machine::JvoidType))); (t, getJClass(t, type(t, Machine::JvoidType)));
default: default:
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType);
(t, Machine::IllegalArgumentExceptionType);
return 0; return 0;
} }
} }
@ -2494,7 +2464,7 @@ EXPORT(JVM_FindClassFromClassLoader)(Thread* t, const char* name,
(t, loader ? *loader : root(t, Machine::BootLoader), name); (t, loader ? *loader : root(t, Machine::BootLoader), name);
if (t->exception) { if (t->exception) {
if (throwError) { if (throwError) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::NoClassDefFoundErrorType, (t, Machine::NoClassDefFoundErrorType,
throwableMessage(t, t->exception), throwableMessage(t, t->exception),
throwableTrace(t, t->exception), throwableTrace(t, t->exception),

View File

@ -2150,8 +2150,7 @@ findInterfaceMethodFromInstance(MyThread* t, object method, object instance)
return methodAddress(t, target); return methodAddress(t, target);
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
unwind(t); unwind(t);
} }
} }
@ -2422,7 +2421,7 @@ makeBlankObjectArray(MyThread* t, object class_, int32_t length)
return reinterpret_cast<uint64_t>(makeObjectArray(t, class_, length)); return reinterpret_cast<uint64_t>(makeObjectArray(t, class_, length));
} else { } else {
object message = makeString(t, "%d", length); object message = makeString(t, "%d", length);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
unwind(t); unwind(t);
} }
@ -2472,7 +2471,7 @@ makeBlankArray(MyThread* t, unsigned type, int32_t length)
return reinterpret_cast<uintptr_t>(constructor(t, length)); return reinterpret_cast<uintptr_t>(constructor(t, length));
} else { } else {
object message = makeString(t, "%d", length); object message = makeString(t, "%d", length);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
unwind(t); unwind(t);
} }
@ -2507,8 +2506,7 @@ setMaybeNull(MyThread* t, object o, unsigned offset, object value)
if (LIKELY(o)) { if (LIKELY(o)) {
set(t, o, offset, value); set(t, o, offset, value);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
unwind(t); unwind(t);
} }
} }
@ -2519,8 +2517,7 @@ acquireMonitorForObject(MyThread* t, object o)
if (LIKELY(o)) { if (LIKELY(o)) {
acquire(t, o); acquire(t, o);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
unwind(t); unwind(t);
} }
} }
@ -2531,8 +2528,7 @@ releaseMonitorForObject(MyThread* t, object o)
if (LIKELY(o)) { if (LIKELY(o)) {
release(t, o); release(t, o);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
unwind(t); unwind(t);
} }
} }
@ -2548,7 +2544,7 @@ makeMultidimensionalArray2(MyThread* t, object class_, uintptr_t* countStack,
RUNTIME_ARRAY_BODY(counts)[i] = countStack[dimensions - i - 1]; RUNTIME_ARRAY_BODY(counts)[i] = countStack[dimensions - i - 1];
if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) { if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
object message = makeString(t, "%d", RUNTIME_ARRAY_BODY(counts)[i]); object message = makeString(t, "%d", RUNTIME_ARRAY_BODY(counts)[i]);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
return 0; return 0;
} }
@ -2603,7 +2599,7 @@ throwArrayIndexOutOfBounds(MyThread* t)
{ {
if (ensure(t, FixedSizeOfArrayIndexOutOfBoundsException + traceSize(t))) { if (ensure(t, FixedSizeOfArrayIndexOutOfBoundsException + traceSize(t))) {
atomicOr(&(t->flags), Thread::TracingFlag); atomicOr(&(t->flags), Thread::TracingFlag);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType); (t, Machine::ArrayIndexOutOfBoundsExceptionType);
atomicAnd(&(t->flags), ~Thread::TracingFlag); atomicAnd(&(t->flags), ~Thread::TracingFlag);
} else { } else {
@ -2621,8 +2617,7 @@ throw_(MyThread* t, object o)
if (LIKELY(o)) { if (LIKELY(o)) {
t->exception = o; t->exception = o;
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
// printTrace(t, t->exception); // printTrace(t, t->exception);
@ -2638,8 +2633,7 @@ checkCast(MyThread* t, object class_, object o)
(t, "%s as %s", (t, "%s as %s",
&byteArrayBody(t, className(t, objectClass(t, o)), 0), &byteArrayBody(t, className(t, objectClass(t, o)), 0),
&byteArrayBody(t, className(t, class_), 0)); &byteArrayBody(t, className(t, class_), 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::ClassCastExceptionType, message);
(t, Machine::ClassCastExceptionType, message);
unwind(t); unwind(t);
} }
} }
@ -6837,7 +6831,7 @@ callContinuation(MyThread* t, object continuation, object result,
action = Call; action = Call;
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::IncompatibleContinuationExceptionType); (t, Machine::IncompatibleContinuationExceptionType);
action = Throw; action = Throw;
} }
@ -7175,8 +7169,7 @@ class SegFaultHandler: public System::SignalHandler {
if (ensure(t, FixedSizeOfNullPointerException + traceSize(t))) { if (ensure(t, FixedSizeOfNullPointerException + traceSize(t))) {
atomicOr(&(t->flags), Thread::TracingFlag); atomicOr(&(t->flags), Thread::TracingFlag);
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
atomicAnd(&(t->flags), ~Thread::TracingFlag); atomicAnd(&(t->flags), ~Thread::TracingFlag);
} else { } else {
// not enough memory available for a new NPE and stack trace // not enough memory available for a new NPE and stack trace

View File

@ -438,8 +438,7 @@ checkStack(Thread* t, object method)
+ codeMaxStack(t, methodCode(t, method)) + codeMaxStack(t, methodCode(t, method))
> Thread::StackSizeInWords / 2)) > Thread::StackSizeInWords / 2))
{ {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::StackOverflowErrorType);
(t, Machine::StackOverflowErrorType);
} }
} }
@ -864,13 +863,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString object message = makeString
(t, "%d not in [0,%d)", index, objectArrayLength(t, array)); (t, "%d not in [0,%d)", index, objectArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -888,13 +886,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString object message = makeString
(t, "%d not in [0,%d)", index, objectArrayLength(t, array)); (t, "%d not in [0,%d)", index, objectArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -935,7 +932,7 @@ interpret(Thread* t)
pushObject(t, makeObjectArray(t, class_, count)); pushObject(t, makeObjectArray(t, class_, count));
} else { } else {
object message = makeString(t, "%d", count); object message = makeString(t, "%d", count);
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
goto throw_; goto throw_;
} }
@ -957,8 +954,7 @@ interpret(Thread* t)
if (LIKELY(array)) { if (LIKELY(array)) {
pushInt(t, cast<uintptr_t>(array, BytesPerWord)); pushInt(t, cast<uintptr_t>(array, BytesPerWord));
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -986,8 +982,7 @@ interpret(Thread* t)
case athrow: { case athrow: {
exception = popObject(t); exception = popObject(t);
if (UNLIKELY(exception == 0)) { if (UNLIKELY(exception == 0)) {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
} goto throw_; } goto throw_;
@ -1005,7 +1000,7 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
booleanArrayLength(t, array)); booleanArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
@ -1019,14 +1014,13 @@ interpret(Thread* t)
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
byteArrayLength(t, array)); byteArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1046,7 +1040,7 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
booleanArrayLength(t, array)); booleanArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
@ -1058,14 +1052,13 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
byteArrayLength(t, array)); byteArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1086,13 +1079,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
charArrayLength(t, array)); charArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1110,13 +1102,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
charArrayLength(t, array)); charArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1134,7 +1125,7 @@ interpret(Thread* t)
&byteArrayBody &byteArrayBody
(t, className(t, objectClass(t, peekObject(t, sp - 1))), 0), (t, className(t, objectClass(t, peekObject(t, sp - 1))), 0),
&byteArrayBody(t, className(t, class_), 0)); &byteArrayBody(t, className(t, class_), 0));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ClassCastExceptionType, message); (t, Machine::ClassCastExceptionType, message);
goto throw_; goto throw_;
} }
@ -1172,13 +1163,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
doubleArrayLength(t, array)); doubleArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1196,13 +1186,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
doubleArrayLength(t, array)); doubleArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1376,13 +1365,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
floatArrayLength(t, array)); floatArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1400,13 +1388,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
floatArrayLength(t, array)); floatArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1518,8 +1505,7 @@ interpret(Thread* t)
} }
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1611,13 +1597,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
intArrayLength(t, array)); intArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1642,13 +1627,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
intArrayLength(t, array)); intArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1915,8 +1899,7 @@ interpret(Thread* t)
(t, method, objectClass(t, peekObject(t, sp - parameterFootprint))); (t, method, objectClass(t, peekObject(t, sp - parameterFootprint)));
goto invoke; goto invoke;
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1941,8 +1924,7 @@ interpret(Thread* t)
goto invoke; goto invoke;
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1973,8 +1955,7 @@ interpret(Thread* t)
code = findVirtualMethod(t, method, class_); code = findVirtualMethod(t, method, class_);
goto invoke; goto invoke;
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2110,13 +2091,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
longArrayLength(t, array)); longArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2141,13 +2121,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
longArrayLength(t, array)); longArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2373,8 +2352,7 @@ interpret(Thread* t)
if (LIKELY(o)) { if (LIKELY(o)) {
acquire(t, o); acquire(t, o);
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2384,8 +2362,7 @@ interpret(Thread* t)
if (LIKELY(o)) { if (LIKELY(o)) {
release(t, o); release(t, o);
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2403,7 +2380,7 @@ interpret(Thread* t)
counts[i] = popInt(t); counts[i] = popInt(t);
if (UNLIKELY(counts[i] < 0)) { if (UNLIKELY(counts[i] < 0)) {
object message = makeString(t, "%d", counts[i]); object message = makeString(t, "%d", counts[i]);
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
goto throw_; goto throw_;
} }
@ -2477,7 +2454,7 @@ interpret(Thread* t)
pushObject(t, array); pushObject(t, array);
} else { } else {
object message = makeString(t, "%d", count); object message = makeString(t, "%d", count);
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::NegativeArraySizeExceptionType, message); (t, Machine::NegativeArraySizeExceptionType, message);
goto throw_; goto throw_;
} }
@ -2540,8 +2517,7 @@ interpret(Thread* t)
break; break;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
} break; } break;
@ -2552,8 +2528,7 @@ interpret(Thread* t)
if (LIKELY(o)) { if (LIKELY(o)) {
cast<int64_t>(o, fieldOffset(t, field)) = value; cast<int64_t>(o, fieldOffset(t, field)) = value;
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
} break; } break;
@ -2563,8 +2538,7 @@ interpret(Thread* t)
if (LIKELY(o)) { if (LIKELY(o)) {
set(t, o, fieldOffset(t, field), value); set(t, o, fieldOffset(t, field), value);
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
} break; } break;
@ -2694,13 +2668,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
shortArrayLength(t, array)); shortArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2718,13 +2691,12 @@ interpret(Thread* t)
} else { } else {
object message = makeString(t, "%d not in [0,%d)", index, object message = makeString(t, "%d not in [0,%d)", index,
shortArrayLength(t, array)); shortArrayLength(t, array));
exception = t->m->classpath->makeThrowable exception = makeThrowable
(t, Machine::ArrayIndexOutOfBoundsExceptionType, message); (t, Machine::ArrayIndexOutOfBoundsExceptionType, message);
goto throw_; goto throw_;
} }
} else { } else {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -3166,8 +3138,7 @@ class MyProcessor: public Processor {
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2)) > Thread::StackSizeInWords / 2))
{ {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::StackOverflowErrorType);
(t, Machine::StackOverflowErrorType);
return 0; return 0;
} }
@ -3192,8 +3163,7 @@ class MyProcessor: public Processor {
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2)) > Thread::StackSizeInWords / 2))
{ {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::StackOverflowErrorType);
(t, Machine::StackOverflowErrorType);
return 0; return 0;
} }
@ -3217,8 +3187,7 @@ class MyProcessor: public Processor {
if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false) if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false)
> Thread::StackSizeInWords / 2)) > Thread::StackSizeInWords / 2))
{ {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::StackOverflowErrorType);
(t, Machine::StackOverflowErrorType);
return 0; return 0;
} }

View File

@ -31,26 +31,17 @@ AttachCurrentThread(Machine* m, Thread** t, void*)
{ {
*t = static_cast<Thread*>(m->localThread->get()); *t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) { if (*t == 0) {
*t = m->processor->makeThread(m, 0, m->rootThread); *t = attachThread(m, false);
m->system->attach(&((*t)->runnable));
enter(*t, Thread::ActiveState);
enter(*t, Thread::IdleState);
m->localThread->set(*t);
} }
return 0; return 0;
} }
jint JNICALL jint JNICALL
AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void* parameters) AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void*)
{ {
*t = static_cast<Thread*>(m->localThread->get()); *t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) { if (*t == 0) {
AttachCurrentThread(m, t, parameters); *t = attachThread(m, true);
ENTER(*t, Thread::ActiveState);
setDaemon(*t, (*t)->javaThread, true);
} }
return 0; return 0;
} }
@ -2040,13 +2031,12 @@ boot(Thread* t)
enter(t, Thread::ActiveState); enter(t, Thread::ActiveState);
if (t->exception == 0) { if (t->exception == 0) {
setRoot(t, Machine::NullPointerException, t->m->classpath->makeThrowable setRoot(t, Machine::NullPointerException, makeThrowable
(t, Machine::NullPointerExceptionType)); (t, Machine::NullPointerExceptionType));
if (t->exception == 0) { if (t->exception == 0) {
setRoot(t, Machine::ArrayIndexOutOfBoundsException, setRoot(t, Machine::ArrayIndexOutOfBoundsException,
t->m->classpath->makeThrowable makeThrowable(t, Machine::ArrayIndexOutOfBoundsExceptionType));
(t, Machine::ArrayIndexOutOfBoundsExceptionType));
} }
} }

View File

@ -1731,11 +1731,13 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec,
PROTECT(t, spec); PROTECT(t, spec);
PROTECT(t, elementClass); 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 resolveSystemClass
(t, root(t, Machine::BootLoader), (t, root(t, Machine::BootLoader),
className(t, type(t, Machine::JobjectType))); className(t, type(t, Machine::JobjectType)), false);
if (UNLIKELY(t->exception)) return 0;
} }
object vtable = classVirtualTable(t, type(t, Machine::JobjectType)); object vtable = classVirtualTable(t, type(t, Machine::JobjectType));
@ -2324,18 +2326,16 @@ Thread::init()
setRoot(this, Machine::JNIMethodTable, makeVector(this, 0, 0)); setRoot(this, Machine::JNIMethodTable, makeVector(this, 0, 0));
m->localThread->set(this); m->localThread->set(this);
javaThread = m->classpath->makeThread(this, 0);
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
} else { } else {
peer = parent->child; peer = parent->child;
parent->child = this; parent->child = this;
} }
expect(this, m->system->success(m->system->make(&lock))); expect(this, m->system->success(m->system->make(&lock)));
if (javaThread == 0) {
this->javaThread = m->classpath->makeThread(this, parent);
}
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
} }
void void
@ -2494,36 +2494,6 @@ enter(Thread* t, Thread::State s)
} break; } break;
case Thread::IdleState: 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)) { if (LIKELY(t->state == Thread::ActiveState)) {
// fast path // fast path
assert(t, t->m->activeCount > 0); assert(t, t->m->activeCount > 0);
@ -2563,7 +2533,7 @@ enter(Thread* t, Thread::State s)
assert(t, t->m->liveCount > 0); assert(t, t->m->liveCount > 0);
-- t->m->liveCount; -- t->m->liveCount;
if (threadDaemon(t, t->javaThread)) { if (t->flags & Thread::DaemonFlag) {
-- t->m->daemonCount; -- t->m->daemonCount;
} }
} }
@ -3239,7 +3209,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_)
hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash); hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash);
} else if (throw_ and t->exception == 0) { } else if (throw_ and t->exception == 0) {
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::ClassNotFoundExceptionType, message); (t, Machine::ClassNotFoundExceptionType, message);
} }
} }
@ -3334,7 +3304,7 @@ resolveClass(Thread* t, object loader, object spec, bool throw_)
} else { } else {
if (t->exception == 0) { if (t->exception == 0) {
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::ClassNotFoundExceptionType, message); (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, (t, "%s %s not found in %s", methodName, methodSpec,
&byteArrayBody(t, className(t, class_), 0)); &byteArrayBody(t, className(t, class_), 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NoSuchMethodErrorType, message);
(t, Machine::NoSuchMethodErrorType, message);
return 0; return 0;
} else { } else {
return method; return method;
@ -3395,8 +3364,7 @@ resolveField(Thread* t, object class_, const char* fieldName,
(t, "%s %s not found in %s", fieldName, fieldSpec, (t, "%s %s not found in %s", fieldName, fieldSpec,
&byteArrayBody(t, className(t, class_), 0)); &byteArrayBody(t, className(t, class_), 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::NoSuchFieldErrorType, message);
(t, Machine::NoSuchFieldErrorType, message);
return 0; return 0;
} else { } else {
return field; return field;
@ -3449,7 +3417,7 @@ preInitClass(Thread* t, object c)
object message = makeString object message = makeString
(t, "%s", &byteArrayBody(t, className(t, c), 0)); (t, "%s", &byteArrayBody(t, className(t, c), 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::NoClassDefFoundErrorType, message); (t, Machine::NoClassDefFoundErrorType, message);
} else { } else {
classVmFlags(t, c) |= InitFlag; classVmFlags(t, c) |= InitFlag;
@ -3467,7 +3435,7 @@ postInitClass(Thread* t, object c)
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
if (t->exception) { if (t->exception) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::ExceptionInInitializerErrorType, 0, 0, t->exception); (t, Machine::ExceptionInInitializerErrorType, 0, 0, t->exception);
classVmFlags(t, c) |= NeedInitFlag | InitErrorFlag; classVmFlags(t, c) |= NeedInitFlag | InitErrorFlag;
@ -3527,6 +3495,7 @@ resolveObjectArrayClass(Thread* t, object loader, object elementClass)
} }
object arrayClass = resolveClass(t, loader, spec); object arrayClass = resolveClass(t, loader, spec);
if (UNLIKELY(t->exception)) return 0;
set(t, getClassRuntimeData(t, elementClass), ClassRuntimeDataArrayClass, set(t, getClassRuntimeData(t, elementClass), ClassRuntimeDataArrayClass,
arrayClass); arrayClass);
@ -3539,6 +3508,8 @@ makeObjectArray(Thread* t, object elementClass, unsigned count)
{ {
object arrayClass = resolveObjectArrayClass object arrayClass = resolveObjectArrayClass
(t, classLoader(t, elementClass), elementClass); (t, classLoader(t, elementClass), elementClass);
if (UNLIKELY(t->exception)) return 0;
PROTECT(t, arrayClass); PROTECT(t, arrayClass);
object array = makeArray(t, count); object array = makeArray(t, count);
@ -3760,13 +3731,12 @@ collect(Thread* t, Heap::CollectionType type)
} }
if (root(t, Machine::ObjectsToFinalize) and m->finalizeThread == 0) { if (root(t, Machine::ObjectsToFinalize) and m->finalizeThread == 0) {
m->finalizeThread = m->processor->makeThread object javaThread = t->m->classpath->makeThread(t, m->rootThread);
(m, t->m->classpath->makeThread(t, m->rootThread), m->rootThread); threadDaemon(t, javaThread) = true;
if (not t->m->system->success m->finalizeThread = m->processor->makeThread(m, javaThread, m->rootThread);
(m->system->start(&(m->finalizeThread->runnable))))
{ if (not startThread(t, m->finalizeThread)) {
m->finalizeThread->exit();
m->finalizeThread = 0; m->finalizeThread = 0;
} }
} }
@ -3849,8 +3819,7 @@ void
printTrace(Thread* t, object exception) printTrace(Thread* t, object exception)
{ {
if (exception == 0) { if (exception == 0) {
exception = t->m->classpath->makeThrowable exception = makeThrowable(t, Machine::NullPointerExceptionType);
(t, Machine::NullPointerExceptionType);
} }
for (object e = exception; e; e = throwableCause(t, e)) { for (object e = exception; e; e = throwableCause(t, e)) {
@ -3956,8 +3925,6 @@ makeTrace(Thread* t, Thread* target)
void void
runFinalizeThread(Thread* t) runFinalizeThread(Thread* t)
{ {
setDaemon(t, t->javaThread, true);
object list = 0; object list = 0;
PROTECT(t, list); PROTECT(t, list);

View File

@ -1282,6 +1282,9 @@ runJavaThread(Thread* t);
void void
runFinalizeThread(Thread* t); runFinalizeThread(Thread* t);
void
checkDaemon(Thread* t);
class Thread { class Thread {
public: public:
enum State { enum State {
@ -1361,6 +1364,8 @@ class Thread {
t->m->localThread->set(t); t->m->localThread->set(t);
checkDaemon(t);
if (t == t->m->finalizeThread) { if (t == t->m->finalizeThread) {
runFinalizeThread(t); runFinalizeThread(t);
} else if (t->javaThread) { } else if (t->javaThread) {
@ -1429,11 +1434,6 @@ class Classpath {
virtual void virtual void
runThread(Thread* t) = 0; runThread(Thread* t) = 0;
virtual object
makeThrowable
(Thread* t, Machine::Type type, object message = 0, object trace = 0,
object cause = 0) = 0;
virtual void virtual void
boot(Thread* t) = 0; boot(Thread* t) = 0;
@ -1709,19 +1709,6 @@ setObjectClass(Thread*, object o, object value)
| (reinterpret_cast<uintptr_t>(cast<object>(o, 0)) & (~PointerMask))); | (reinterpret_cast<uintptr_t>(cast<object>(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* inline const char*
findProperty(Machine* m, const char* name) findProperty(Machine* m, const char* name)
{ {
@ -1759,6 +1746,69 @@ runJavaThread(Thread* t)
t->m->classpath->runThread(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<jlong>(t);
if (daemon) {
threadDaemon(t, t->javaThread) = true;
registerDaemon(t);
}
enter(t, Thread::IdleState);
m->localThread->set(t);
return t;
}
inline object& inline object&
root(Thread* t, Machine::Root root) 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); (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 object
findInHierarchyOrNull(Thread* t, object class_, object name, object spec, findInHierarchyOrNull(Thread* t, object class_, object name, object spec,
object (*find)(Thread*, object, object, object)); 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, name, 0),
&byteArrayBody(t, spec, 0), &byteArrayBody(t, spec, 0),
&byteArrayBody(t, className(t, class_), 0)); &byteArrayBody(t, className(t, class_), 0));
t->exception = t->m->classpath->makeThrowable(t, errorType, message); t->exception = makeThrowable(t, errorType, message);
} }
return o; return o;
@ -2707,12 +2779,10 @@ wait(Thread* t, object o, int64_t milliseconds)
bool interrupted = monitorWait(t, m, milliseconds); bool interrupted = monitorWait(t, m, milliseconds);
if (interrupted) { if (interrupted) {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::InterruptedExceptionType);
(t, Machine::InterruptedExceptionType);
} }
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType);
(t, Machine::IllegalMonitorStateExceptionType);
} }
if (DebugMonitors) { if (DebugMonitors) {
@ -2741,8 +2811,7 @@ notify(Thread* t, object o)
if (m and monitorOwner(t, m) == t) { if (m and monitorOwner(t, m) == t) {
monitorNotify(t, m); monitorNotify(t, m);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType);
(t, Machine::IllegalMonitorStateExceptionType);
} }
} }
@ -2759,8 +2828,7 @@ notifyAll(Thread* t, object o)
if (m and monitorOwner(t, m) == t) { if (m and monitorOwner(t, m) == t) {
monitorNotifyAll(t, m); monitorNotifyAll(t, m);
} else { } else {
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalMonitorStateExceptionType);
(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<Thread*>(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 object
intern(Thread* t, object s); intern(Thread* t, object s);
@ -3157,8 +3197,7 @@ primitiveClass(Thread* t, char name)
case 'V': return type(t, Machine::JvoidType); case 'V': return type(t, Machine::JvoidType);
case 'Z': return type(t, Machine::JbooleanType); case 'Z': return type(t, Machine::JbooleanType);
default: default:
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable(t, Machine::IllegalArgumentExceptionType);
(t, Machine::IllegalArgumentExceptionType);
return 0; return 0;
} }
} }

View File

@ -243,7 +243,7 @@ resolveNative(Thread* t, object method)
&byteArrayBody(t, methodName(t, method), 0), &byteArrayBody(t, methodName(t, method), 0),
&byteArrayBody(t, methodSpec(t, method), 0)); &byteArrayBody(t, methodSpec(t, method), 0));
t->exception = t->m->classpath->makeThrowable t->exception = makeThrowable
(t, Machine::UnsatisfiedLinkErrorType, message); (t, Machine::UnsatisfiedLinkErrorType, message);
return; return;
} }