mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
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:
parent
cda1ae81c8
commit
3d49173b0b
@ -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();
|
||||
|
||||
|
@ -40,8 +40,7 @@ search(Thread* t, object loader, object name,
|
||||
|
||||
return reinterpret_cast<int64_t>(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<int64_t>(r);
|
||||
} else {
|
||||
t->exception = t->m->classpath->makeThrowable
|
||||
(t, Machine::NullPointerExceptionType);
|
||||
t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -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<int64_t>(v);
|
||||
@ -348,12 +327,10 @@ Avian_java_lang_reflect_Array_getLength
|
||||
if (LIKELY(elementSize)) {
|
||||
return cast<uintptr_t>(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<object>(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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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<System::Region*>(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<int64_t>(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),
|
||||
|
@ -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<uint64_t>(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<uintptr_t>(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
|
||||
|
@ -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<uintptr_t>(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<int64_t>(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;
|
||||
}
|
||||
|
||||
|
@ -31,26 +31,17 @@ AttachCurrentThread(Machine* m, Thread** t, void*)
|
||||
{
|
||||
*t = static_cast<Thread*>(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<Thread*>(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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<jlong>(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<jlong>(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);
|
||||
|
||||
|
153
src/machine.h
153
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<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*
|
||||
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<jlong>(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<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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user