diff --git a/makefile b/makefile index 9b7705e8b3..5c7f63fc0f 100644 --- a/makefile +++ b/makefile @@ -32,7 +32,7 @@ src = src classpath = classpath test = test -input = $(cls)/Hello.class +input = $(cls)/Threads.class cxx = g++ cc = gcc diff --git a/src/builtin.cpp b/src/builtin.cpp index 01e69f8082..271288f6fd 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -308,11 +308,12 @@ Java_java_lang_reflect_Method_getCaller(Thread* t, jclass) { ENTER(t, Thread::ActiveState); - FrameIterator it; t->m->processor->start(t, &it); - t->m->processor->next(t, &it); - t->m->processor->next(t, &it); + Processor* p = t->m->processor; + uintptr_t frame = p->frameStart(t); + frame = p->frameNext(t, frame); + frame = p->frameNext(t, frame); - return makeLocalReference(t, it.method); + return makeLocalReference(t, p->frameMethod(t, frame)); } extern "C" JNIEXPORT jobject JNICALL @@ -321,7 +322,7 @@ Java_java_lang_reflect_Method_invoke { ENTER(t, Thread::ActiveState); - object v = t->m->processor->invoke + object v = t->m->processor->invokeArray (t, *method, (instance ? *instance : 0), *arguments); if (t->exception) { t->exception = makeInvocationTargetException(t, t->exception); @@ -529,25 +530,27 @@ Java_java_lang_Throwable_trace(Thread* t, jclass, jint skipCount) { ENTER(t, Thread::ActiveState); - FrameIterator it; t->m->processor->start(t, &it); + Processor* p = t->m->processor; + uintptr_t frame = p->frameStart(t); - while (skipCount-- and it.valid()) { - t->m->processor->next(t, &it); + while (skipCount-- and p->frameValid(t, frame)) { + frame = p->frameNext(t, frame); } // skip Throwable constructors - while (it.valid() + while (p->frameValid(t, frame) and isAssignableFrom (t, arrayBody(t, t->m->types, Machine::ThrowableType), - methodClass(t, it.method)) + methodClass(t, p->frameMethod(t, frame))) and strcmp(reinterpret_cast(""), - &byteArrayBody(t, methodName(t, it.method), 0)) + &byteArrayBody + (t, methodName(t, p->frameMethod(t, frame)), 0)) == 0) { - t->m->processor->next(t, &it); + frame = p->frameNext(t, frame); } - return makeLocalReference(t, makeTrace(t, &it)); + return makeLocalReference(t, makeTrace(t, frame)); } extern "C" JNIEXPORT jarray JNICALL @@ -599,8 +602,7 @@ Java_java_lang_Thread_doStart(Thread* t, jobject this_) { ENTER(t, Thread::ActiveState); - Thread* p = new (t->m->system->allocate(sizeof(Thread))) - Thread(t->m, *this_, t); + Thread* p = t->m->processor->makeThread(t->m, *this_, t); enter(p, Thread::ActiveState); diff --git a/src/interpret.cpp b/src/interpret.cpp index 6ad06e7316..3a4fb5ac33 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -28,45 +28,6 @@ class Thread: public vm::Thread { uintptr_t stack[StackSizeInWords]; }; -class MyProcessor: public Processor { - public: - MyProcessor(System* s): - s(s) - { } - - virtual vm::Thread* - makeThread(Machine* m, object javaThread, vm::Thread* parent) - { - return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent); - } - - virtual void - visitObjects(vm::Thread* t, Heap::Visitor* v); - - virtual void - start(vm::Thread* t, FrameIterator* it); - - virtual void - next(vm::Thread* t, FrameIterator* it); - - virtual object - invokeArray(vm::Thread* t, object method, object this_, object arguments); - - virtual object - invokeList(vm::Thread* t, object method, object this_, bool indirectObjects, - va_list arguments); - - virtual object - invokeList(vm::Thread* t, const char* className, const char* methodName, - const char* methodSpec, object this_, va_list arguments); - - virtual void dispose() { - s->free(this); - } - - System* s; -}; - inline void pushObject(Thread* t, object o) { @@ -3039,127 +3000,176 @@ invoke(Thread* t, object method) } } -void -MyProcessor::visitObjects(vm::Thread* vmt, Heap::Visitor* v) -{ - Thread* t = static_cast(vmt); +class MyProcessor: public Processor { + public: + MyProcessor(System* s): + s(s) + { } - v->visit(&(t->code)); + virtual vm::Thread* + makeThread(Machine* m, object javaThread, vm::Thread* parent) + { + return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent); + } - for (unsigned i = 0; i < t->sp; ++i) { - if (t->stack[i * 2] == ObjectTag) { - v->visit(t->stack + (i * 2) + 1); + virtual void + visitObjects(vm::Thread* vmt, Heap::Visitor* v) + { + Thread* t = static_cast(vmt); + + v->visit(&(t->code)); + + for (unsigned i = 0; i < t->sp; ++i) { + if (t->stack[i * 2] == ObjectTag) { + v->visit(t->stack + (i * 2) + 1); + } } } -} -void -MyProcessor::start(vm::Thread* vmt, FrameIterator* it) -{ - Thread* t = static_cast(vmt); + virtual uintptr_t + frameStart(vm::Thread* vmt) + { + Thread* t = static_cast(vmt); - int f = t->frame; - it->base = f + 1; - if (it->valid()) { - pokeInt(t, t->frame + FrameIpOffset, t->ip); - it->method = frameMethod(t, f); - it->ip = frameIp(t, f); + if (t->frame >= 0) { + pokeInt(t, t->frame + FrameIpOffset, t->ip); + } + return t->frame; } -} -void -MyProcessor::next(vm::Thread* vmt, FrameIterator* it) -{ - Thread* t = static_cast(vmt); + virtual uintptr_t + frameNext(vm::Thread* vmt, uintptr_t frame) + { + Thread* t = static_cast(vmt); - if (it->valid()) { - int f = frameNext(t, it->base - 1); - it->base = f + 1; - if (it->valid()) { - it->method = frameMethod(t, f); - it->ip = frameIp(t, f); + assert(t, static_cast(frame) >= 0); + return ::frameNext(t, frame); + } + + virtual bool + frameValid(vm::Thread*, uintptr_t frame) + { + return static_cast(frame) >= 0; + } + + virtual object + frameMethod(vm::Thread* vmt, uintptr_t frame) + { + Thread* t = static_cast(vmt); + + assert(t, static_cast(frame) >= 0); + return ::frameMethod(t, frame); + } + + virtual unsigned + frameIp(vm::Thread* vmt, uintptr_t frame) + { + Thread* t = static_cast(vmt); + + assert(t, static_cast(frame) >= 0); + return ::frameIp(t, frame); + } + + virtual object* + makeLocalReference(vm::Thread* vmt, object o) + { + Thread* t = static_cast(vmt); + + return pushReference(t, o); + } + + virtual void + disposeLocalReference(vm::Thread*, object* r) + { + if (r) { + *r = 0; } } -} -object -MyProcessor::invokeArray(vm::Thread* vmt, object method, object this_, - object arguments) -{ - Thread* t = static_cast(vmt); - - assert(t, t->state == Thread::ActiveState - or t->state == Thread::ExclusiveState); - - assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); - - if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 - > Thread::StackSizeInWords / 2)) + virtual object + invokeArray(vm::Thread* vmt, object method, object this_, object arguments) { - t->exception = makeStackOverflowError(t); - return 0; - } + Thread* t = static_cast(vmt); - const char* spec = reinterpret_cast - (&byteArrayBody(t, methodSpec(t, method), 0)); - pushArguments(t, this_, spec, arguments); + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); - return ::invoke(t, method); -} - -object -MyProcessor::invokeList(vm::Thread* vmt, object method, object this_, - bool indirectObjects, va_list arguments) -{ - Thread* t = static_cast(vmt); - - assert(t, t->state == Thread::ActiveState - or t->state == Thread::ExclusiveState); - - assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); - - if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 - > Thread::StackSizeInWords / 2)) - { - t->exception = makeStackOverflowError(t); - return 0; - } - - const char* spec = reinterpret_cast - (&byteArrayBody(t, methodSpec(t, method), 0)); - pushArguments(t, this_, spec, indirectObjects, arguments); - - return ::invoke(t, method); -} - -object -MyProcessor::invokeList(vm::Thread* vmt, const char* className, - const char* methodName, const char* methodSpec, - object this_, va_list arguments) -{ - Thread* t = static_cast(vmt); - - assert(t, t->state == Thread::ActiveState - or t->state == Thread::ExclusiveState); - - if (UNLIKELY(t->sp + parameterFootprint(methodSpec) + 1 - > Thread::StackSizeInWords / 2)) - { - t->exception = makeStackOverflowError(t); - return 0; - } - - pushArguments(t, this_, methodSpec, false, arguments); - - object method = resolveMethod(t, className, methodName, methodSpec); - if (LIKELY(t->exception == 0)) { assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 + > Thread::StackSizeInWords / 2)) + { + t->exception = makeStackOverflowError(t); + return 0; + } + + const char* spec = reinterpret_cast + (&byteArrayBody(t, methodSpec(t, method), 0)); + pushArguments(t, this_, spec, arguments); + return ::invoke(t, method); - } else { - return 0; } -} + + virtual object + invokeList(vm::Thread* vmt, object method, object this_, + bool indirectObjects, + va_list arguments) + { + Thread* t = static_cast(vmt); + + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); + + assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + + if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 + > Thread::StackSizeInWords / 2)) + { + t->exception = makeStackOverflowError(t); + return 0; + } + + const char* spec = reinterpret_cast + (&byteArrayBody(t, methodSpec(t, method), 0)); + pushArguments(t, this_, spec, indirectObjects, arguments); + + return ::invoke(t, method); + } + + virtual object + invokeList(vm::Thread* vmt, const char* className, const char* methodName, + const char* methodSpec, object this_, va_list arguments) + { + Thread* t = static_cast(vmt); + + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); + + if (UNLIKELY(t->sp + parameterFootprint(methodSpec) + 1 + > Thread::StackSizeInWords / 2)) + { + t->exception = makeStackOverflowError(t); + return 0; + } + + pushArguments(t, this_, methodSpec, false, arguments); + + object method = resolveMethod(t, className, methodName, methodSpec); + if (LIKELY(t->exception == 0)) { + assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + + return ::invoke(t, method); + } else { + return 0; + } + } + + virtual void dispose() { + s->free(this); + } + + System* s; +}; } // namespace diff --git a/src/machine.cpp b/src/machine.cpp index 0441ce6837..48011f44ba 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2752,21 +2752,28 @@ run(System* system, Heap* heap, Finder* finder, Processor* processor, } object -makeTrace(Thread* t, FrameIterator* it) +makeTrace(Thread* t, uintptr_t start) { + Processor* p = t->m->processor; + unsigned count = 0; - FrameIterator copy(it); - while (copy.valid()) { + for (uintptr_t frame = start; + p->frameValid(t, frame); + frame = p->frameNext(t, frame)) + { ++ count; - t->m->processor->next(t, ©); } object trace = makeArray(t, count, true); PROTECT(t, trace); unsigned index = 0; - while (it->valid()) { - object e = makeTraceElement(t, it->method, it->ip); + for (uintptr_t frame = start; + p->frameValid(t, frame); + frame = p->frameNext(t, frame)) + { + object e = makeTraceElement + (t, p->frameMethod(t, frame), p->frameIp(t, frame)); set(t, arrayBody(t, trace, index++), e); } diff --git a/src/machine.h b/src/machine.h index ccc391c7fa..890fa7f9c5 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1423,13 +1423,12 @@ arrayBodyUnsafe(Thread*, object, unsigned); #include "type-declarations.cpp" object -makeTrace(Thread* t, FrameIterator* it); +makeTrace(Thread* t, uintptr_t start); inline object makeTrace(Thread* t) { - FrameIterator it; t->m->processor->start(t, &it); - return makeTrace(t, &it); + return makeTrace(t, t->m->processor->frameStart(t)); } inline object @@ -2054,11 +2053,17 @@ int run(System* system, Heap* heap, Finder* finder, Processor* processor, const char* className, int argc, const char** argv); -jobject -makeLocalReference(Thread* t, object o); +inline jobject +makeLocalReference(Thread* t, object o) +{ + return t->m->processor->makeLocalReference(t, o); +} -void -disposeLocalReference(Thread* t, jobject r); +inline void +disposeLocalReference(Thread* t, jobject r) +{ + t->m->processor->disposeLocalReference(t, r); +} } // namespace vm diff --git a/src/processor.h b/src/processor.h index 929215ab1f..fa91fadbdc 100644 --- a/src/processor.h +++ b/src/processor.h @@ -7,29 +7,6 @@ namespace vm { -class FrameIterator { - public: - FrameIterator(): - base(0), - method(0), - ip(0) - { } - - FrameIterator(FrameIterator* it): - base(it->base), - method(it->method), - ip(it->ip) - { } - - bool valid() { - return base != 0; - } - - uintptr_t base; - object method; - unsigned ip; -}; - class Processor { public: virtual ~Processor() { } @@ -40,11 +17,26 @@ class Processor { virtual void visitObjects(Thread* t, Heap::Visitor* v) = 0; - virtual void - start(Thread* t, FrameIterator* it) = 0; + virtual uintptr_t + frameStart(Thread* t) = 0; - virtual void - next(Thread* t, FrameIterator* it) = 0; + virtual uintptr_t + frameNext(Thread* t, uintptr_t frame) = 0; + + virtual bool + frameValid(Thread* t, uintptr_t frame) = 0; + + virtual object + frameMethod(Thread* t, uintptr_t frame) = 0; + + virtual unsigned + frameIp(Thread* t, uintptr_t frame) = 0; + + virtual object* + makeLocalReference(Thread* t, object o) = 0; + + virtual void + disposeLocalReference(Thread* t, object* r) = 0; virtual object invokeArray(Thread* t, object method, object this_, object arguments) = 0; diff --git a/valgrind.supp b/valgrind.supp index 69ecd0aba1..9ca17ffbbf 100644 --- a/valgrind.supp +++ b/valgrind.supp @@ -17,28 +17,28 @@ obj:/lib/ld-2.3.6.so } -{ - - Memcheck:Param - write(buf) - obj:* -} +# { +# +# Memcheck:Param +# write(buf) +# obj:* +# } -{ - - Memcheck:Param - writev(vector[...]) - obj:* -} +# { +# +# Memcheck:Param +# writev(vector[...]) +# obj:* +# } -{ - - Memcheck:Cond - obj:* -} +# { +# +# Memcheck:Cond +# obj:* +# } -{ - - Memcheck:Value8 - obj:* -} +# { +# +# Memcheck:Value8 +# obj:* +# }