diff --git a/src/compile.cpp b/src/compile.cpp index 9bc57e2fa2..905aeee7a4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -70,7 +70,8 @@ class MyThread: public Thread { base(0), stack(0), trace(0), - reference(0) + reference(0), + methodInvoked(0) { } void* ip; @@ -78,6 +79,7 @@ class MyThread: public Thread { void* stack; CallTrace* trace; Reference* reference; + object methodInvoked; }; object @@ -4087,10 +4089,17 @@ uint64_t FORCE_ALIGN invokeNative(MyThread* t) { object node = findTraceNode(t, *static_cast(t->stack)); - object target = traceNodeTarget(t, node); - if (traceNodeVirtualCall(t, node)) { - target = resolveTarget(t, t->stack, target); + object target; + if (node) { + target = traceNodeTarget(t, node); + if (traceNodeVirtualCall(t, node)) { + target = resolveTarget(t, t->stack, target); + } + } else { + target = t->methodInvoked; + t->methodInvoked = 0; } + uint64_t result = 0; if (LIKELY(t->exception == 0)) { @@ -4339,6 +4348,10 @@ invoke(Thread* thread, object method, ArgumentList* arguments) unsigned returnCode = methodReturnCode(t, method); unsigned returnType = fieldType(t, returnCode); + if (methodFlags(t, method) & ACC_NATIVE) { + t->methodInvoked = method; + } + uint64_t result; { MyThread::CallTrace trace(t); @@ -4348,6 +4361,8 @@ invoke(Thread* thread, object method, ArgumentList* arguments) arguments->position, returnType); } + assert(t, t->methodInvoked == 0); + object r; switch (returnCode) { case ByteField: @@ -4528,6 +4543,8 @@ class MyProcessor: public Processor { v->visit(&addressTable); } + v->visit(&(t->methodInvoked)); + for (Reference* r = t->reference; r; r = r->next) { v->visit(&(r->target)); } @@ -4577,6 +4594,8 @@ class MyProcessor: public Processor { virtual object invokeArray(Thread* t, object method, object this_, object arguments) { + if (UNLIKELY(t->exception)) return 0; + assert(t, t->state == Thread::ActiveState or t->state == Thread::ExclusiveState); @@ -4605,6 +4624,8 @@ class MyProcessor: public Processor { invokeList(Thread* t, object method, object this_, bool indirectObjects, va_list arguments) { + if (UNLIKELY(t->exception)) return 0; + assert(t, t->state == Thread::ActiveState or t->state == Thread::ExclusiveState); @@ -4634,6 +4655,8 @@ class MyProcessor: public Processor { invokeList(Thread* t, const char* className, const char* methodName, const char* methodSpec, object this_, va_list arguments) { + if (UNLIKELY(t->exception)) return 0; + assert(t, t->state == Thread::ActiveState or t->state == Thread::ExclusiveState); diff --git a/src/jnienv.cpp b/src/jnienv.cpp index bbd9ef74b2..4b0806a577 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -287,11 +287,20 @@ getMethod(Thread* t, object o, jmethodID m) { if (m & InterfaceMethodID) { return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); - } else if (m & NonVirtualMethodID) { - return arrayBody(t, classMethodTable(t, objectClass(t, o)), - m & (~NonVirtualMethodID)); } else { - return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); + if (classVmFlags(t, objectClass(t, o)) & BootstrapFlag) { + PROTECT(t, o); + + resolveClass(t, className(t, objectClass(t, o))); + if (UNLIKELY(t->exception)) return 0; + } + + if (m & NonVirtualMethodID) { + return arrayBody(t, classMethodTable(t, objectClass(t, o)), + m & (~NonVirtualMethodID)); + } else { + return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); + } } } @@ -326,8 +335,9 @@ CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - return makeLocalReference(t, t->m->processor->invokeList - (t, getMethod(t, *o, m), *o, true, a)); + object method = getMethod(t, *o, m); + return makeLocalReference + (t, t->m->processor->invokeList(t, method, *o, true, a)); } jobject JNICALL @@ -348,7 +358,8 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? false : (intValue(t, r) != 0)); } @@ -370,7 +381,8 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -392,7 +404,8 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -414,7 +427,8 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -436,7 +450,8 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -458,7 +473,8 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -480,7 +496,8 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } @@ -502,7 +519,8 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } @@ -524,7 +542,8 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); + object method = getMethod(t, *o, m); + t->m->processor->invokeList(t, method, *o, true, a); } void JNICALL @@ -539,9 +558,16 @@ CallVoidMethod(Thread* t, jobject o, jmethodID m, ...) } inline object -getStaticMethod(Thread* t, object class_, jmethodID m) +getStaticMethod(Thread* t, object c, jmethodID m) { - return arrayBody(t, classMethodTable(t, class_), m - 1); + if (classVmFlags(t, c) & BootstrapFlag) { + PROTECT(t, c); + + resolveClass(t, className(t, c)); + if (UNLIKELY(t->exception)) return 0; + } + + return arrayBody(t, classMethodTable(t, c), m - 1); } jobject JNICALL diff --git a/src/machine.cpp b/src/machine.cpp index a59def2a75..fcebb85d86 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -861,7 +861,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) if (flags & ACC_STATIC) { unsigned size = fieldSize(t, code); - unsigned excess = staticOffset % size; + unsigned excess = (staticOffset % size) % BytesPerWord; if (excess) { staticOffset += BytesPerWord - excess; } @@ -878,7 +878,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) abort(t); // todo: handle non-static field initializers } - unsigned excess = memberOffset % fieldSize(t, code); + unsigned excess = (memberOffset % fieldSize(t, code)) % BytesPerWord; if (excess) { memberOffset += BytesPerWord - excess; } diff --git a/test/Misc.java b/test/Misc.java index f75b38d92c..d4a2b3251c 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -2,7 +2,22 @@ public class Misc { private static int alpha; private static int beta; private static byte byte1, byte2, byte3; + private int gamma; + private int pajama; + private boolean boolean1; + private boolean boolean2; + private long time; + + public Misc() { + expect(! boolean1); + expect(! boolean2); + + time = 0xffffffffffffffffL; + + expect(! boolean1); + expect(! boolean2); + } private String foo(String s) { return s;