diff --git a/makefile b/makefile index 96d49ce0ce..9b7705e8b3 100644 --- a/makefile +++ b/makefile @@ -93,9 +93,9 @@ interpreter-depends = \ $(src)/system.h \ $(src)/heap.h \ $(src)/finder.h \ + $(src)/processor.h \ $(src)/stream.h \ $(src)/constants.h \ - $(src)/run.h \ $(src)/jnienv.h \ $(src)/machine.h @@ -104,7 +104,7 @@ interpreter-sources = \ $(src)/finder.cpp \ $(src)/machine.cpp \ $(src)/heap.cpp \ - $(src)/run.cpp \ + $(src)/interpret.cpp \ $(src)/builtin.cpp \ $(src)/jnienv.cpp \ $(src)/main.cpp @@ -151,7 +151,7 @@ flags = -cp $(cls) args = $(flags) $(call class-name,$(input)) .PHONY: build -build: $(executable) $(classpath-objects) +build: $(executable) $(classpath-objects) $(test-classes) $(input): $(classpath-objects) diff --git a/src/builtin.cpp b/src/builtin.cpp index cb15584d9a..01e69f8082 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -1,6 +1,6 @@ #include "machine.h" #include "constants.h" -#include "run.h" +#include "processor.h" #undef JNIEXPORT #define JNIEXPORT __attribute__ ((visibility("default"))) @@ -33,7 +33,7 @@ search(Thread* t, jstring name, object (*op)(Thread*, object), return 0; } - return pushReference(t, r); + return makeLocalReference(t, r); } else { t->exception = makeNullPointerException(t); return 0; @@ -53,7 +53,7 @@ Java_java_lang_Object_toString(Thread* t, jobject this_) &byteArrayBody(t, className(t, objectClass(t, *this_)), 0), hash); - return pushReference(t, s); + return makeLocalReference(t, s); } extern "C" JNIEXPORT jclass JNICALL @@ -61,7 +61,7 @@ Java_java_lang_Object_getClass(Thread* t, jobject this_) { ENTER(t, Thread::ActiveState); - return pushReference(t, objectClass(t, *this_)); + return makeLocalReference(t, objectClass(t, *this_)); } extern "C" JNIEXPORT void JNICALL @@ -105,7 +105,7 @@ Java_java_lang_Object_clone(Thread* t, jclass, jobject o) memcpy(reinterpret_cast(clone) + 1, reinterpret_cast(*o) + 1, (baseSize(t, *o, objectClass(t, *o)) - 1) * BytesPerWord); - return pushReference(t, clone); + return makeLocalReference(t, clone); } extern "C" JNIEXPORT jclass JNICALL @@ -114,11 +114,11 @@ Java_java_lang_ClassLoader_defineClass { ENTER(t, Thread::ActiveState); - uint8_t* buffer = static_cast(t->vm->system->allocate(length)); + uint8_t* buffer = static_cast(t->m->system->allocate(length)); memcpy(buffer, &byteArrayBody(t, *b, offset), length); object c = parseClass(t, buffer, length); - t->vm->system->free(buffer); - return pushReference(t, c); + t->m->system->free(buffer); + return makeLocalReference(t, c); } extern "C" JNIEXPORT jclass JNICALL @@ -147,7 +147,7 @@ Java_java_lang_SystemClassLoader_resourceExists if (LIKELY(name)) { char n[stringLength(t, *name) + 1]; stringChars(t, *name, n); - return t->vm->finder->exists(n); + return t->m->finder->exists(n); } else { t->exception = makeNullPointerException(t); return 0; @@ -159,7 +159,7 @@ Java_java_io_ObjectInputStream_makeInstance(Thread* t, jclass, jclass c) { ENTER(t, Thread::ActiveState); - return pushReference(t, make(t, *c)); + return makeLocalReference(t, make(t, *c)); } extern "C" JNIEXPORT jclass JNICALL @@ -169,23 +169,23 @@ Java_java_lang_Class_primitiveClass(Thread* t, jclass, jchar name) switch (name) { case 'B': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JbyteType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JbyteType)); case 'C': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JcharType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JcharType)); case 'D': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JdoubleType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JdoubleType)); case 'F': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JfloatType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JfloatType)); case 'I': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JintType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JintType)); case 'J': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JlongType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JlongType)); case 'S': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JshortType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JshortType)); case 'V': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JvoidType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JvoidType)); case 'Z': - return pushReference(t, arrayBody(t, t->vm->types, Machine::JbooleanType)); + return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JbooleanType)); default: t->exception = makeIllegalArgumentException(t); return 0; @@ -247,7 +247,7 @@ Java_java_lang_reflect_Field_getObject { ENTER(t, Thread::ActiveState); - return pushReference(t, cast(*instance, offset)); + return makeLocalReference(t, cast(*instance, offset)); } extern "C" JNIEXPORT void JNICALL @@ -300,7 +300,7 @@ Java_java_lang_reflect_Constructor_make(Thread* t, jclass, jclass c) { ENTER(t, Thread::ActiveState); - return pushReference(t, make(t, *c)); + return makeLocalReference(t, make(t, *c)); } extern "C" JNIEXPORT jobject JNICALL @@ -308,8 +308,11 @@ Java_java_lang_reflect_Method_getCaller(Thread* t, jclass) { ENTER(t, Thread::ActiveState); - return pushReference - (t, frameMethod(t, frameNext(t, frameNext(t, t->frame)))); + FrameIterator it; t->m->processor->start(t, &it); + t->m->processor->next(t, &it); + t->m->processor->next(t, &it); + + return makeLocalReference(t, it.method); } extern "C" JNIEXPORT jobject JNICALL @@ -318,11 +321,12 @@ Java_java_lang_reflect_Method_invoke { ENTER(t, Thread::ActiveState); - object v = run2(t, *method, (instance ? *instance : 0), *arguments); + object v = t->m->processor->invoke + (t, *method, (instance ? *instance : 0), *arguments); if (t->exception) { t->exception = makeInvocationTargetException(t, t->exception); } - return pushReference(t, v); + return makeLocalReference(t, v); } extern "C" JNIEXPORT jint JNICALL @@ -351,7 +355,7 @@ Java_java_lang_reflect_Array_makeObjectArray { ENTER(t, Thread::ActiveState); - return pushReference(t, makeObjectArray(t, *elementType, length, true)); + return makeLocalReference(t, makeObjectArray(t, *elementType, length, true)); } extern "C" JNIEXPORT jint JNICALL @@ -387,7 +391,7 @@ Java_java_lang_String_intern(Thread* t, jobject this_) { ENTER(t, Thread::ActiveState); - return pushReference(t, intern(t, *this_)); + return makeLocalReference(t, intern(t, *this_)); } extern "C" JNIEXPORT jstring JNICALL @@ -401,7 +405,7 @@ Java_java_lang_System_getVMProperty(Thread* t, jclass, jint code) switch (code) { case JavaClassPath: - return pushReference(t, makeString(t, "%s", t->vm->finder->path())); + return makeLocalReference(t, makeString(t, "%s", t->m->finder->path())); default: t->exception = makeRuntimeException(t, 0); @@ -469,12 +473,12 @@ extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_load(Thread* t, jclass, jstring name, jboolean mapName) { ENTER(t, Thread::ActiveState); - ACQUIRE(t, t->vm->classLock); + ACQUIRE(t, t->m->classLock); char n[stringLength(t, *name) + 1]; stringChars(t, *name, n); - for (System::Library* lib = t->vm->libraries; lib; lib = lib->next()) + for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { if (lib->name() and strcmp(lib->name(), n) == 0 @@ -486,10 +490,10 @@ Java_java_lang_Runtime_load(Thread* t, jclass, jstring name, jboolean mapName) } System::Library* lib; - if (LIKELY(t->vm->system->success - (t->vm->system->load(&lib, n, mapName, t->vm->libraries)))) + if (LIKELY(t->m->system->success + (t->m->system->load(&lib, n, mapName, t->m->libraries)))) { - t->vm->libraries = lib; + t->m->libraries = lib; } else { object message = makeString(t, "library not found: %s", n); t->exception = makeUnsatisfiedLinkError(t, message); @@ -510,7 +514,7 @@ Java_java_lang_Runtime_exit(Thread* t, jobject, jint code) { ENTER(t, Thread::ActiveState); - t->vm->system->exit(code); + t->m->system->exit(code); } extern "C" JNIEXPORT jlong JNICALL @@ -525,24 +529,25 @@ Java_java_lang_Throwable_trace(Thread* t, jclass, jint skipCount) { ENTER(t, Thread::ActiveState); - int frame = t->frame; - while (skipCount-- and frame >= 0) { - frame = frameNext(t, frame); + FrameIterator it; t->m->processor->start(t, &it); + + while (skipCount-- and it.valid()) { + t->m->processor->next(t, &it); } // skip Throwable constructors - while (frame >= 0 + while (it.valid() and isAssignableFrom - (t, arrayBody(t, t->vm->types, Machine::ThrowableType), - methodClass(t, frameMethod(t, frame))) + (t, arrayBody(t, t->m->types, Machine::ThrowableType), + methodClass(t, it.method)) and strcmp(reinterpret_cast(""), - &byteArrayBody(t, methodName(t, frameMethod(t, frame)), 0)) + &byteArrayBody(t, methodName(t, it.method), 0)) == 0) { - frame = frameNext(t, frame); + t->m->processor->next(t, &it); } - return pushReference(t, makeTrace(t, frame)); + return makeLocalReference(t, makeTrace(t, &it)); } extern "C" JNIEXPORT jarray JNICALL @@ -552,7 +557,7 @@ Java_java_lang_Throwable_resolveTrace(Thread* t, jclass, jobject trace) unsigned length = arrayLength(t, *trace); object array = makeObjectArray - (t, arrayBody(t, t->vm->types, Machine::StackTraceElementType), + (t, arrayBody(t, t->m->types, Machine::StackTraceElementType), length, true); PROTECT(t, array); @@ -578,7 +583,7 @@ Java_java_lang_Throwable_resolveTrace(Thread* t, jclass, jobject trace) set(t, objectArrayBody(t, array, i), ste); } - return pushReference(t, array); + return makeLocalReference(t, array); } extern "C" JNIEXPORT jobject JNICALL @@ -586,7 +591,7 @@ Java_java_lang_Thread_currentThread(Thread* t, jclass) { ENTER(t, Thread::ActiveState); - return pushReference(t, t->javaThread); + return makeLocalReference(t, t->javaThread); } extern "C" JNIEXPORT jlong JNICALL @@ -594,12 +599,12 @@ Java_java_lang_Thread_doStart(Thread* t, jobject this_) { ENTER(t, Thread::ActiveState); - Thread* p = new (t->vm->system->allocate(sizeof(Thread))) - Thread(t->vm, *this_, t); + Thread* p = new (t->m->system->allocate(sizeof(Thread))) + Thread(t->m, *this_, t); enter(p, Thread::ActiveState); - if (t->vm->system->success(t->vm->system->start(&(p->runnable)))) { + if (t->m->system->success(t->m->system->start(&(p->runnable)))) { return reinterpret_cast(p); } else { p->exit(); @@ -623,7 +628,7 @@ Java_java_net_URL_00024ResourceInputStream_open char p[stringLength(t, *path) + 1]; stringChars(t, *path, p); - return reinterpret_cast(t->vm->finder->find(p)); + return reinterpret_cast(t->m->finder->find(p)); } else { t->exception = makeNullPointerException(t); return 0; diff --git a/src/common.h b/src/common.h index f9e9460a85..77ea27ad12 100644 --- a/src/common.h +++ b/src/common.h @@ -176,6 +176,13 @@ hash(const uint16_t* s, unsigned length) return h; } +class Machine; +class Thread; + +struct Object { }; + +typedef Object* object; + } // namespace vm #endif//COMMON_H diff --git a/src/compile.cpp b/src/compile.cpp new file mode 100644 index 0000000000..704f2a0f0e --- /dev/null +++ b/src/compile.cpp @@ -0,0 +1,281 @@ +#include "common.h" +#include "system.h" +#include "constants.h" +#include "machine.h" + +using namespace vm; + +namespace { + +class Rope { + public: + class Node { + public: + static const unsigned Size = 32; + + Node(): + next(0) + { } + + Node* next; + uint8_t data[Size]; + }; + + Rope(System* s): + s(s), + front(0), + rear(0), + count(0), + position(Node::Size) + { } + + void append(uint8_t v) { + if (position == Node::Size) { + Node* n = new (s->allocate(sizeof(Node))) Node; + if (front == 0) { + front = rear = n; + } else { + rear->next = n; + rear = n; + } + position = 0; + ++ count; + } + + rear->data[position++] = v; + } + + unsigned length() { + return (count * Node::Size) + position; + } + + void copyTo(uint8_t* b) { + if (front) { + Node* n = front; + while (true) { + if (n == rear) { + memcpy(b, n->data, position); + break; + } else { + memcpy(b, n->data, Node::Size); + b += Node::Size; + n = n->next; + } + } + } + } + + System* s; + Node* front; + Node* rear; + unsigned count; + unsigned position; +}; + +class Assembler { + public: + Assembler(System* s): + rope(s) + { } + + Rope rope; +}; + +class Compiler: private Assembler { + public: + Compiler(System* s): + Assembler(s) + { } + + void compile(Thread* t, object method) { + push(ebp); + mov(esp, ebp); + + object code = methodCode(t, method); + + // reserve space for local variables + sub(codeMaxLocals(t, code), esp); + + for (unsigned i = 0; i < codeLength(t, code);) { + switch (codeBody(t, code, i++)) { + case iadd: + pop(eax); + pop(edx); + add(eax, edx); + push(edx); + break; + + case iconst_m1: + push(-1); + break; + + case iconst_0: + push(0); + break; + + case iconst_1: + push(1); + break; + + case iconst_2: + push(2); + break; + + case iconst_3: + push(3); + break; + + case iconst_4: + push(4); + break; + + case iconst_5: + push(5); + break; + + case iload_0: + case fload_0: + mov(ebp, 0, eax); + push(eax); + break; + + case iload_1: + case fload_1: + mov(ebp, -1, eax); + push(eax); + break; + + case iload_2: + case fload_2: + mov(ebp, -2, eax); + push(eax); + break; + + case iload_3: + case fload_3: + mov(ebp, -3, eax); + push(eax); + break; + + case istore_0: + case fstore_0: + pop(eax); + mov(eax, ebp, 0); + break; + + case istore_1: + case fstore_1: + pop(eax); + mov(eax, ebp, -1); + break; + + case istore_2: + case fstore_2: + pop(eax); + mov(eax, ebp, -2); + break; + + case istore_3: + case fstore_3: + pop(eax); + mov(eax, ebp, -3); + break; + + case return_: + mov(ebp, esp); + pop(ebp); + ret(); + break; + + default: + abort(t); + } + } + } +}; + +object +compile(Thread* t, object method) +{ + Compiler c(t->vm->system); + c.compile(t, method); + + object r = makeByteArray(t, c.rope.length(), false); + c.rope.copyTo(&byteArrayBody(t, r, 0)); + + return r; +} + +class MyInvoker: public Invoker { + public: + MyInvoker(System* s): + s(s) + { } + + virtual object + invokeArray(Thread* t, object method, object this_, object arguments) + { + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); + + assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + + uintptr_t a[methodParameterCount(t, method) * 2]; + ArgumentArray array(t, a, method, this_, spec, arguments); + + return invoke(t, method, &array); + } + + virtual object + invokeList(Thread* t, object method, object this_, bool indirectObjects, + va_list arguments) + { + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); + + assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + + uintptr_t a[methodParameterCount(t, method) * 2]; + ArgumentArray array(t, a, method, this_, spec, indirectObjects, arguments); + + return invoke(t, method, &array); + } + + virtual object + invokeList(Thread* t, const char* className, const char* methodName, + const char* methodSpec, object this_, va_list arguments) + { + assert(t, t->state == Thread::ActiveState + or t->state == Thread::ExclusiveState); + + uintptr_t a[methodParameterCount(t, method) * 2]; + ArgumentArray array(t, a, method, 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, &array); + } else { + return 0; + } + } + + virtual void dispose() { + s->free(this); + } + + System* s; +}; + +} // namespace + +namespace vm { + +Invoker* +makeInvoker(System* system) +{ + return new (system->allocate(sizeof(MyInvoker))) MyInvoker(system); +} + +} // namespace vm diff --git a/src/run.cpp b/src/interpret.cpp similarity index 86% rename from src/run.cpp rename to src/interpret.cpp index 558598315a..6ad06e7316 100644 --- a/src/run.cpp +++ b/src/interpret.cpp @@ -1,16 +1,327 @@ #include "common.h" #include "system.h" -#include "heap.h" -#include "finder.h" #include "constants.h" -#include "run.h" -#include "jnienv.h" #include "machine.h" +#include "processor.h" using namespace vm; namespace { +class Thread: public vm::Thread { + public: + static const unsigned StackSizeInBytes = 64 * 1024; + static const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord; + + Thread(Machine* m, object javaThread, vm::Thread* parent): + vm::Thread(m, javaThread, parent), + ip(0), + sp(0), + frame(-1), + code(0) + { } + + unsigned ip; + unsigned sp; + int frame; + object code; + 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) +{ + if (DebugStack) { + fprintf(stderr, "push object %p at %d\n", o, t->sp); + } + + assert(t, t->sp + 1 < Thread::StackSizeInWords / 2); + t->stack[(t->sp * 2) ] = ObjectTag; + t->stack[(t->sp * 2) + 1] = reinterpret_cast(o); + ++ t->sp; +} + +inline void +pushInt(Thread* t, uint32_t v) +{ + if (DebugStack) { + fprintf(stderr, "push int %d at %d\n", v, t->sp); + } + + assert(t, t->sp + 1 < Thread::StackSizeInWords / 2); + t->stack[(t->sp * 2) ] = IntTag; + t->stack[(t->sp * 2) + 1] = v; + ++ t->sp; +} + +inline void +pushFloat(Thread* t, float v) +{ + uint32_t a; memcpy(&a, &v, sizeof(uint32_t)); + pushInt(t, a); +} + +inline void +pushLong(Thread* t, uint64_t v) +{ + if (DebugStack) { + fprintf(stderr, "push long %"LLD" at %d\n", v, t->sp); + } + + pushInt(t, v >> 32); + pushInt(t, v & 0xFFFFFFFF); +} + +inline void +pushDouble(Thread* t, double v) +{ + uint64_t a; memcpy(&a, &v, sizeof(uint64_t)); + pushLong(t, a); +} + +inline object +popObject(Thread* t) +{ + if (DebugStack) { + fprintf(stderr, "pop object %p at %d\n", + reinterpret_cast(t->stack[((t->sp - 1) * 2) + 1]), + t->sp - 1); + } + + assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag); + return reinterpret_cast(t->stack[((-- t->sp) * 2) + 1]); +} + +inline uint32_t +popInt(Thread* t) +{ + if (DebugStack) { + fprintf(stderr, "pop int %"ULD" at %d\n", + t->stack[((t->sp - 1) * 2) + 1], + t->sp - 1); + } + + assert(t, t->stack[(t->sp - 1) * 2] == IntTag); + return t->stack[((-- t->sp) * 2) + 1]; +} + +inline float +popFloat(Thread* t) +{ + uint32_t a = popInt(t); + float f; memcpy(&f, &a, sizeof(float)); + return f; +} + +inline uint64_t +popLong(Thread* t) +{ + if (DebugStack) { + fprintf(stderr, "pop long %"LLD" at %d\n", + (static_cast(t->stack[((t->sp - 2) * 2) + 1]) << 32) + | static_cast(t->stack[((t->sp - 1) * 2) + 1]), + t->sp - 2); + } + + uint64_t a = popInt(t); + uint64_t b = popInt(t); + return (b << 32) | a; +} + +inline float +popDouble(Thread* t) +{ + uint64_t a = popLong(t); + double d; memcpy(&d, &a, sizeof(double)); + return d; +} + +inline object +peekObject(Thread* t, unsigned index) +{ + if (DebugStack) { + fprintf(stderr, "peek object %p at %d\n", + reinterpret_cast(t->stack[(index * 2) + 1]), + index); + } + + assert(t, index < Thread::StackSizeInWords / 2); + assert(t, t->stack[index * 2] == ObjectTag); + return *reinterpret_cast(t->stack + (index * 2) + 1); +} + +inline uint32_t +peekInt(Thread* t, unsigned index) +{ + if (DebugStack) { + fprintf(stderr, "peek int %"ULD" at %d\n", + t->stack[(index * 2) + 1], + index); + } + + assert(t, index < Thread::StackSizeInWords / 2); + assert(t, t->stack[index * 2] == IntTag); + return t->stack[(index * 2) + 1]; +} + +inline uint64_t +peekLong(Thread* t, unsigned index) +{ + if (DebugStack) { + fprintf(stderr, "peek long %"LLD" at %d\n", + (static_cast(t->stack[(index * 2) + 1]) << 32) + | static_cast(t->stack[((index + 1) * 2) + 1]), + index); + } + + return (static_cast(peekInt(t, index)) << 32) + | static_cast(peekInt(t, index + 1)); +} + +inline void +pokeObject(Thread* t, unsigned index, object value) +{ + if (DebugStack) { + fprintf(stderr, "poke object %p at %d\n", value, index); + } + + t->stack[index * 2] = ObjectTag; + t->stack[(index * 2) + 1] = reinterpret_cast(value); +} + +inline void +pokeInt(Thread* t, unsigned index, uint32_t value) +{ + if (DebugStack) { + fprintf(stderr, "poke int %d at %d\n", value, index); + } + + t->stack[index * 2] = IntTag; + t->stack[(index * 2) + 1] = value; +} + +inline void +pokeLong(Thread* t, unsigned index, uint64_t value) +{ + if (DebugStack) { + fprintf(stderr, "poke long %"LLD" at %d\n", value, index); + } + + pokeInt(t, index, value >> 32); + pokeInt(t, index + 1, value & 0xFFFFFFFF); +} + +inline object* +pushReference(Thread* t, object o) +{ + if (o) { + expect(t, t->sp + 1 < Thread::StackSizeInWords / 2); + pushObject(t, o); + return reinterpret_cast(t->stack + ((t->sp - 1) * 2) + 1); + } else { + return 0; + } +} + +inline int +frameNext(Thread* t, int frame) +{ + return peekInt(t, frame + FrameNextOffset); +} + +inline object +frameMethod(Thread* t, int frame) +{ + return peekObject(t, frame + FrameMethodOffset); +} + +inline unsigned +frameIp(Thread* t, int frame) +{ + return peekInt(t, frame + FrameIpOffset); +} + +inline unsigned +frameBase(Thread* t, int frame) +{ + return peekInt(t, frame + FrameBaseOffset); +} + +inline object +localObject(Thread* t, unsigned index) +{ + return peekObject(t, frameBase(t, t->frame) + index); +} + +inline uint32_t +localInt(Thread* t, unsigned index) +{ + return peekInt(t, frameBase(t, t->frame) + index); +} + +inline uint64_t +localLong(Thread* t, unsigned index) +{ + return peekLong(t, frameBase(t, t->frame) + index); +} + +inline void +setLocalObject(Thread* t, unsigned index, object value) +{ + pokeObject(t, frameBase(t, t->frame) + index, value); +} + +inline void +setLocalInt(Thread* t, unsigned index, uint32_t value) +{ + pokeInt(t, frameBase(t, t->frame) + index, value); +} + +inline void +setLocalLong(Thread* t, unsigned index, uint64_t value) +{ + pokeLong(t, frameBase(t, t->frame) + index, value); +} + void pushFrame(Thread* t, object method) { @@ -69,7 +380,7 @@ popFrame(Thread* t) t->exception = makeExceptionInInitializerError(t, t->exception); } classVmFlags(t, methodClass(t, method)) &= ~(NeedInitFlag | InitFlag); - release(t, t->vm->classLock); + release(t, t->m->classLock); } t->sp = frameBase(t, t->frame); @@ -128,7 +439,7 @@ inline object resolveClass(Thread* t, object pool, unsigned index) { object o = arrayBody(t, pool, index); - if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { PROTECT(t, pool); @@ -141,10 +452,11 @@ resolveClass(Thread* t, object pool, unsigned index) } inline object -resolveClass(Thread* t, object container, object& (*class_)(Thread*, object)) +resolveClass(Thread* t, object container, + object& (*class_)(vm::Thread*, object)) { object o = class_(t, container); - if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { PROTECT(t, container); @@ -158,11 +470,11 @@ resolveClass(Thread* t, object container, object& (*class_)(Thread*, object)) inline object resolve(Thread* t, object pool, unsigned index, - object (*find)(Thread*, object, object, object), - object (*makeError)(Thread*, object)) + object (*find)(vm::Thread*, object, object, object), + object (*makeError)(vm::Thread*, object)) { object o = arrayBody(t, pool, index); - if (objectClass(t, o) == arrayBody(t, t->vm->types, Machine::ReferenceType)) + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType)) { PROTECT(t, pool); @@ -264,10 +576,10 @@ inline object resolveNativeMethodData(Thread* t, object method) { if (objectClass(t, methodCode(t, method)) - == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) { object data = 0; - for (System::Library* lib = t->vm->libraries; lib; lib = lib->next()) { + for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { void* p = lib->resolve(reinterpret_cast (&byteArrayBody(t, methodCode(t, method), 0))); if (p) { @@ -383,7 +695,7 @@ invokeNative(Thread* t, object method) { ENTER(t, Thread::IdleState); - result = t->vm->system->call + result = t->m->system->call (function, args, &nativeMethodDataParameterTypes(t, data, 0), @@ -451,7 +763,7 @@ bool classInit2(Thread* t, object class_, unsigned ipOffset) { PROTECT(t, class_); - acquire(t, t->vm->classLock); + acquire(t, t->m->classLock); if (classVmFlags(t, class_) & NeedInitFlag and (classVmFlags(t, class_) & InitFlag) == 0) { @@ -460,7 +772,7 @@ classInit2(Thread* t, object class_, unsigned ipOffset) t->ip -= ipOffset; return true; } else { - release(t, t->vm->classLock); + release(t, t->m->classLock); return false; } } @@ -533,7 +845,7 @@ populateMultiArray(Thread* t, object array, int32_t* counts, } object -run(Thread* t) +interpret(Thread* t) { const int base = t->frame; @@ -717,7 +1029,7 @@ run(Thread* t) if (LIKELY(array)) { if (objectClass(t, array) - == arrayBody(t, t->vm->types, Machine::BooleanArrayType)) + == arrayBody(t, t->m->types, Machine::BooleanArrayType)) { if (LIKELY(index >= 0 and static_cast(index) @@ -756,7 +1068,7 @@ run(Thread* t) if (LIKELY(array)) { if (objectClass(t, array) - == arrayBody(t, t->vm->types, Machine::BooleanArrayType)) + == arrayBody(t, t->m->types, Machine::BooleanArrayType)) { if (LIKELY(index >= 0 and static_cast(index) @@ -1890,14 +2202,14 @@ run(Thread* t) object v = arrayBody(t, codePool(t, code), index - 1); - if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::IntType)) { + if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::IntType)) { pushInt(t, intValue(t, v)); } else if (objectClass(t, v) - == arrayBody(t, t->vm->types, Machine::FloatType)) + == arrayBody(t, t->m->types, Machine::FloatType)) { pushInt(t, floatValue(t, v)); } else if (objectClass(t, v) - == arrayBody(t, t->vm->types, Machine::StringType)) + == arrayBody(t, t->m->types, Machine::StringType)) { pushObject(t, v); } else { @@ -1914,10 +2226,10 @@ run(Thread* t) object v = arrayBody(t, codePool(t, code), ((index1 << 8) | index2) - 1); - if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::LongType)) { + if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType)) { pushLong(t, longValue(t, v)); } else if (objectClass(t, v) - == arrayBody(t, t->vm->types, Machine::DoubleType)) + == arrayBody(t, t->m->types, Machine::DoubleType)) { pushLong(t, doubleValue(t, v)); } else { @@ -2506,24 +2818,6 @@ run(Thread* t) return 0; } -void -run(Thread* t, const char* className, int argc, const char** argv) -{ - enter(t, Thread::ActiveState); - - object args = makeObjectArray - (t, arrayBody(t, t->vm->types, Machine::StringType), argc, true); - - PROTECT(t, args); - - for (int i = 0; i < argc; ++i) { - object arg = makeString(t, "%s", argv[i]); - set(t, objectArrayBody(t, args, i), arg); - } - - run(t, className, "main", "([Ljava/lang/String;)V", 0, args); -} - void pushArguments(Thread* t, object this_, const char* spec, bool indirectObjects, va_list a) @@ -2704,7 +2998,7 @@ invoke(Thread* t, object method) checkStack(t, method); if (LIKELY(t->exception == 0)) { pushFrame(t, method); - result = ::run(t); + result = interpret(t); if (LIKELY(t->exception == 0)) { popFrame(t); } @@ -2745,48 +3039,55 @@ invoke(Thread* t, object method) } } -} // namespace - -namespace vm { - -object -runv(Thread* t, object method, object this_, bool indirectObjects, va_list a) +void +MyProcessor::visitObjects(vm::Thread* vmt, Heap::Visitor* v) { - assert(t, t->state == Thread::ActiveState - or t->state == Thread::ExclusiveState); + Thread* t = static_cast(vmt); - assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); + v->visit(&(t->code)); - if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 - > Thread::StackSizeInWords / 2)) - { - t->exception = makeStackOverflowError(t); - return 0; + for (unsigned i = 0; i < t->sp; ++i) { + if (t->stack[i * 2] == ObjectTag) { + v->visit(t->stack + (i * 2) + 1); + } } +} - const char* spec = reinterpret_cast - (&byteArrayBody(t, methodSpec(t, method), 0)); - pushArguments(t, this_, spec, indirectObjects, a); +void +MyProcessor::start(vm::Thread* vmt, FrameIterator* it) +{ + Thread* t = static_cast(vmt); - return invoke(t, method); + 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); + } +} + +void +MyProcessor::next(vm::Thread* vmt, FrameIterator* it) +{ + 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); + } + } } object -run(Thread* t, object method, object this_, ...) +MyProcessor::invokeArray(vm::Thread* vmt, object method, object this_, + object arguments) { - va_list a; - va_start(a, this_); + Thread* t = static_cast(vmt); - object r = runv(t, method, this_, false, a); - - va_end(a); - - return r; -} - -object -run2(Thread* t, object method, object this_, object arguments) -{ assert(t, t->state == Thread::ActiveState or t->state == Thread::ExclusiveState); @@ -2803,13 +3104,41 @@ run2(Thread* t, object method, object this_, object arguments) (&byteArrayBody(t, methodSpec(t, method), 0)); pushArguments(t, this_, spec, arguments); - return invoke(t, method); + return ::invoke(t, method); } object -run(Thread* t, const char* className, const char* methodName, - const char* methodSpec, object this_, ...) +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); @@ -2820,55 +3149,26 @@ run(Thread* t, const char* className, const char* methodName, return 0; } - va_list a; - va_start(a, this_); + pushArguments(t, this_, methodSpec, false, arguments); - pushArguments(t, this_, methodSpec, false, a); - - va_end(a); - - object class_ = resolveClass(t, makeByteArray(t, "%s", className)); + object method = resolveMethod(t, className, methodName, methodSpec); if (LIKELY(t->exception == 0)) { - PROTECT(t, class_); + assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); - object name = makeByteArray(t, methodName); - PROTECT(t, name); - - object spec = makeByteArray(t, methodSpec); - object reference = makeReference(t, class_, name, spec); - - object method = findMethodInClass(t, class_, referenceName(t, reference), - referenceSpec(t, reference)); - if (LIKELY(t->exception == 0)) { - assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); - - return invoke(t, method); - } + return ::invoke(t, method); + } else { + return 0; } - - return 0; } -int -run(System* system, Heap* heap, Finder* finder, - const char* className, int argc, const char** argv) +} // namespace + +namespace vm { + +Processor* +makeProcessor(System* system) { - Machine m(system, heap, finder); - Thread* t = new (system->allocate(sizeof(Thread))) Thread(&m, 0, 0); - - enter(t, Thread::ActiveState); - - ::run(t, className, argc, argv); - - int exitCode = 0; - if (t->exception) { - exitCode = -1; - printTrace(t, t->exception); - } - - exit(t); - - return exitCode; + return new (system->allocate(sizeof(MyProcessor))) MyProcessor(system); } } // namespace vm diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 2517e28d7a..fb5276a08a 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -1,6 +1,6 @@ #include "jnienv.h" #include "machine.h" -#include "run.h" +#include "processor.h" #include "constants.h" using namespace vm; @@ -15,7 +15,7 @@ AttachCurrentThread(Machine* m, Thread** t, void*) { *t = static_cast(m->localThread->get()); if (*t == 0) { - *t = new (m->system->allocate(sizeof(Thread))) Thread(m, 0, m->rootThread); + *t = m->processor->makeThread(m, 0, m->rootThread); m->localThread->set(*t); } @@ -63,7 +63,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy) ENTER(t, Thread::ActiveState); char* chars = static_cast - (t->vm->system->allocate(stringLength(t, *s) + 1)); + (t->m->system->allocate(stringLength(t, *s) + 1)); stringChars(t, *s, chars); if (isCopy) *isCopy = true; @@ -73,7 +73,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy) void JNICALL ReleaseStringUTFChars(Thread* t, jstring, const char* chars) { - t->vm->system->free(chars); + t->m->system->free(chars); } jstring JNICALL @@ -81,7 +81,7 @@ NewStringUTF(Thread* t, const char* chars) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeString(t, "%s", chars)); + return makeLocalReference(t, makeString(t, "%s", chars)); } jclass JNICALL @@ -92,7 +92,7 @@ FindClass(Thread* t, const char* name) object n = makeByteArray(t, strlen(name) + 1, false); memcpy(&byteArrayBody(t, n, 0), name, byteArrayLength(t, n)); - return pushReference(t, resolveClass(t, n)); + return makeLocalReference(t, resolveClass(t, n)); } jint JNICALL @@ -122,9 +122,9 @@ ThrowNew(Thread* t, jclass c, const char* message) } void JNICALL -DeleteLocalRef(Thread*, jobject) +DeleteLocalRef(Thread* t, jobject r) { - // do nothing + disposeLocalReference(t, r); } jboolean JNICALL @@ -138,7 +138,7 @@ GetObjectClass(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); - return pushReference(t, objectClass(t, *o)); + return makeLocalReference(t, objectClass(t, *o)); } jboolean JNICALL @@ -172,18 +172,18 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec) if (classFlags(t, *c) & ACC_INTERFACE) { PROTECT(t, method); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); - for (unsigned i = 0; i < vectorSize(t, t->vm->jniInterfaceTable); ++i) { - if (method == vectorBody(t, t->vm->jniInterfaceTable, i)) { + for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) { + if (method == vectorBody(t, t->m->jniInterfaceTable, i)) { return i; } } - t->vm->jniInterfaceTable - = vectorAppend(t, t->vm->jniInterfaceTable, method); + t->m->jniInterfaceTable + = vectorAppend(t, t->m->jniInterfaceTable, method); - return (vectorSize(t, t->vm->jniInterfaceTable) - 1) | InterfaceMethodID; + return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID; } else { return methodOffset(t, method) + 1; } @@ -204,7 +204,7 @@ inline object getMethod(Thread* t, object o, jmethodID m) { if (m & InterfaceMethodID) { - return vectorBody(t, t->vm->jniInterfaceTable, m & (~InterfaceMethodID)); + return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); } else { return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); } @@ -215,7 +215,8 @@ CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - return pushReference(t, runv(t, getMethod(t, *o, m), *o, true, a)); + return makeLocalReference(t, t->m->processor->invokeList + (t, getMethod(t, *o, m), *o, true, a)); } jobject JNICALL @@ -236,7 +237,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : booleanValue(t, r)); } @@ -258,7 +259,7 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : byteValue(t, r)); } @@ -280,7 +281,7 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : charValue(t, r)); } @@ -302,7 +303,7 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : shortValue(t, r)); } @@ -324,7 +325,7 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -346,7 +347,7 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -368,7 +369,7 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); jint i = (t->exception ? 0 : floatValue(t, r)); jfloat f; memcpy(&f, &i, 4); return f; @@ -392,7 +393,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getMethod(t, *o, m), *o, true, a); + object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); jlong i = (t->exception ? 0 : doubleValue(t, r)); jdouble f; memcpy(&f, &i, 4); return f; @@ -416,7 +417,7 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - runv(t, getMethod(t, *o, m), *o, true, a); + t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a); } void JNICALL @@ -441,7 +442,8 @@ CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - return pushReference(t, runv(t, getStaticMethod(t, *c, m), 0, true, a)); + return makeLocalReference(t, t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a)); } jobject JNICALL @@ -462,7 +464,8 @@ CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : booleanValue(t, r)); } @@ -484,7 +487,8 @@ CallStaticByteMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : byteValue(t, r)); } @@ -506,7 +510,8 @@ CallStaticCharMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : charValue(t, r)); } @@ -528,7 +533,8 @@ CallStaticShortMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : shortValue(t, r)); } @@ -550,7 +556,8 @@ CallStaticIntMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -572,7 +579,8 @@ CallStaticLongMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -594,7 +602,8 @@ CallStaticFloatMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); jint i = (t->exception ? 0 : floatValue(t, r)); jfloat f; memcpy(&f, &i, 4); return f; @@ -618,7 +627,8 @@ CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = runv(t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList + (t, getStaticMethod(t, *c, m), 0, true, a); jlong i = (t->exception ? 0 : doubleValue(t, r)); jdouble f; memcpy(&f, &i, 4); return f; @@ -642,7 +652,7 @@ CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - runv(t, getStaticMethod(t, *c, m), 0, true, a); + t->m->processor->invokeList(t, getStaticMethod(t, *c, m), 0, true, a); } void JNICALL @@ -693,7 +703,7 @@ GetObjectField(Thread* t, jobject o, jfieldID field) { ENTER(t, Thread::ActiveState); - return pushReference(t, cast(*o, field)); + return makeLocalReference(t, cast(*o, field)); } jboolean JNICALL @@ -837,7 +847,7 @@ GetStaticObjectField(Thread* t, jclass c, jfieldID field) { ENTER(t, Thread::ActiveState); - return pushReference(t, arrayBody(t, classStaticTable(t, *c), field)); + return makeLocalReference(t, arrayBody(t, classStaticTable(t, *c), field)); } jboolean JNICALL @@ -1003,12 +1013,12 @@ NewGlobalRef(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); - t->vm->jniReferences = new (t->vm->system->allocate(sizeof(Reference))) - Reference(*o, t->vm->jniReferences); + t->m->jniReferences = new (t->m->system->allocate(sizeof(Reference))) + Reference(*o, t->m->jniReferences); - return &(t->vm->jniReferences->target); + return &(t->m->jniReferences->target); } void JNICALL @@ -1016,9 +1026,9 @@ DeleteGlobalRef(Thread* t, jobject o) { ENTER(t, Thread::ActiveState); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); - for (Reference** r = &(t->vm->jniReferences); *r;) { + for (Reference** r = &(t->m->jniReferences); *r;) { if (&((*r)->target) == o) { *r = (*r)->next; break; @@ -1033,7 +1043,7 @@ ExceptionOccurred(Thread* t) { ENTER(t, Thread::ActiveState); - return pushReference(t, t->exception); + return makeLocalReference(t, t->exception); } void JNICALL @@ -1057,7 +1067,7 @@ NewBooleanArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeBooleanArray(t, length, true)); + return makeLocalReference(t, makeBooleanArray(t, length, true)); } jbyteArray JNICALL @@ -1065,7 +1075,7 @@ NewByteArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeByteArray(t, length, true)); + return makeLocalReference(t, makeByteArray(t, length, true)); } jcharArray JNICALL @@ -1073,7 +1083,7 @@ NewCharArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeCharArray(t, length, true)); + return makeLocalReference(t, makeCharArray(t, length, true)); } jshortArray JNICALL @@ -1081,7 +1091,7 @@ NewShortArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeShortArray(t, length, true)); + return makeLocalReference(t, makeShortArray(t, length, true)); } jintArray JNICALL @@ -1089,7 +1099,7 @@ NewIntArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeIntArray(t, length, true)); + return makeLocalReference(t, makeIntArray(t, length, true)); } jlongArray JNICALL @@ -1097,7 +1107,7 @@ NewLongArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeLongArray(t, length, true)); + return makeLocalReference(t, makeLongArray(t, length, true)); } jfloatArray JNICALL @@ -1105,7 +1115,7 @@ NewFloatArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeFloatArray(t, length, true)); + return makeLocalReference(t, makeFloatArray(t, length, true)); } jdoubleArray JNICALL @@ -1113,7 +1123,7 @@ NewDoubleArray(Thread* t, jsize length) { ENTER(t, Thread::ActiveState); - return pushReference(t, makeDoubleArray(t, length, true)); + return makeLocalReference(t, makeDoubleArray(t, length, true)); } jboolean* JNICALL @@ -1122,7 +1132,7 @@ GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean); - jboolean* p = static_cast(t->vm->system->allocate(size)); + jboolean* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &booleanArrayBody(t, *array, 0), size); } @@ -1140,7 +1150,7 @@ GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = byteArrayLength(t, *array) * sizeof(jbyte); - jbyte* p = static_cast(t->vm->system->allocate(size)); + jbyte* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &byteArrayBody(t, *array, 0), size); } @@ -1158,7 +1168,7 @@ GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = charArrayLength(t, *array) * sizeof(jchar); - jchar* p = static_cast(t->vm->system->allocate(size)); + jchar* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &charArrayBody(t, *array, 0), size); } @@ -1176,7 +1186,7 @@ GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = shortArrayLength(t, *array) * sizeof(jshort); - jshort* p = static_cast(t->vm->system->allocate(size)); + jshort* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &shortArrayBody(t, *array, 0), size); } @@ -1194,7 +1204,7 @@ GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = intArrayLength(t, *array) * sizeof(jint); - jint* p = static_cast(t->vm->system->allocate(size)); + jint* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &intArrayBody(t, *array, 0), size); } @@ -1212,7 +1222,7 @@ GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = longArrayLength(t, *array) * sizeof(jlong); - jlong* p = static_cast(t->vm->system->allocate(size)); + jlong* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &longArrayBody(t, *array, 0), size); } @@ -1230,7 +1240,7 @@ GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = floatArrayLength(t, *array) * sizeof(jfloat); - jfloat* p = static_cast(t->vm->system->allocate(size)); + jfloat* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &floatArrayBody(t, *array, 0), size); } @@ -1248,7 +1258,7 @@ GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy) ENTER(t, Thread::ActiveState); unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble); - jdouble* p = static_cast(t->vm->system->allocate(size)); + jdouble* p = static_cast(t->m->system->allocate(size)); if (size) { memcpy(p, &doubleArrayBody(t, *array, 0), size); } @@ -1274,7 +1284,7 @@ ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p, } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1291,7 +1301,7 @@ ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1308,7 +1318,7 @@ ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1325,7 +1335,7 @@ ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1342,7 +1352,7 @@ ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1359,7 +1369,7 @@ ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1376,7 +1386,7 @@ ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode) } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1394,7 +1404,7 @@ ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p, } if (mode == 0 or mode == JNI_ABORT) { - t->vm->system->free(p); + t->m->system->free(p); } } @@ -1567,7 +1577,7 @@ ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint) jint JNICALL GetJavaVM(Thread* t, Machine** m) { - *m = t->vm; + *m = t->m; return 0; } diff --git a/src/machine.cpp b/src/machine.cpp index 91bba65fe2..0441ce6837 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2,7 +2,7 @@ #include "machine.h" #include "stream.h" #include "constants.h" -#include "run.h" +#include "processor.h" using namespace vm; @@ -48,18 +48,18 @@ dispose(Thread* t, Thread* o, bool remove) o->parent->child = 0; } } else if (o->child) { - t->vm->rootThread = o->child; + t->m->rootThread = o->child; if (o->peer) { o->peer->peer = o->child->peer; o->child->peer = o->peer; } } else if (o->peer) { - t->vm->rootThread = o->peer; + t->m->rootThread = o->peer; } else { abort(t); } - assert(t, not find(t->vm->rootThread, o)); + assert(t, not find(t->m->rootThread, o)); } o->dispose(); @@ -132,14 +132,9 @@ visitRoots(Thread* t, Heap::Visitor* v) { if (t->state != Thread::ZombieState) { v->visit(&(t->javaThread)); - v->visit(&(t->code)); v->visit(&(t->exception)); - for (unsigned i = 0; i < t->sp; ++i) { - if (t->stack[i * 2] == ObjectTag) { - v->visit(t->stack + (i * 2) + 1); - } - } + t->m->processor->visitObjects(t, v); for (Thread::Protector* p = t->protector; p; p = p->next) { v->visit(p->p); @@ -158,8 +153,8 @@ finalizerTargetUnreachable(Thread* t, object* p, Heap::Visitor* v) object finalizer = *p; *p = finalizerNext(t, finalizer); - finalizerNext(t, finalizer) = t->vm->finalizeQueue; - t->vm->finalizeQueue = finalizer; + finalizerNext(t, finalizer) = t->m->finalizeQueue; + t->m->finalizeQueue = finalizer; } void @@ -174,7 +169,7 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v) jreferenceTarget(t, *p) = 0; if (jreferenceQueue(t, *p) - and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) + and t->m->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) { // queue is reachable - add the reference @@ -205,7 +200,7 @@ referenceUnreachable(Thread* t, object* p, Heap::Visitor* v) } if (jreferenceQueue(t, *p) - and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) + and t->m->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) { // queue is reachable - add the reference referenceTargetUnreachable(t, p, v); @@ -225,7 +220,7 @@ referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v) v->visit(p); v->visit(&jreferenceTarget(t, *p)); - if (t->vm->heap->status(jreferenceQueue(t, *p)) == Heap::Unreachable) { + if (t->m->heap->status(jreferenceQueue(t, *p)) == Heap::Unreachable) { jreferenceQueue(t, *p) = 0; } else { v->visit(&jreferenceQueue(t, *p)); @@ -235,7 +230,7 @@ referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v) void postVisit(Thread* t, Heap::Visitor* v) { - Machine* m = t->vm; + Machine* m = t->m; for (object* p = &(m->finalizeQueue); *p; p = &(finalizerNext(t, *p))) { v->visit(p); @@ -359,9 +354,9 @@ void postCollect(Thread* t) { #ifdef VM_STRESS - t->vm->system->free(t->defaultHeap); + t->m->system->free(t->defaultHeap); t->defaultHeap = static_cast - (t->vm->system->allocate(Thread::HeapSizeInBytes)); + (t->m->system->allocate(Thread::HeapSizeInBytes)); #endif t->heap = t->defaultHeap; @@ -369,7 +364,7 @@ postCollect(Thread* t) t->heapIndex = 0; if (t->large) { - t->vm->system->free(t->large); + t->m->system->free(t->large); t->large = 0; } @@ -588,7 +583,7 @@ parsePool(Thread* t, Stream& s) for (unsigned i = 0; i < poolCount; ++i) { object o = arrayBody(t, pool, i); if (o and objectClass(t, o) - == arrayBody(t, t->vm->types, Machine::IntArrayType)) + == arrayBody(t, t->m->types, Machine::IntArrayType)) { switch (intArrayBody(t, o, 0)) { case CONSTANT_Class: { @@ -617,7 +612,7 @@ parsePool(Thread* t, Stream& s) for (unsigned i = 0; i < poolCount; ++i) { object o = arrayBody(t, pool, i); if (o and objectClass(t, o) - == arrayBody(t, t->vm->types, Machine::IntArrayType)) + == arrayBody(t, t->m->types, Machine::IntArrayType)) { switch (intArrayBody(t, o, 0)) { case CONSTANT_Fieldref: @@ -1183,15 +1178,15 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec, dimensions, 2 * BytesPerWord, BytesPerWord, - classObjectMask(t, arrayBody(t, t->vm->types, Machine::ArrayType)), + classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)), spec, - arrayBody(t, t->vm->types, Machine::JobjectType), + arrayBody(t, t->m->types, Machine::JobjectType), 0, - classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)), + classVirtualTable(t, arrayBody(t, t->m->types, Machine::JobjectType)), 0, 0, elementClass, - t->vm->loader); + t->m->loader); } object @@ -1232,7 +1227,7 @@ makeArrayClass(Thread* t, object spec) } object elementClass = hashMapFind - (t, t->vm->bootstrapClassMap, elementSpec, byteArrayHash, byteArrayEqual); + (t, t->m->bootstrapClassMap, elementSpec, byteArrayHash, byteArrayEqual); if (elementClass == 0) { elementClass = resolveClass(t, elementSpec); @@ -1245,7 +1240,7 @@ makeArrayClass(Thread* t, object spec) void removeMonitor(Thread* t, object o) { - object p = hashMapRemove(t, t->vm->monitorMap, o, objectHash, objectEqual); + object p = hashMapRemove(t, t->m->monitorMap, o, objectHash, objectEqual); assert(t, p); @@ -1261,18 +1256,39 @@ removeMonitor(Thread* t, object o) void removeString(Thread* t, object o) { - hashMapRemove(t, t->vm->stringMap, o, stringHash, objectEqual); + hashMapRemove(t, t->m->stringMap, o, stringHash, objectEqual); +} + +void +invoke(Thread* t, const char* className, int argc, const char** argv) +{ + enter(t, Thread::ActiveState); + + object args = makeObjectArray + (t, arrayBody(t, t->m->types, Machine::StringType), argc, true); + + PROTECT(t, args); + + for (int i = 0; i < argc; ++i) { + object arg = makeString(t, "%s", argv[i]); + set(t, objectArrayBody(t, args, i), arg); + } + + t->m->processor->invoke + (t, className, "main", "([Ljava/lang/String;)V", 0, args); } } // namespace namespace vm { -Machine::Machine(System* system, Heap* heap, Finder* finder): +Machine::Machine(System* system, Heap* heap, Finder* finder, + Processor* processor): vtable(&javaVMVTable), system(system), heap(heap), finder(finder), + processor(processor), rootThread(0), exclusive(0), jniReferences(0), @@ -1333,7 +1349,7 @@ Machine::dispose() Thread::Thread(Machine* m, object javaThread, Thread* parent): vtable(&(m->jniEnvVTable)), - vm(m), + m(m), parent(parent), peer((parent ? parent->child : 0)), child(0), @@ -1341,12 +1357,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent): criticalLevel(0), systemThread(0), javaThread(javaThread), - code(0), exception(0), large(0), - ip(0), - sp(0), - frame(-1), heapIndex(0), heapOffset(0), protector(0), @@ -1370,17 +1382,17 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent): Thread* t = this; - t->vm->loader = allocate(t, sizeof(void*) * 3); - memset(t->vm->loader, 0, sizeof(void*) * 2); + t->m->loader = allocate(t, sizeof(void*) * 3); + memset(t->m->loader, 0, sizeof(void*) * 2); #include "type-initializations.cpp" - object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType); - set(t, cast(t->vm->types, 0), arrayClass); + object arrayClass = arrayBody(t, t->m->types, Machine::ArrayType); + set(t, cast(t->m->types, 0), arrayClass); object loaderClass = arrayBody - (t, t->vm->types, Machine::SystemClassLoaderType); - set(t, cast(t->vm->loader, 0), loaderClass); + (t, t->m->types, Machine::SystemClassLoaderType); + set(t, cast(t->m->loader, 0), loaderClass); object objectClass = arrayBody(t, m->types, Machine::JobjectType); @@ -1453,7 +1465,7 @@ Thread::exit() { enter(this, Thread::ExclusiveState); - if (vm->liveCount == 1) { + if (m->liveCount == 1) { vm::exit(this); } else { enter(this, Thread::ZombieState); @@ -1465,7 +1477,7 @@ void Thread::dispose() { if (large) { - vm->system->free(large); + m->system->free(large); large = 0; } @@ -1475,11 +1487,11 @@ Thread::dispose() } #ifdef VM_STRESS - vm->system->free(heap); + m->system->free(heap); heap = 0; #endif // VM_STRESS - vm->system->free(this); + m->system->free(this); } void @@ -1487,9 +1499,9 @@ exit(Thread* t) { enter(t, Thread::ExitState); - joinAll(t, t->vm->rootThread); + joinAll(t, t->m->rootThread); - for (object* p = &(t->vm->finalizers); *p;) { + for (object* p = &(t->m->finalizers); *p;) { object f = *p; *p = finalizerNext(t, *p); @@ -1497,7 +1509,7 @@ exit(Thread* t) (t, finalizerTarget(t, f)); } - for (object* p = &(t->vm->tenuredFinalizers); *p;) { + for (object* p = &(t->m->tenuredFinalizers); *p;) { object f = *p; *p = finalizerNext(t, *p); @@ -1505,7 +1517,7 @@ exit(Thread* t) (t, finalizerTarget(t, f)); } - disposeAll(t, t->vm->rootThread); + disposeAll(t, t->m->rootThread); } void @@ -1520,22 +1532,22 @@ enter(Thread* t, Thread::State s) return; } - ACQUIRE_RAW(t, t->vm->stateLock); + ACQUIRE_RAW(t, t->m->stateLock); switch (s) { case Thread::ExclusiveState: { assert(t, t->state == Thread::ActiveState); - while (t->vm->exclusive) { + while (t->m->exclusive) { // another thread got here first. ENTER(t, Thread::IdleState); } t->state = Thread::ExclusiveState; - t->vm->exclusive = t; + t->m->exclusive = t; - while (t->vm->activeCount > 1) { - t->vm->stateLock->wait(t->systemThread, 0); + while (t->m->activeCount > 1) { + t->m->stateLock->wait(t->systemThread, 0); } } break; @@ -1543,8 +1555,8 @@ enter(Thread* t, Thread::State s) case Thread::ZombieState: { switch (t->state) { case Thread::ExclusiveState: { - assert(t, t->vm->exclusive == t); - t->vm->exclusive = 0; + assert(t, t->m->exclusive == t); + t->m->exclusive = 0; } break; case Thread::ActiveState: break; @@ -1552,38 +1564,38 @@ enter(Thread* t, Thread::State s) default: abort(t); } - assert(t, t->vm->activeCount > 0); - -- t->vm->activeCount; + assert(t, t->m->activeCount > 0); + -- t->m->activeCount; if (s == Thread::ZombieState) { - assert(t, t->vm->liveCount > 0); - -- t->vm->liveCount; + assert(t, t->m->liveCount > 0); + -- t->m->liveCount; } t->state = s; - t->vm->stateLock->notifyAll(t->systemThread); + t->m->stateLock->notifyAll(t->systemThread); } break; case Thread::ActiveState: { switch (t->state) { case Thread::ExclusiveState: { - assert(t, t->vm->exclusive == t); + assert(t, t->m->exclusive == t); t->state = s; - t->vm->exclusive = 0; + t->m->exclusive = 0; - t->vm->stateLock->notifyAll(t->systemThread); + t->m->stateLock->notifyAll(t->systemThread); } break; case Thread::NoState: case Thread::IdleState: { - while (t->vm->exclusive) { - t->vm->stateLock->wait(t->systemThread, 0); + while (t->m->exclusive) { + t->m->stateLock->wait(t->systemThread, 0); } - ++ t->vm->activeCount; + ++ t->m->activeCount; if (t->state == Thread::NoState) { - ++ t->vm->liveCount; + ++ t->m->liveCount; } t->state = s; } break; @@ -1595,8 +1607,8 @@ enter(Thread* t, Thread::State s) case Thread::ExitState: { switch (t->state) { case Thread::ExclusiveState: { - assert(t, t->vm->exclusive == t); - t->vm->exclusive = 0; + assert(t, t->m->exclusive == t); + t->m->exclusive = 0; } break; case Thread::ActiveState: break; @@ -1604,13 +1616,13 @@ enter(Thread* t, Thread::State s) default: abort(t); } - assert(t, t->vm->activeCount > 0); - -- t->vm->activeCount; + assert(t, t->m->activeCount > 0); + -- t->m->activeCount; t->state = s; - while (t->vm->liveCount > 1) { - t->vm->stateLock->wait(t->systemThread, 0); + while (t->m->liveCount > 1) { + t->m->stateLock->wait(t->systemThread, 0); } } break; @@ -1625,9 +1637,9 @@ allocate2(Thread* t, unsigned sizeInBytes) return allocateLarge(t, sizeInBytes); } - ACQUIRE_RAW(t, t->vm->stateLock); + ACQUIRE_RAW(t, t->m->stateLock); - while (t->vm->exclusive and t->vm->exclusive != t) { + while (t->m->exclusive and t->m->exclusive != t) { // another thread wants to enter the exclusive state, either for a // collection or some other reason. We give it a chance here. ENTER(t, Thread::IdleState); @@ -1637,11 +1649,11 @@ allocate2(Thread* t, unsigned sizeInBytes) >= Thread::HeapSizeInWords) { t->heap = 0; - if (t->large == 0 and t->vm->heapPoolIndex < Machine::HeapPoolSize) { + if (t->large == 0 and t->m->heapPoolIndex < Machine::HeapPoolSize) { t->heap = static_cast - (t->vm->system->tryAllocate(Thread::HeapSizeInBytes)); + (t->m->system->tryAllocate(Thread::HeapSizeInBytes)); if (t->heap) { - t->vm->heapPool[t->vm->heapPoolIndex++] = t->heap; + t->m->heapPool[t->m->heapPoolIndex++] = t->heap; t->heapOffset += t->heapIndex; t->heapIndex = 0; } @@ -1673,10 +1685,10 @@ make(Thread* t, object class_) if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) { PROTECT(t, instance); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); - jreferenceNextUnsafe(t, instance) = t->vm->weakReferences; - t->vm->weakReferences = instance; + jreferenceNextUnsafe(t, instance) = t->m->weakReferences; + t->m->weakReferences = instance; } return instance; @@ -1709,7 +1721,7 @@ stringChars(Thread* t, object string, char* chars) { object data = stringData(t, string); if (objectClass(t, data) - == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) { memcpy(chars, &byteArrayBody(t, data, stringOffset(t, string)), @@ -1865,7 +1877,7 @@ hashMapFindNode(Thread* t, object map, object key, bool (*equal)(Thread*, object, object)) { bool weak = objectClass(t, map) - == arrayBody(t, t->vm->types, Machine::WeakHashMapType); + == arrayBody(t, t->m->types, Machine::WeakHashMapType); object array = hashMapArray(t, map); if (array) { @@ -1905,7 +1917,7 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object), if (oldArray) { bool weak = objectClass(t, map) - == arrayBody(t, t->vm->types, Machine::WeakHashMapType); + == arrayBody(t, t->m->types, Machine::WeakHashMapType); for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) { object next; @@ -1934,7 +1946,7 @@ hashMapInsert(Thread* t, object map, object key, object value, uint32_t (*hash)(Thread*, object)) { bool weak = objectClass(t, map) - == arrayBody(t, t->vm->types, Machine::WeakHashMapType); + == arrayBody(t, t->m->types, Machine::WeakHashMapType); object array = hashMapArray(t, map); PROTECT(t, array); @@ -1958,8 +1970,8 @@ hashMapInsert(Thread* t, object map, object key, object value, object r = makeWeakReference(t, 0, 0, 0, 0); jreferenceTarget(t, r) = key; - jreferenceNext(t, r) = t->vm->weakReferences; - key = t->vm->weakReferences = r; + jreferenceNext(t, r) = t->m->weakReferences; + key = t->m->weakReferences = r; } object n = makeTriple(t, key, value, arrayBody(t, array, index)); @@ -1973,7 +1985,7 @@ hashMapRemove(Thread* t, object map, object key, bool (*equal)(Thread*, object, object)) { bool weak = objectClass(t, map) - == arrayBody(t, t->vm->types, Machine::WeakHashMapType); + == arrayBody(t, t->m->types, Machine::WeakHashMapType); object array = hashMapArray(t, map); object o = 0; @@ -2004,26 +2016,6 @@ hashMapRemove(Thread* t, object map, object key, return o; } -object -makeTrace(Thread* t, int frame) -{ - unsigned count = 0; - for (int f = frame; f >= 0; f = frameNext(t, f)) { - ++ count; - } - - object trace = makeArray(t, count, true); - PROTECT(t, trace); - - unsigned index = 0; - for (int f = frame; f >= 0; f = frameNext(t, f)) { - object e = makeTraceElement(t, frameMethod(t, f), frameIp(t, f)); - set(t, arrayBody(t, trace, index++), e); - } - - return trace; -} - object hashMapIterator(Thread* t, object map) { @@ -2186,9 +2178,9 @@ object findLoadedClass(Thread* t, object spec) { PROTECT(t, spec); - ACQUIRE(t, t->vm->classLock); + ACQUIRE(t, t->m->classLock); - return hashMapFind(t, systemClassLoaderMap(t, t->vm->loader), + return hashMapFind(t, systemClassLoaderMap(t, t->m->loader), spec, byteArrayHash, byteArrayEqual); } @@ -2234,7 +2226,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size) 0, // fields 0, // methods 0, // static table - t->vm->loader); + t->m->loader); PROTECT(t, class_); unsigned super = s.read2(); @@ -2264,14 +2256,14 @@ object resolveClass(Thread* t, object spec) { PROTECT(t, spec); - ACQUIRE(t, t->vm->classLock); + ACQUIRE(t, t->m->classLock); - object class_ = hashMapFind(t, systemClassLoaderMap(t, t->vm->loader), + object class_ = hashMapFind(t, systemClassLoaderMap(t, t->m->loader), spec, byteArrayHash, byteArrayEqual); if (class_ == 0) { if (byteArrayBody(t, spec, 0) == '[') { class_ = hashMapFind - (t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); + (t, t->m->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); if (class_ == 0) { class_ = makeArrayClass(t, spec); @@ -2281,7 +2273,7 @@ resolveClass(Thread* t, object spec) memcpy(file, &byteArrayBody(t, spec, 0), byteArrayLength(t, spec) - 1); memcpy(file + byteArrayLength(t, spec) - 1, ".class", 7); - System::Region* region = t->vm->finder->find(file); + System::Region* region = t->m->finder->find(file); if (region) { if (Verbose) { @@ -2298,7 +2290,7 @@ resolveClass(Thread* t, object spec) } object bootstrapClass = hashMapFind - (t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); + (t, t->m->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); if (bootstrapClass) { PROTECT(t, bootstrapClass); @@ -2313,7 +2305,7 @@ resolveClass(Thread* t, object spec) if (class_) { PROTECT(t, class_); - hashMapInsert(t, systemClassLoaderMap(t, t->vm->loader), + hashMapInsert(t, systemClassLoaderMap(t, t->m->loader), spec, class_, byteArrayHash); } else if (t->exception == 0) { object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); @@ -2324,6 +2316,27 @@ resolveClass(Thread* t, object spec) return class_; } +object +resolveMethod(Thread* t, const char* className, const char* methodName, + const char* methodSpec) +{ + object class_ = resolveClass(t, makeByteArray(t, "%s", className)); + if (LIKELY(t->exception == 0)) { + PROTECT(t, class_); + + object name = makeByteArray(t, methodName); + PROTECT(t, name); + + object spec = makeByteArray(t, methodSpec); + object reference = makeReference(t, class_, name, spec); + + return findMethodInClass(t, class_, referenceName(t, reference), + referenceSpec(t, reference)); + } + + return 0; +} + object resolveObjectArrayClass(Thread* t, object elementSpec) { @@ -2444,18 +2457,18 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)) { PROTECT(t, target); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); object f = makeFinalizer(t, 0, reinterpret_cast(finalize), 0); finalizerTarget(t, f) = target; - finalizerNext(t, f) = t->vm->finalizers; - t->vm->finalizers = f; + finalizerNext(t, f) = t->m->finalizers; + t->m->finalizers = f; } System::Monitor* objectMonitor(Thread* t, object o) { - object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, objectEqual); + object p = hashMapFind(t, t->m->monitorMap, o, objectHash, objectEqual); if (p) { if (DebugMonitors) { @@ -2471,8 +2484,8 @@ objectMonitor(Thread* t, object o) ENTER(t, Thread::ExclusiveState); System::Monitor* m; - System::Status s = t->vm->system->make(&m); - expect(t, t->vm->system->success(s)); + System::Status s = t->m->system->make(&m); + expect(t, t->m->system->success(s)); if (DebugMonitors) { fprintf(stderr, "made monitor %p for object %x\n", @@ -2481,7 +2494,7 @@ objectMonitor(Thread* t, object o) } p = makePointer(t, m); - hashMapInsert(t, t->vm->monitorMap, o, p, objectHash); + hashMapInsert(t, t->m->monitorMap, o, p, objectHash); addFinalizer(t, o, removeMonitor); @@ -2494,13 +2507,13 @@ intern(Thread* t, object s) { PROTECT(t, s); - ACQUIRE(t, t->vm->referenceLock); + ACQUIRE(t, t->m->referenceLock); - object n = hashMapFindNode(t, t->vm->stringMap, s, stringHash, stringEqual); + object n = hashMapFindNode(t, t->m->stringMap, s, stringHash, stringEqual); if (n) { return jreferenceTarget(t, tripleFirst(t, n)); } else { - hashMapInsert(t, t->vm->stringMap, s, 0, stringHash); + hashMapInsert(t, t->m->stringMap, s, 0, stringHash); addFinalizer(t, s, removeString); return s; } @@ -2509,7 +2522,7 @@ intern(Thread* t, object s) void collect(Thread* t, Heap::CollectionType type) { - Machine* m = t->vm; + Machine* m = t->m; class Client: public Heap::Client { public: @@ -2716,6 +2729,50 @@ printTrace(Thread* t, object exception) } } +int +run(System* system, Heap* heap, Finder* finder, Processor* processor, + const char* className, int argc, const char** argv) +{ + Machine m(system, heap, finder, processor); + Thread* t = processor->makeThread(&m, 0, 0); + + enter(t, Thread::ActiveState); + + ::invoke(t, className, argc, argv); + + int exitCode = 0; + if (t->exception) { + exitCode = -1; + printTrace(t, t->exception); + } + + exit(t); + + return exitCode; +} + +object +makeTrace(Thread* t, FrameIterator* it) +{ + unsigned count = 0; + FrameIterator copy(it); + while (copy.valid()) { + ++ 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); + set(t, arrayBody(t, trace, index++), e); + } + + return trace; +} + void noop() { } diff --git a/src/machine.h b/src/machine.h index 95c1528629..ccc391c7fa 100644 --- a/src/machine.h +++ b/src/machine.h @@ -5,6 +5,7 @@ #include "system.h" #include "heap.h" #include "finder.h" +#include "processor.h" #define JNICALL @@ -65,13 +66,6 @@ const unsigned PrimitiveFlag = 1 << 4; // method flags: const unsigned ClassInitFlag = 1 << 0; -class Machine; -class Thread; - -struct Object { }; - -typedef Object* object; - typedef Machine JavaVM; typedef Thread JNIEnv; @@ -1101,7 +1095,7 @@ class Machine { #include "type-enums.cpp" }; - Machine(System* system, Heap* heap, Finder* finder); + Machine(System* system, Heap* heap, Finder* finder, Processor* processor); ~Machine() { dispose(); @@ -1115,6 +1109,7 @@ class Machine { System* system; Heap* heap; Finder* finder; + Processor* processor; Thread* rootThread; Thread* exclusive; Reference* jniReferences; @@ -1144,13 +1139,6 @@ class Machine { unsigned heapPoolIndex; }; -object -run(Thread* t, object method, object this_, ...); - -object -run(Thread* t, const char* className, const char* methodName, - const char* methodSpec, object this_, ...); - void printTrace(Thread* t, object exception); @@ -1193,9 +1181,10 @@ class Thread { } virtual void run() { - t->vm->localThread->set(t); + t->m->localThread->set(t); - vm::run(t, "java/lang/Thread", "run", "()V", t->javaThread); + t->m->processor->invoke + (t, "java/lang/Thread", "run", "()V", t->javaThread); if (t->exception) { printTrace(t, t->exception); @@ -1216,10 +1205,7 @@ class Thread { }; static const unsigned HeapSizeInBytes = 64 * 1024; - static const unsigned StackSizeInBytes = 64 * 1024; - static const unsigned HeapSizeInWords = HeapSizeInBytes / BytesPerWord; - static const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord; Thread(Machine* m, object javaThread, Thread* parent); @@ -1227,7 +1213,7 @@ class Thread { void dispose(); JNIEnvVTable* vtable; - Machine* vm; + Machine* m; Thread* parent; Thread* peer; Thread* child; @@ -1235,12 +1221,8 @@ class Thread { unsigned criticalLevel; System::Thread* systemThread; object javaThread; - object code; object exception; object large; - unsigned ip; - unsigned sp; - int frame; unsigned heapIndex; unsigned heapOffset; Protector* protector; @@ -1253,7 +1235,6 @@ class Thread { uintptr_t* heap; uintptr_t defaultHeap[HeapSizeInWords]; #endif // not VM_STRESS - uintptr_t stack[StackSizeInWords]; }; inline object @@ -1362,27 +1343,27 @@ class RawMonitorResource { inline void NO_RETURN abort(Thread* t) { - abort(t->vm->system); + abort(t->m->system); } #ifndef NDEBUG inline void assert(Thread* t, bool v) { - assert(t->vm->system, v); + assert(t->m->system, v); } #endif // not NDEBUG inline void expect(Thread* t, bool v) { - expect(t->vm->system, v); + expect(t->m->system, v); } inline object allocateLarge(Thread* t, unsigned sizeInBytes) { - return t->large = static_cast(t->vm->system->allocate(sizeInBytes)); + return t->large = static_cast(t->m->system->allocate(sizeInBytes)); } inline object @@ -1403,7 +1384,7 @@ allocate(Thread* t, unsigned sizeInBytes) if (UNLIKELY(t->heapIndex + ceiling(sizeInBytes, BytesPerWord) >= Thread::HeapSizeInWords - or t->vm->exclusive)) + or t->m->exclusive)) { return allocate2(t, sizeInBytes); } else { @@ -1414,9 +1395,9 @@ allocate(Thread* t, unsigned sizeInBytes) inline void mark(Thread* t, object& target) { - if (t->vm->heap->needsMark(reinterpret_cast(&target))) { - ACQUIRE_RAW(t, t->vm->heapLock); - t->vm->heap->mark(reinterpret_cast(&target)); + if (t->m->heap->needsMark(reinterpret_cast(&target))) { + ACQUIRE_RAW(t, t->m->heapLock); + t->m->heap->mark(reinterpret_cast(&target)); } } @@ -1442,10 +1423,14 @@ arrayBodyUnsafe(Thread*, object, unsigned); #include "type-declarations.cpp" object -makeTrace(Thread* t, int frame); +makeTrace(Thread* t, FrameIterator* it); -object -makeTrace(Thread* t); +inline object +makeTrace(Thread* t) +{ + FrameIterator it; t->m->processor->start(t, &it); + return makeTrace(t, &it); +} inline object makeRuntimeException(Thread* t, object message) @@ -1595,268 +1580,6 @@ classInitializer(Thread* t, object class_); object frameMethod(Thread* t, int frame); -inline void -pushObject(Thread* t, object o) -{ - if (DebugStack) { - fprintf(stderr, "push object %p at %d\n", o, t->sp); - } - - assert(t, t->sp + 1 < Thread::StackSizeInWords / 2); - t->stack[(t->sp * 2) ] = ObjectTag; - t->stack[(t->sp * 2) + 1] = reinterpret_cast(o); - ++ t->sp; -} - -inline void -pushInt(Thread* t, uint32_t v) -{ - if (DebugStack) { - fprintf(stderr, "push int %d at %d\n", v, t->sp); - } - - assert(t, t->sp + 1 < Thread::StackSizeInWords / 2); - t->stack[(t->sp * 2) ] = IntTag; - t->stack[(t->sp * 2) + 1] = v; - ++ t->sp; -} - -inline void -pushFloat(Thread* t, float v) -{ - uint32_t a; memcpy(&a, &v, sizeof(uint32_t)); - pushInt(t, a); -} - -inline void -pushLong(Thread* t, uint64_t v) -{ - if (DebugStack) { - fprintf(stderr, "push long %"LLD" at %d\n", v, t->sp); - } - - pushInt(t, v >> 32); - pushInt(t, v & 0xFFFFFFFF); -} - -inline void -pushDouble(Thread* t, double v) -{ - uint64_t a; memcpy(&a, &v, sizeof(uint64_t)); - pushLong(t, a); -} - -inline object -popObject(Thread* t) -{ - if (DebugStack) { - fprintf(stderr, "pop object %p at %d\n", - reinterpret_cast(t->stack[((t->sp - 1) * 2) + 1]), - t->sp - 1); - } - - assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag); - return reinterpret_cast(t->stack[((-- t->sp) * 2) + 1]); -} - -inline uint32_t -popInt(Thread* t) -{ - if (DebugStack) { - fprintf(stderr, "pop int %"ULD" at %d\n", - t->stack[((t->sp - 1) * 2) + 1], - t->sp - 1); - } - - assert(t, t->stack[(t->sp - 1) * 2] == IntTag); - return t->stack[((-- t->sp) * 2) + 1]; -} - -inline float -popFloat(Thread* t) -{ - uint32_t a = popInt(t); - float f; memcpy(&f, &a, sizeof(float)); - return f; -} - -inline uint64_t -popLong(Thread* t) -{ - if (DebugStack) { - fprintf(stderr, "pop long %"LLD" at %d\n", - (static_cast(t->stack[((t->sp - 2) * 2) + 1]) << 32) - | static_cast(t->stack[((t->sp - 1) * 2) + 1]), - t->sp - 2); - } - - uint64_t a = popInt(t); - uint64_t b = popInt(t); - return (b << 32) | a; -} - -inline float -popDouble(Thread* t) -{ - uint64_t a = popLong(t); - double d; memcpy(&d, &a, sizeof(double)); - return d; -} - -inline object -peekObject(Thread* t, unsigned index) -{ - if (DebugStack) { - fprintf(stderr, "peek object %p at %d\n", - reinterpret_cast(t->stack[(index * 2) + 1]), - index); - } - - assert(t, index < Thread::StackSizeInWords / 2); - assert(t, t->stack[index * 2] == ObjectTag); - return *reinterpret_cast(t->stack + (index * 2) + 1); -} - -inline uint32_t -peekInt(Thread* t, unsigned index) -{ - if (DebugStack) { - fprintf(stderr, "peek int %"ULD" at %d\n", - t->stack[(index * 2) + 1], - index); - } - - assert(t, index < Thread::StackSizeInWords / 2); - assert(t, t->stack[index * 2] == IntTag); - return t->stack[(index * 2) + 1]; -} - -inline uint64_t -peekLong(Thread* t, unsigned index) -{ - if (DebugStack) { - fprintf(stderr, "peek long %"LLD" at %d\n", - (static_cast(t->stack[(index * 2) + 1]) << 32) - | static_cast(t->stack[((index + 1) * 2) + 1]), - index); - } - - return (static_cast(peekInt(t, index)) << 32) - | static_cast(peekInt(t, index + 1)); -} - -inline void -pokeObject(Thread* t, unsigned index, object value) -{ - if (DebugStack) { - fprintf(stderr, "poke object %p at %d\n", value, index); - } - - t->stack[index * 2] = ObjectTag; - t->stack[(index * 2) + 1] = reinterpret_cast(value); -} - -inline void -pokeInt(Thread* t, unsigned index, uint32_t value) -{ - if (DebugStack) { - fprintf(stderr, "poke int %d at %d\n", value, index); - } - - t->stack[index * 2] = IntTag; - t->stack[(index * 2) + 1] = value; -} - -inline void -pokeLong(Thread* t, unsigned index, uint64_t value) -{ - if (DebugStack) { - fprintf(stderr, "poke long %"LLD" at %d\n", value, index); - } - - pokeInt(t, index, value >> 32); - pokeInt(t, index + 1, value & 0xFFFFFFFF); -} - -inline object* -pushReference(Thread* t, object o) -{ - if (o) { - expect(t, t->sp + 1 < Thread::StackSizeInWords / 2); - pushObject(t, o); - return reinterpret_cast(t->stack + ((t->sp - 1) * 2) + 1); - } else { - return 0; - } -} - -inline int -frameNext(Thread* t, int frame) -{ - return peekInt(t, frame + FrameNextOffset); -} - -inline object -frameMethod(Thread* t, int frame) -{ - return peekObject(t, frame + FrameMethodOffset); -} - -inline unsigned -frameIp(Thread* t, int frame) -{ - return peekInt(t, frame + FrameIpOffset); -} - -inline unsigned -frameBase(Thread* t, int frame) -{ - return peekInt(t, frame + FrameBaseOffset); -} - -inline object -localObject(Thread* t, unsigned index) -{ - return peekObject(t, frameBase(t, t->frame) + index); -} - -inline uint32_t -localInt(Thread* t, unsigned index) -{ - return peekInt(t, frameBase(t, t->frame) + index); -} - -inline uint64_t -localLong(Thread* t, unsigned index) -{ - return peekLong(t, frameBase(t, t->frame) + index); -} - -inline void -setLocalObject(Thread* t, unsigned index, object value) -{ - pokeObject(t, frameBase(t, t->frame) + index, value); -} - -inline void -setLocalInt(Thread* t, unsigned index, uint32_t value) -{ - pokeInt(t, frameBase(t, t->frame) + index, value); -} - -inline void -setLocalLong(Thread* t, unsigned index, uint64_t value) -{ - pokeLong(t, frameBase(t, t->frame) + index, value); -} - -inline object -makeTrace(Thread* t) -{ - pokeInt(t, t->frame + FrameIpOffset, t->ip); - return makeTrace(t, t->frame); -} - inline unsigned baseSize(Thread* t, object o, object class_) { @@ -1897,8 +1620,8 @@ markHashTaken(Thread* t, object o) assert(t, not objectExtended(t, o)); cast(o, 0) |= HashTakenMark; - ACQUIRE_RAW(t, t->vm->heapLock); - t->vm->heap->pad(o, 1); + ACQUIRE_RAW(t, t->m->heapLock); + t->m->heap->pad(o, 1); } inline uint32_t @@ -1951,7 +1674,7 @@ stringHash(Thread* t, object s) if (stringHashCode(t, s) == 0 and stringLength(t, s)) { object data = stringData(t, s); if (objectClass(t, data) - == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) { stringHashCode(t, s) = hash (&byteArrayBody(t, data, stringOffset(t, s)), stringLength(t, s)); @@ -1968,7 +1691,7 @@ stringCharAt(Thread* t, object s, int i) { object data = stringData(t, s); if (objectClass(t, data) - == arrayBody(t, t->vm->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) { return byteArrayBody(t, data, i); } else { @@ -2114,6 +1837,10 @@ parseClass(Thread* t, const uint8_t* data, unsigned length); object resolveClass(Thread* t, object spec); +object +resolveMethod(Thread* t, const char* className, const char* methodName, + const char* methodSpec); + object resolveObjectArrayClass(Thread* t, object elementSpec); @@ -2122,14 +1849,14 @@ initClass(Thread* t, object c) { PROTECT(t, c); - acquire(t, t->vm->classLock); + acquire(t, t->m->classLock); if (classVmFlags(t, c) & NeedInitFlag and (classVmFlags(t, c) & InitFlag) == 0) { classVmFlags(t, c) |= InitFlag; - run(t, classInitializer(t, c), 0); + t->m->processor->invoke(t, classInitializer(t, c), 0); } else { - release(t, t->vm->classLock); + release(t, t->m->classLock); } } @@ -2189,7 +1916,7 @@ objectArrayBody(Thread* t UNUSED, object array, unsigned index) assert(t, classArrayElementSize(t, objectClass(t, array)) == BytesPerWord); assert(t, classObjectMask(t, objectClass(t, array)) == classObjectMask(t, arrayBody - (t, t->vm->types, Machine::ArrayType))); + (t, t->m->types, Machine::ArrayType))); return cast(array, (2 + index) * BytesPerWord); } @@ -2323,6 +2050,16 @@ intern(Thread* t, object s); void exit(Thread* t); +int +run(System* system, Heap* heap, Finder* finder, Processor* processor, + const char* className, int argc, const char** argv); + +jobject +makeLocalReference(Thread* t, object o); + +void +disposeLocalReference(Thread* t, jobject r); + } // namespace vm #endif//MACHINE_H diff --git a/src/main.cpp b/src/main.cpp index 9a88c2dfbe..d3cb5fe230 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,8 @@ #include "system.h" #include "heap.h" #include "finder.h" -#include "run.h" +#include "processor.h" +#include "machine.h" using namespace vm; @@ -15,9 +16,11 @@ run(unsigned heapSize, const char* path, const char* class_, int argc, System* s = makeSystem(heapSize); Finder* f = makeFinder(s, path); Heap* heap = makeHeap(s); + Processor* p = makeProcessor(s); - int exitCode = run(s, heap, f, class_, argc, argv); + int exitCode = run(s, heap, f, p, class_, argc, argv); + p->dispose(); heap->dispose(); f->dispose(); s->dispose(); diff --git a/src/processor.h b/src/processor.h new file mode 100644 index 0000000000..929215ab1f --- /dev/null +++ b/src/processor.h @@ -0,0 +1,96 @@ +#ifndef PROCESSOR_H +#define PROCESSOR_H + +#include "common.h" +#include "system.h" +#include "heap.h" + +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() { } + + virtual Thread* + makeThread(Machine* m, object javaThread, Thread* parent) = 0; + + virtual void + visitObjects(Thread* t, Heap::Visitor* v) = 0; + + virtual void + start(Thread* t, FrameIterator* it) = 0; + + virtual void + next(Thread* t, FrameIterator* it) = 0; + + virtual object + invokeArray(Thread* t, object method, object this_, object arguments) = 0; + + virtual object + invokeList(Thread* t, object method, object this_, bool indirectObjects, + va_list arguments) = 0; + + virtual object + invokeList(Thread* t, const char* className, const char* methodName, + const char* methodSpec, object this_, va_list arguments) = 0; + + virtual void + dispose() = 0; + + object + invoke(Thread* t, object method, object this_, ...) + { + va_list a; + va_start(a, this_); + + object r = invokeList(t, method, this_, false, a); + + va_end(a); + + return r; + } + + object + invoke(Thread* t, const char* className, const char* methodName, + const char* methodSpec, object this_, ...) + { + va_list a; + va_start(a, this_); + + object r = invokeList(t, className, methodName, methodSpec, this_, a); + + va_end(a); + + return r; + } +}; + +Processor* +makeProcessor(System* system); + +} // namespace vm + +#endif//PROCESSOR_H diff --git a/src/run.h b/src/run.h deleted file mode 100644 index 709032f6c5..0000000000 --- a/src/run.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef RUN_H -#define RUN_H - -#include "system.h" -#include "heap.h" -#include "finder.h" -#include "machine.h" - -namespace vm { - -object -runv(Thread* t, object method, object this_, bool indirectObjects, va_list a); - -object -run(Thread* t, object method, object this_, ...); - -object -run2(Thread* t, object method, object this_, object arguments); - -object -run(Thread* t, const char* className, const char* methodName, - const char* methodSpec, object this_, ...); - -int -run(System* sys, Heap* heap, Finder* finder, - const char* className, int argc, const char** argv); - -} // namespace vm - -#endif//RUN_H diff --git a/src/type-generator.cpp b/src/type-generator.cpp index d94d0fa83d..6409cfb964 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -1022,7 +1022,7 @@ writeSubtypeAssertions(Output* out, Object* o) for (Object* p = typeSubtypes(o); p; p = cdr(p)) { Object* st = car(p); out->write(" or objectClass(t, o) == arrayBodyUnsafe"); - out->write("(t, t->vm->types, Machine::"); + out->write("(t, t->m->types, Machine::"); out->write(capitalize(typeName(st))); out->write("Type)"); writeSubtypeAssertions(out, st); @@ -1061,9 +1061,9 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) if (unsafe) { out->write(" assert(t, true);"); } else { - out->write(" assert(t, t->vm->unsafe or "); + out->write(" assert(t, t->m->unsafe or "); out->write("objectClass(t, o) == arrayBodyUnsafe"); - out->write("(t, t->vm->types, Machine::"); + out->write("(t, t->m->types, Machine::"); out->write(capitalize(::typeName(memberOwner(member)))); out->write("Type)"); writeSubtypeAssertions(out, memberOwner(member)); @@ -1347,7 +1347,7 @@ writeConstructors(Output* out, Object* declarations) out->write(");\n"); out->write(" cast(o, 0) "); - out->write("= arrayBody(t, t->vm->types, Machine::"); + out->write("= arrayBody(t, t->m->types, Machine::"); out->write(capitalize(typeName(o))); out->write("Type);\n"); @@ -1502,7 +1502,7 @@ writeInitialization(Output* out, Object* type) } if (typeJavaName(type) and typeSuper(type)) { - out->write(" object super = arrayBody(t, t->vm->types, Machine::"); + out->write(" object super = arrayBody(t, t->m->types, Machine::"); out->write(capitalize(typeName(typeSuper(type)))); out->write("Type);\n"); } else { @@ -1514,9 +1514,9 @@ writeInitialization(Output* out, Object* type) out->write(typeFixedSize(type)); out->write(", "); out->write(typeArrayElementSize(type)); - out->write(", mask, 0, super, 0, 0, 0, 0, 0, t->vm->loader);\n"); + out->write(", mask, 0, super, 0, 0, 0, 0, 0, t->m->loader);\n"); - out->write(" set(t, arrayBody(t, t->vm->types, Machine::"); + out->write(" set(t, arrayBody(t, t->m->types, Machine::"); out->write(capitalize(typeName(type))); out->write("Type), class_);\n"); @@ -1566,14 +1566,14 @@ writeInitializations(Output* out, Object* declarations) { unsigned count = typeCount(declarations); - out->write("t->vm->types = allocate(t, pad(("); + out->write("t->m->types = allocate(t, pad(("); out->write(count); out->write(" * sizeof(void*)) + sizeof(uintptr_t) + sizeof(void*)));\n"); - out->write("cast(t->vm->types, 0) = 0;\n"); - out->write("arrayLength(t, t->vm->types) = "); + out->write("cast(t->m->types, 0) = 0;\n"); + out->write("arrayLength(t, t->m->types) = "); out->write(count); out->write(";\n"); - out->write("memset(&arrayBody(t, t->vm->types, 0), 0, "); + out->write("memset(&arrayBody(t, t->m->types, 0), 0, "); out->write(count); out->write(" * sizeof(void*));\n\n"); @@ -1596,13 +1596,13 @@ writeJavaInitialization(Output* out, Object* type) out->write(typeJavaName(type)); out->write("\");\n"); - out->write(" object class_ = arrayBody(t, t->vm->types, Machine::"); + out->write(" object class_ = arrayBody(t, t->m->types, Machine::"); out->write(capitalize(typeName(type))); out->write("Type);\n"); out->write(" set(t, className(t, class_), name);\n"); - out->write(" hashMapInsert(t, t->vm->bootstrapClassMap, "); + out->write(" hashMapInsert(t, t->m->bootstrapClassMap, "); out->write("name, class_, byteArrayHash);\n"); out->write("}\n\n"); diff --git a/test/Instructions.java b/test/Instructions.java new file mode 100644 index 0000000000..9e60fd904c --- /dev/null +++ b/test/Instructions.java @@ -0,0 +1,7 @@ +public class Instructions { + public static void main(String[] args) { + int a = 2; + int b = 2; + int c = a + b; + } +}