refactoring effort to pave the way for JIT compilation

This commit is contained in:
Joel Dice 2007-09-23 19:39:03 -06:00
parent 65a3ee4277
commit 8d983c8a39
13 changed files with 1195 additions and 722 deletions

View File

@ -93,9 +93,9 @@ interpreter-depends = \
$(src)/system.h \ $(src)/system.h \
$(src)/heap.h \ $(src)/heap.h \
$(src)/finder.h \ $(src)/finder.h \
$(src)/processor.h \
$(src)/stream.h \ $(src)/stream.h \
$(src)/constants.h \ $(src)/constants.h \
$(src)/run.h \
$(src)/jnienv.h \ $(src)/jnienv.h \
$(src)/machine.h $(src)/machine.h
@ -104,7 +104,7 @@ interpreter-sources = \
$(src)/finder.cpp \ $(src)/finder.cpp \
$(src)/machine.cpp \ $(src)/machine.cpp \
$(src)/heap.cpp \ $(src)/heap.cpp \
$(src)/run.cpp \ $(src)/interpret.cpp \
$(src)/builtin.cpp \ $(src)/builtin.cpp \
$(src)/jnienv.cpp \ $(src)/jnienv.cpp \
$(src)/main.cpp $(src)/main.cpp
@ -151,7 +151,7 @@ flags = -cp $(cls)
args = $(flags) $(call class-name,$(input)) args = $(flags) $(call class-name,$(input))
.PHONY: build .PHONY: build
build: $(executable) $(classpath-objects) build: $(executable) $(classpath-objects) $(test-classes)
$(input): $(classpath-objects) $(input): $(classpath-objects)

View File

@ -1,6 +1,6 @@
#include "machine.h" #include "machine.h"
#include "constants.h" #include "constants.h"
#include "run.h" #include "processor.h"
#undef JNIEXPORT #undef JNIEXPORT
#define JNIEXPORT __attribute__ ((visibility("default"))) #define JNIEXPORT __attribute__ ((visibility("default")))
@ -33,7 +33,7 @@ search(Thread* t, jstring name, object (*op)(Thread*, object),
return 0; return 0;
} }
return pushReference(t, r); return makeLocalReference(t, r);
} else { } else {
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
return 0; return 0;
@ -53,7 +53,7 @@ Java_java_lang_Object_toString(Thread* t, jobject this_)
&byteArrayBody(t, className(t, objectClass(t, *this_)), 0), &byteArrayBody(t, className(t, objectClass(t, *this_)), 0),
hash); hash);
return pushReference(t, s); return makeLocalReference(t, s);
} }
extern "C" JNIEXPORT jclass JNICALL extern "C" JNIEXPORT jclass JNICALL
@ -61,7 +61,7 @@ Java_java_lang_Object_getClass(Thread* t, jobject this_)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, objectClass(t, *this_)); return makeLocalReference(t, objectClass(t, *this_));
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -105,7 +105,7 @@ Java_java_lang_Object_clone(Thread* t, jclass, jobject o)
memcpy(reinterpret_cast<void**>(clone) + 1, memcpy(reinterpret_cast<void**>(clone) + 1,
reinterpret_cast<void**>(*o) + 1, reinterpret_cast<void**>(*o) + 1,
(baseSize(t, *o, objectClass(t, *o)) - 1) * BytesPerWord); (baseSize(t, *o, objectClass(t, *o)) - 1) * BytesPerWord);
return pushReference(t, clone); return makeLocalReference(t, clone);
} }
extern "C" JNIEXPORT jclass JNICALL extern "C" JNIEXPORT jclass JNICALL
@ -114,11 +114,11 @@ Java_java_lang_ClassLoader_defineClass
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
uint8_t* buffer = static_cast<uint8_t*>(t->vm->system->allocate(length)); uint8_t* buffer = static_cast<uint8_t*>(t->m->system->allocate(length));
memcpy(buffer, &byteArrayBody(t, *b, offset), length); memcpy(buffer, &byteArrayBody(t, *b, offset), length);
object c = parseClass(t, buffer, length); object c = parseClass(t, buffer, length);
t->vm->system->free(buffer); t->m->system->free(buffer);
return pushReference(t, c); return makeLocalReference(t, c);
} }
extern "C" JNIEXPORT jclass JNICALL extern "C" JNIEXPORT jclass JNICALL
@ -147,7 +147,7 @@ Java_java_lang_SystemClassLoader_resourceExists
if (LIKELY(name)) { if (LIKELY(name)) {
char n[stringLength(t, *name) + 1]; char n[stringLength(t, *name) + 1];
stringChars(t, *name, n); stringChars(t, *name, n);
return t->vm->finder->exists(n); return t->m->finder->exists(n);
} else { } else {
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
return 0; return 0;
@ -159,7 +159,7 @@ Java_java_io_ObjectInputStream_makeInstance(Thread* t, jclass, jclass c)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, make(t, *c)); return makeLocalReference(t, make(t, *c));
} }
extern "C" JNIEXPORT jclass JNICALL extern "C" JNIEXPORT jclass JNICALL
@ -169,23 +169,23 @@ Java_java_lang_Class_primitiveClass(Thread* t, jclass, jchar name)
switch (name) { switch (name) {
case 'B': case 'B':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JbyteType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JbyteType));
case 'C': case 'C':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JcharType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JcharType));
case 'D': case 'D':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JdoubleType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JdoubleType));
case 'F': case 'F':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JfloatType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JfloatType));
case 'I': case 'I':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JintType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JintType));
case 'J': case 'J':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JlongType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JlongType));
case 'S': case 'S':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JshortType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JshortType));
case 'V': case 'V':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JvoidType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JvoidType));
case 'Z': case 'Z':
return pushReference(t, arrayBody(t, t->vm->types, Machine::JbooleanType)); return makeLocalReference(t, arrayBody(t, t->m->types, Machine::JbooleanType));
default: default:
t->exception = makeIllegalArgumentException(t); t->exception = makeIllegalArgumentException(t);
return 0; return 0;
@ -247,7 +247,7 @@ Java_java_lang_reflect_Field_getObject
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, cast<object>(*instance, offset)); return makeLocalReference(t, cast<object>(*instance, offset));
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -300,7 +300,7 @@ Java_java_lang_reflect_Constructor_make(Thread* t, jclass, jclass c)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, make(t, *c)); return makeLocalReference(t, make(t, *c));
} }
extern "C" JNIEXPORT jobject JNICALL extern "C" JNIEXPORT jobject JNICALL
@ -308,8 +308,11 @@ Java_java_lang_reflect_Method_getCaller(Thread* t, jclass)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference FrameIterator it; t->m->processor->start(t, &it);
(t, frameMethod(t, frameNext(t, frameNext(t, t->frame)))); t->m->processor->next(t, &it);
t->m->processor->next(t, &it);
return makeLocalReference(t, it.method);
} }
extern "C" JNIEXPORT jobject JNICALL extern "C" JNIEXPORT jobject JNICALL
@ -318,11 +321,12 @@ Java_java_lang_reflect_Method_invoke
{ {
ENTER(t, Thread::ActiveState); 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) { if (t->exception) {
t->exception = makeInvocationTargetException(t, t->exception); t->exception = makeInvocationTargetException(t, t->exception);
} }
return pushReference(t, v); return makeLocalReference(t, v);
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
@ -351,7 +355,7 @@ Java_java_lang_reflect_Array_makeObjectArray
{ {
ENTER(t, Thread::ActiveState); 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 extern "C" JNIEXPORT jint JNICALL
@ -387,7 +391,7 @@ Java_java_lang_String_intern(Thread* t, jobject this_)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, intern(t, *this_)); return makeLocalReference(t, intern(t, *this_));
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
@ -401,7 +405,7 @@ Java_java_lang_System_getVMProperty(Thread* t, jclass, jint code)
switch (code) { switch (code) {
case JavaClassPath: case JavaClassPath:
return pushReference(t, makeString(t, "%s", t->vm->finder->path())); return makeLocalReference(t, makeString(t, "%s", t->m->finder->path()));
default: default:
t->exception = makeRuntimeException(t, 0); 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) Java_java_lang_Runtime_load(Thread* t, jclass, jstring name, jboolean mapName)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->vm->classLock); ACQUIRE(t, t->m->classLock);
char n[stringLength(t, *name) + 1]; char n[stringLength(t, *name) + 1];
stringChars(t, *name, n); 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() if (lib->name()
and strcmp(lib->name(), n) == 0 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; System::Library* lib;
if (LIKELY(t->vm->system->success if (LIKELY(t->m->system->success
(t->vm->system->load(&lib, n, mapName, t->vm->libraries)))) (t->m->system->load(&lib, n, mapName, t->m->libraries))))
{ {
t->vm->libraries = lib; t->m->libraries = lib;
} else { } else {
object message = makeString(t, "library not found: %s", n); object message = makeString(t, "library not found: %s", n);
t->exception = makeUnsatisfiedLinkError(t, message); t->exception = makeUnsatisfiedLinkError(t, message);
@ -510,7 +514,7 @@ Java_java_lang_Runtime_exit(Thread* t, jobject, jint code)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
t->vm->system->exit(code); t->m->system->exit(code);
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
@ -525,24 +529,25 @@ Java_java_lang_Throwable_trace(Thread* t, jclass, jint skipCount)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
int frame = t->frame; FrameIterator it; t->m->processor->start(t, &it);
while (skipCount-- and frame >= 0) {
frame = frameNext(t, frame); while (skipCount-- and it.valid()) {
t->m->processor->next(t, &it);
} }
// skip Throwable constructors // skip Throwable constructors
while (frame >= 0 while (it.valid()
and isAssignableFrom and isAssignableFrom
(t, arrayBody(t, t->vm->types, Machine::ThrowableType), (t, arrayBody(t, t->m->types, Machine::ThrowableType),
methodClass(t, frameMethod(t, frame))) methodClass(t, it.method))
and strcmp(reinterpret_cast<const int8_t*>("<init>"), and strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, frameMethod(t, frame)), 0)) &byteArrayBody(t, methodName(t, it.method), 0))
== 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 extern "C" JNIEXPORT jarray JNICALL
@ -552,7 +557,7 @@ Java_java_lang_Throwable_resolveTrace(Thread* t, jclass, jobject trace)
unsigned length = arrayLength(t, *trace); unsigned length = arrayLength(t, *trace);
object array = makeObjectArray object array = makeObjectArray
(t, arrayBody(t, t->vm->types, Machine::StackTraceElementType), (t, arrayBody(t, t->m->types, Machine::StackTraceElementType),
length, true); length, true);
PROTECT(t, array); PROTECT(t, array);
@ -578,7 +583,7 @@ Java_java_lang_Throwable_resolveTrace(Thread* t, jclass, jobject trace)
set(t, objectArrayBody(t, array, i), ste); set(t, objectArrayBody(t, array, i), ste);
} }
return pushReference(t, array); return makeLocalReference(t, array);
} }
extern "C" JNIEXPORT jobject JNICALL extern "C" JNIEXPORT jobject JNICALL
@ -586,7 +591,7 @@ Java_java_lang_Thread_currentThread(Thread* t, jclass)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, t->javaThread); return makeLocalReference(t, t->javaThread);
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
@ -594,12 +599,12 @@ Java_java_lang_Thread_doStart(Thread* t, jobject this_)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
Thread* p = new (t->vm->system->allocate(sizeof(Thread))) Thread* p = new (t->m->system->allocate(sizeof(Thread)))
Thread(t->vm, *this_, t); Thread(t->m, *this_, t);
enter(p, Thread::ActiveState); 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<jlong>(p); return reinterpret_cast<jlong>(p);
} else { } else {
p->exit(); p->exit();
@ -623,7 +628,7 @@ Java_java_net_URL_00024ResourceInputStream_open
char p[stringLength(t, *path) + 1]; char p[stringLength(t, *path) + 1];
stringChars(t, *path, p); stringChars(t, *path, p);
return reinterpret_cast<jlong>(t->vm->finder->find(p)); return reinterpret_cast<jlong>(t->m->finder->find(p));
} else { } else {
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
return 0; return 0;

View File

@ -176,6 +176,13 @@ hash(const uint16_t* s, unsigned length)
return h; return h;
} }
class Machine;
class Thread;
struct Object { };
typedef Object* object;
} // namespace vm } // namespace vm
#endif//COMMON_H #endif//COMMON_H

281
src/compile.cpp Normal file
View File

@ -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

View File

@ -1,16 +1,327 @@
#include "common.h" #include "common.h"
#include "system.h" #include "system.h"
#include "heap.h"
#include "finder.h"
#include "constants.h" #include "constants.h"
#include "run.h"
#include "jnienv.h"
#include "machine.h" #include "machine.h"
#include "processor.h"
using namespace vm; using namespace vm;
namespace { 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<uintptr_t>(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<object>(t->stack[((t->sp - 1) * 2) + 1]),
t->sp - 1);
}
assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag);
return reinterpret_cast<object>(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<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32)
| static_cast<uint64_t>(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<object>(t->stack[(index * 2) + 1]),
index);
}
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == ObjectTag);
return *reinterpret_cast<object*>(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<uint64_t>(t->stack[(index * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]),
index);
}
return (static_cast<uint64_t>(peekInt(t, index)) << 32)
| static_cast<uint64_t>(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<uintptr_t>(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<object*>(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 void
pushFrame(Thread* t, object method) pushFrame(Thread* t, object method)
{ {
@ -69,7 +380,7 @@ popFrame(Thread* t)
t->exception = makeExceptionInInitializerError(t, t->exception); t->exception = makeExceptionInInitializerError(t, t->exception);
} }
classVmFlags(t, methodClass(t, method)) &= ~(NeedInitFlag | InitFlag); classVmFlags(t, methodClass(t, method)) &= ~(NeedInitFlag | InitFlag);
release(t, t->vm->classLock); release(t, t->m->classLock);
} }
t->sp = frameBase(t, t->frame); t->sp = frameBase(t, t->frame);
@ -128,7 +439,7 @@ inline object
resolveClass(Thread* t, object pool, unsigned index) resolveClass(Thread* t, object pool, unsigned index)
{ {
object o = arrayBody(t, pool, 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); PROTECT(t, pool);
@ -141,10 +452,11 @@ resolveClass(Thread* t, object pool, unsigned index)
} }
inline object 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); 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); PROTECT(t, container);
@ -158,11 +470,11 @@ resolveClass(Thread* t, object container, object& (*class_)(Thread*, object))
inline object inline object
resolve(Thread* t, object pool, unsigned index, resolve(Thread* t, object pool, unsigned index,
object (*find)(Thread*, object, object, object), object (*find)(vm::Thread*, object, object, object),
object (*makeError)(Thread*, object)) object (*makeError)(vm::Thread*, object))
{ {
object o = arrayBody(t, pool, index); 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); PROTECT(t, pool);
@ -264,10 +576,10 @@ inline object
resolveNativeMethodData(Thread* t, object method) resolveNativeMethodData(Thread* t, object method)
{ {
if (objectClass(t, methodCode(t, method)) if (objectClass(t, methodCode(t, method))
== arrayBody(t, t->vm->types, Machine::ByteArrayType)) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{ {
object data = 0; 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<const char*> void* p = lib->resolve(reinterpret_cast<const char*>
(&byteArrayBody(t, methodCode(t, method), 0))); (&byteArrayBody(t, methodCode(t, method), 0)));
if (p) { if (p) {
@ -383,7 +695,7 @@ invokeNative(Thread* t, object method)
{ ENTER(t, Thread::IdleState); { ENTER(t, Thread::IdleState);
result = t->vm->system->call result = t->m->system->call
(function, (function,
args, args,
&nativeMethodDataParameterTypes(t, data, 0), &nativeMethodDataParameterTypes(t, data, 0),
@ -451,7 +763,7 @@ bool
classInit2(Thread* t, object class_, unsigned ipOffset) classInit2(Thread* t, object class_, unsigned ipOffset)
{ {
PROTECT(t, class_); PROTECT(t, class_);
acquire(t, t->vm->classLock); acquire(t, t->m->classLock);
if (classVmFlags(t, class_) & NeedInitFlag if (classVmFlags(t, class_) & NeedInitFlag
and (classVmFlags(t, class_) & InitFlag) == 0) and (classVmFlags(t, class_) & InitFlag) == 0)
{ {
@ -460,7 +772,7 @@ classInit2(Thread* t, object class_, unsigned ipOffset)
t->ip -= ipOffset; t->ip -= ipOffset;
return true; return true;
} else { } else {
release(t, t->vm->classLock); release(t, t->m->classLock);
return false; return false;
} }
} }
@ -533,7 +845,7 @@ populateMultiArray(Thread* t, object array, int32_t* counts,
} }
object object
run(Thread* t) interpret(Thread* t)
{ {
const int base = t->frame; const int base = t->frame;
@ -717,7 +1029,7 @@ run(Thread* t)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) if (objectClass(t, array)
== arrayBody(t, t->vm->types, Machine::BooleanArrayType)) == arrayBody(t, t->m->types, Machine::BooleanArrayType))
{ {
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) static_cast<uintptr_t>(index)
@ -756,7 +1068,7 @@ run(Thread* t)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) if (objectClass(t, array)
== arrayBody(t, t->vm->types, Machine::BooleanArrayType)) == arrayBody(t, t->m->types, Machine::BooleanArrayType))
{ {
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) static_cast<uintptr_t>(index)
@ -1890,14 +2202,14 @@ run(Thread* t)
object v = arrayBody(t, codePool(t, code), index - 1); 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)); pushInt(t, intValue(t, v));
} else if (objectClass(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)); pushInt(t, floatValue(t, v));
} else if (objectClass(t, v) } else if (objectClass(t, v)
== arrayBody(t, t->vm->types, Machine::StringType)) == arrayBody(t, t->m->types, Machine::StringType))
{ {
pushObject(t, v); pushObject(t, v);
} else { } else {
@ -1914,10 +2226,10 @@ run(Thread* t)
object v = arrayBody(t, codePool(t, code), ((index1 << 8) | index2) - 1); 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)); pushLong(t, longValue(t, v));
} else if (objectClass(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)); pushLong(t, doubleValue(t, v));
} else { } else {
@ -2506,24 +2818,6 @@ run(Thread* t)
return 0; 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 void
pushArguments(Thread* t, object this_, const char* spec, bool indirectObjects, pushArguments(Thread* t, object this_, const char* spec, bool indirectObjects,
va_list a) va_list a)
@ -2704,7 +2998,7 @@ invoke(Thread* t, object method)
checkStack(t, method); checkStack(t, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
pushFrame(t, method); pushFrame(t, method);
result = ::run(t); result = interpret(t);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
popFrame(t); popFrame(t);
} }
@ -2745,48 +3039,55 @@ invoke(Thread* t, object method)
} }
} }
} // namespace void
MyProcessor::visitObjects(vm::Thread* vmt, Heap::Visitor* v)
namespace vm {
object
runv(Thread* t, object method, object this_, bool indirectObjects, va_list a)
{ {
assert(t, t->state == Thread::ActiveState Thread* t = static_cast<Thread*>(vmt);
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); v->visit(&(t->code));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1 for (unsigned i = 0; i < t->sp; ++i) {
> Thread::StackSizeInWords / 2)) if (t->stack[i * 2] == ObjectTag) {
{ v->visit(t->stack + (i * 2) + 1);
t->exception = makeStackOverflowError(t);
return 0;
} }
}
}
const char* spec = reinterpret_cast<char*> void
(&byteArrayBody(t, methodSpec(t, method), 0)); MyProcessor::start(vm::Thread* vmt, FrameIterator* it)
pushArguments(t, this_, spec, indirectObjects, a); {
Thread* t = static_cast<Thread*>(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<Thread*>(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 object
run(Thread* t, object method, object this_, ...) MyProcessor::invokeArray(vm::Thread* vmt, object method, object this_,
object arguments)
{ {
va_list a; Thread* t = static_cast<Thread*>(vmt);
va_start(a, this_);
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 assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState); or t->state == Thread::ExclusiveState);
@ -2803,13 +3104,41 @@ run2(Thread* t, object method, object this_, object arguments)
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments); pushArguments(t, this_, spec, arguments);
return invoke(t, method); return ::invoke(t, method);
} }
object object
run(Thread* t, const char* className, const char* methodName, MyProcessor::invokeList(vm::Thread* vmt, object method, object this_,
const char* methodSpec, object this_, ...) bool indirectObjects, va_list arguments)
{ {
Thread* t = static_cast<Thread*>(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<char*>
(&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<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState); or t->state == Thread::ExclusiveState);
@ -2820,55 +3149,26 @@ run(Thread* t, const char* className, const char* methodName,
return 0; return 0;
} }
va_list a; pushArguments(t, this_, methodSpec, false, arguments);
va_start(a, this_);
pushArguments(t, this_, methodSpec, false, a); object method = resolveMethod(t, className, methodName, methodSpec);
va_end(a);
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);
object method = findMethodInClass(t, class_, referenceName(t, reference),
referenceSpec(t, reference));
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 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 } // namespace
run(System* system, Heap* heap, Finder* finder,
const char* className, int argc, const char** argv) namespace vm {
Processor*
makeProcessor(System* system)
{ {
Machine m(system, heap, finder); return new (system->allocate(sizeof(MyProcessor))) MyProcessor(system);
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;
} }
} // namespace vm } // namespace vm

View File

@ -1,6 +1,6 @@
#include "jnienv.h" #include "jnienv.h"
#include "machine.h" #include "machine.h"
#include "run.h" #include "processor.h"
#include "constants.h" #include "constants.h"
using namespace vm; using namespace vm;
@ -15,7 +15,7 @@ AttachCurrentThread(Machine* m, Thread** t, void*)
{ {
*t = static_cast<Thread*>(m->localThread->get()); *t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) { if (*t == 0) {
*t = new (m->system->allocate(sizeof(Thread))) Thread(m, 0, m->rootThread); *t = m->processor->makeThread(m, 0, m->rootThread);
m->localThread->set(*t); m->localThread->set(*t);
} }
@ -63,7 +63,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
char* chars = static_cast<char*> char* chars = static_cast<char*>
(t->vm->system->allocate(stringLength(t, *s) + 1)); (t->m->system->allocate(stringLength(t, *s) + 1));
stringChars(t, *s, chars); stringChars(t, *s, chars);
if (isCopy) *isCopy = true; if (isCopy) *isCopy = true;
@ -73,7 +73,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
void JNICALL void JNICALL
ReleaseStringUTFChars(Thread* t, jstring, const char* chars) ReleaseStringUTFChars(Thread* t, jstring, const char* chars)
{ {
t->vm->system->free(chars); t->m->system->free(chars);
} }
jstring JNICALL jstring JNICALL
@ -81,7 +81,7 @@ NewStringUTF(Thread* t, const char* chars)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeString(t, "%s", chars)); return makeLocalReference(t, makeString(t, "%s", chars));
} }
jclass JNICALL jclass JNICALL
@ -92,7 +92,7 @@ FindClass(Thread* t, const char* name)
object n = makeByteArray(t, strlen(name) + 1, false); object n = makeByteArray(t, strlen(name) + 1, false);
memcpy(&byteArrayBody(t, n, 0), name, byteArrayLength(t, n)); memcpy(&byteArrayBody(t, n, 0), name, byteArrayLength(t, n));
return pushReference(t, resolveClass(t, n)); return makeLocalReference(t, resolveClass(t, n));
} }
jint JNICALL jint JNICALL
@ -122,9 +122,9 @@ ThrowNew(Thread* t, jclass c, const char* message)
} }
void JNICALL void JNICALL
DeleteLocalRef(Thread*, jobject) DeleteLocalRef(Thread* t, jobject r)
{ {
// do nothing disposeLocalReference(t, r);
} }
jboolean JNICALL jboolean JNICALL
@ -138,7 +138,7 @@ GetObjectClass(Thread* t, jobject o)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, objectClass(t, *o)); return makeLocalReference(t, objectClass(t, *o));
} }
jboolean JNICALL jboolean JNICALL
@ -172,18 +172,18 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec)
if (classFlags(t, *c) & ACC_INTERFACE) { if (classFlags(t, *c) & ACC_INTERFACE) {
PROTECT(t, method); PROTECT(t, method);
ACQUIRE(t, t->vm->referenceLock); ACQUIRE(t, t->m->referenceLock);
for (unsigned i = 0; i < vectorSize(t, t->vm->jniInterfaceTable); ++i) { for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) {
if (method == vectorBody(t, t->vm->jniInterfaceTable, i)) { if (method == vectorBody(t, t->m->jniInterfaceTable, i)) {
return i; return i;
} }
} }
t->vm->jniInterfaceTable t->m->jniInterfaceTable
= vectorAppend(t, t->vm->jniInterfaceTable, method); = vectorAppend(t, t->m->jniInterfaceTable, method);
return (vectorSize(t, t->vm->jniInterfaceTable) - 1) | InterfaceMethodID; return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID;
} else { } else {
return methodOffset(t, method) + 1; return methodOffset(t, method) + 1;
} }
@ -204,7 +204,7 @@ inline object
getMethod(Thread* t, object o, jmethodID m) getMethod(Thread* t, object o, jmethodID m)
{ {
if (m & InterfaceMethodID) { if (m & InterfaceMethodID) {
return vectorBody(t, t->vm->jniInterfaceTable, m & (~InterfaceMethodID)); return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID));
} else { } else {
return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); 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); 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 jobject JNICALL
@ -236,7 +237,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); jint i = (t->exception ? 0 : floatValue(t, r));
jfloat f; memcpy(&f, &i, 4); jfloat f; memcpy(&f, &i, 4);
return f; return f;
@ -392,7 +393,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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)); jlong i = (t->exception ? 0 : doubleValue(t, r));
jdouble f; memcpy(&f, &i, 4); jdouble f; memcpy(&f, &i, 4);
return f; return f;
@ -416,7 +417,7 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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 void JNICALL
@ -441,7 +442,8 @@ CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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 jobject JNICALL
@ -462,7 +464,8 @@ CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); 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); 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)); jint i = (t->exception ? 0 : floatValue(t, r));
jfloat f; memcpy(&f, &i, 4); jfloat f; memcpy(&f, &i, 4);
return f; return f;
@ -618,7 +627,8 @@ CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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)); jlong i = (t->exception ? 0 : doubleValue(t, r));
jdouble f; memcpy(&f, &i, 4); jdouble f; memcpy(&f, &i, 4);
return f; return f;
@ -642,7 +652,7 @@ CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); 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 void JNICALL
@ -693,7 +703,7 @@ GetObjectField(Thread* t, jobject o, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, cast<object>(*o, field)); return makeLocalReference(t, cast<object>(*o, field));
} }
jboolean JNICALL jboolean JNICALL
@ -837,7 +847,7 @@ GetStaticObjectField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, arrayBody(t, classStaticTable(t, *c), field)); return makeLocalReference(t, arrayBody(t, classStaticTable(t, *c), field));
} }
jboolean JNICALL jboolean JNICALL
@ -1003,12 +1013,12 @@ NewGlobalRef(Thread* t, jobject o)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->vm->referenceLock); ACQUIRE(t, t->m->referenceLock);
t->vm->jniReferences = new (t->vm->system->allocate(sizeof(Reference))) t->m->jniReferences = new (t->m->system->allocate(sizeof(Reference)))
Reference(*o, t->vm->jniReferences); Reference(*o, t->m->jniReferences);
return &(t->vm->jniReferences->target); return &(t->m->jniReferences->target);
} }
void JNICALL void JNICALL
@ -1016,9 +1026,9 @@ DeleteGlobalRef(Thread* t, jobject o)
{ {
ENTER(t, Thread::ActiveState); 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) { if (&((*r)->target) == o) {
*r = (*r)->next; *r = (*r)->next;
break; break;
@ -1033,7 +1043,7 @@ ExceptionOccurred(Thread* t)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, t->exception); return makeLocalReference(t, t->exception);
} }
void JNICALL void JNICALL
@ -1057,7 +1067,7 @@ NewBooleanArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeBooleanArray(t, length, true)); return makeLocalReference(t, makeBooleanArray(t, length, true));
} }
jbyteArray JNICALL jbyteArray JNICALL
@ -1065,7 +1075,7 @@ NewByteArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeByteArray(t, length, true)); return makeLocalReference(t, makeByteArray(t, length, true));
} }
jcharArray JNICALL jcharArray JNICALL
@ -1073,7 +1083,7 @@ NewCharArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeCharArray(t, length, true)); return makeLocalReference(t, makeCharArray(t, length, true));
} }
jshortArray JNICALL jshortArray JNICALL
@ -1081,7 +1091,7 @@ NewShortArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeShortArray(t, length, true)); return makeLocalReference(t, makeShortArray(t, length, true));
} }
jintArray JNICALL jintArray JNICALL
@ -1089,7 +1099,7 @@ NewIntArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeIntArray(t, length, true)); return makeLocalReference(t, makeIntArray(t, length, true));
} }
jlongArray JNICALL jlongArray JNICALL
@ -1097,7 +1107,7 @@ NewLongArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeLongArray(t, length, true)); return makeLocalReference(t, makeLongArray(t, length, true));
} }
jfloatArray JNICALL jfloatArray JNICALL
@ -1105,7 +1115,7 @@ NewFloatArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeFloatArray(t, length, true)); return makeLocalReference(t, makeFloatArray(t, length, true));
} }
jdoubleArray JNICALL jdoubleArray JNICALL
@ -1113,7 +1123,7 @@ NewDoubleArray(Thread* t, jsize length)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return pushReference(t, makeDoubleArray(t, length, true)); return makeLocalReference(t, makeDoubleArray(t, length, true));
} }
jboolean* JNICALL jboolean* JNICALL
@ -1122,7 +1132,7 @@ GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean); unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
jboolean* p = static_cast<jboolean*>(t->vm->system->allocate(size)); jboolean* p = static_cast<jboolean*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &booleanArrayBody(t, *array, 0), size); memcpy(p, &booleanArrayBody(t, *array, 0), size);
} }
@ -1140,7 +1150,7 @@ GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte); unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
jbyte* p = static_cast<jbyte*>(t->vm->system->allocate(size)); jbyte* p = static_cast<jbyte*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &byteArrayBody(t, *array, 0), size); memcpy(p, &byteArrayBody(t, *array, 0), size);
} }
@ -1158,7 +1168,7 @@ GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = charArrayLength(t, *array) * sizeof(jchar); unsigned size = charArrayLength(t, *array) * sizeof(jchar);
jchar* p = static_cast<jchar*>(t->vm->system->allocate(size)); jchar* p = static_cast<jchar*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &charArrayBody(t, *array, 0), size); memcpy(p, &charArrayBody(t, *array, 0), size);
} }
@ -1176,7 +1186,7 @@ GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = shortArrayLength(t, *array) * sizeof(jshort); unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
jshort* p = static_cast<jshort*>(t->vm->system->allocate(size)); jshort* p = static_cast<jshort*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &shortArrayBody(t, *array, 0), size); memcpy(p, &shortArrayBody(t, *array, 0), size);
} }
@ -1194,7 +1204,7 @@ GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = intArrayLength(t, *array) * sizeof(jint); unsigned size = intArrayLength(t, *array) * sizeof(jint);
jint* p = static_cast<jint*>(t->vm->system->allocate(size)); jint* p = static_cast<jint*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &intArrayBody(t, *array, 0), size); memcpy(p, &intArrayBody(t, *array, 0), size);
} }
@ -1212,7 +1222,7 @@ GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = longArrayLength(t, *array) * sizeof(jlong); unsigned size = longArrayLength(t, *array) * sizeof(jlong);
jlong* p = static_cast<jlong*>(t->vm->system->allocate(size)); jlong* p = static_cast<jlong*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &longArrayBody(t, *array, 0), size); memcpy(p, &longArrayBody(t, *array, 0), size);
} }
@ -1230,7 +1240,7 @@ GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat); unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
jfloat* p = static_cast<jfloat*>(t->vm->system->allocate(size)); jfloat* p = static_cast<jfloat*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &floatArrayBody(t, *array, 0), size); memcpy(p, &floatArrayBody(t, *array, 0), size);
} }
@ -1248,7 +1258,7 @@ GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble); unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
jdouble* p = static_cast<jdouble*>(t->vm->system->allocate(size)); jdouble* p = static_cast<jdouble*>(t->m->system->allocate(size));
if (size) { if (size) {
memcpy(p, &doubleArrayBody(t, *array, 0), 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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 jint JNICALL
GetJavaVM(Thread* t, Machine** m) GetJavaVM(Thread* t, Machine** m)
{ {
*m = t->vm; *m = t->m;
return 0; return 0;
} }

View File

@ -2,7 +2,7 @@
#include "machine.h" #include "machine.h"
#include "stream.h" #include "stream.h"
#include "constants.h" #include "constants.h"
#include "run.h" #include "processor.h"
using namespace vm; using namespace vm;
@ -48,18 +48,18 @@ dispose(Thread* t, Thread* o, bool remove)
o->parent->child = 0; o->parent->child = 0;
} }
} else if (o->child) { } else if (o->child) {
t->vm->rootThread = o->child; t->m->rootThread = o->child;
if (o->peer) { if (o->peer) {
o->peer->peer = o->child->peer; o->peer->peer = o->child->peer;
o->child->peer = o->peer; o->child->peer = o->peer;
} }
} else if (o->peer) { } else if (o->peer) {
t->vm->rootThread = o->peer; t->m->rootThread = o->peer;
} else { } else {
abort(t); abort(t);
} }
assert(t, not find(t->vm->rootThread, o)); assert(t, not find(t->m->rootThread, o));
} }
o->dispose(); o->dispose();
@ -132,14 +132,9 @@ visitRoots(Thread* t, Heap::Visitor* v)
{ {
if (t->state != Thread::ZombieState) { if (t->state != Thread::ZombieState) {
v->visit(&(t->javaThread)); v->visit(&(t->javaThread));
v->visit(&(t->code));
v->visit(&(t->exception)); v->visit(&(t->exception));
for (unsigned i = 0; i < t->sp; ++i) { t->m->processor->visitObjects(t, v);
if (t->stack[i * 2] == ObjectTag) {
v->visit(t->stack + (i * 2) + 1);
}
}
for (Thread::Protector* p = t->protector; p; p = p->next) { for (Thread::Protector* p = t->protector; p; p = p->next) {
v->visit(p->p); v->visit(p->p);
@ -158,8 +153,8 @@ finalizerTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
object finalizer = *p; object finalizer = *p;
*p = finalizerNext(t, finalizer); *p = finalizerNext(t, finalizer);
finalizerNext(t, finalizer) = t->vm->finalizeQueue; finalizerNext(t, finalizer) = t->m->finalizeQueue;
t->vm->finalizeQueue = finalizer; t->m->finalizeQueue = finalizer;
} }
void void
@ -174,7 +169,7 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
jreferenceTarget(t, *p) = 0; jreferenceTarget(t, *p) = 0;
if (jreferenceQueue(t, *p) 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 // queue is reachable - add the reference
@ -205,7 +200,7 @@ referenceUnreachable(Thread* t, object* p, Heap::Visitor* v)
} }
if (jreferenceQueue(t, *p) 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 // queue is reachable - add the reference
referenceTargetUnreachable(t, p, v); referenceTargetUnreachable(t, p, v);
@ -225,7 +220,7 @@ referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v)
v->visit(p); v->visit(p);
v->visit(&jreferenceTarget(t, *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; jreferenceQueue(t, *p) = 0;
} else { } else {
v->visit(&jreferenceQueue(t, *p)); v->visit(&jreferenceQueue(t, *p));
@ -235,7 +230,7 @@ referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v)
void void
postVisit(Thread* t, Heap::Visitor* v) postVisit(Thread* t, Heap::Visitor* v)
{ {
Machine* m = t->vm; Machine* m = t->m;
for (object* p = &(m->finalizeQueue); *p; p = &(finalizerNext(t, *p))) { for (object* p = &(m->finalizeQueue); *p; p = &(finalizerNext(t, *p))) {
v->visit(p); v->visit(p);
@ -359,9 +354,9 @@ void
postCollect(Thread* t) postCollect(Thread* t)
{ {
#ifdef VM_STRESS #ifdef VM_STRESS
t->vm->system->free(t->defaultHeap); t->m->system->free(t->defaultHeap);
t->defaultHeap = static_cast<uintptr_t*> t->defaultHeap = static_cast<uintptr_t*>
(t->vm->system->allocate(Thread::HeapSizeInBytes)); (t->m->system->allocate(Thread::HeapSizeInBytes));
#endif #endif
t->heap = t->defaultHeap; t->heap = t->defaultHeap;
@ -369,7 +364,7 @@ postCollect(Thread* t)
t->heapIndex = 0; t->heapIndex = 0;
if (t->large) { if (t->large) {
t->vm->system->free(t->large); t->m->system->free(t->large);
t->large = 0; t->large = 0;
} }
@ -588,7 +583,7 @@ parsePool(Thread* t, Stream& s)
for (unsigned i = 0; i < poolCount; ++i) { for (unsigned i = 0; i < poolCount; ++i) {
object o = arrayBody(t, pool, i); object o = arrayBody(t, pool, i);
if (o and objectClass(t, o) 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)) { switch (intArrayBody(t, o, 0)) {
case CONSTANT_Class: { case CONSTANT_Class: {
@ -617,7 +612,7 @@ parsePool(Thread* t, Stream& s)
for (unsigned i = 0; i < poolCount; ++i) { for (unsigned i = 0; i < poolCount; ++i) {
object o = arrayBody(t, pool, i); object o = arrayBody(t, pool, i);
if (o and objectClass(t, o) 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)) { switch (intArrayBody(t, o, 0)) {
case CONSTANT_Fieldref: case CONSTANT_Fieldref:
@ -1183,15 +1178,15 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec,
dimensions, dimensions,
2 * BytesPerWord, 2 * BytesPerWord,
BytesPerWord, BytesPerWord,
classObjectMask(t, arrayBody(t, t->vm->types, Machine::ArrayType)), classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)),
spec, spec,
arrayBody(t, t->vm->types, Machine::JobjectType), arrayBody(t, t->m->types, Machine::JobjectType),
0, 0,
classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)), classVirtualTable(t, arrayBody(t, t->m->types, Machine::JobjectType)),
0, 0,
0, 0,
elementClass, elementClass,
t->vm->loader); t->m->loader);
} }
object object
@ -1232,7 +1227,7 @@ makeArrayClass(Thread* t, object spec)
} }
object elementClass = hashMapFind object elementClass = hashMapFind
(t, t->vm->bootstrapClassMap, elementSpec, byteArrayHash, byteArrayEqual); (t, t->m->bootstrapClassMap, elementSpec, byteArrayHash, byteArrayEqual);
if (elementClass == 0) { if (elementClass == 0) {
elementClass = resolveClass(t, elementSpec); elementClass = resolveClass(t, elementSpec);
@ -1245,7 +1240,7 @@ makeArrayClass(Thread* t, object spec)
void void
removeMonitor(Thread* t, object o) 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); assert(t, p);
@ -1261,18 +1256,39 @@ removeMonitor(Thread* t, object o)
void void
removeString(Thread* t, object o) 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
namespace vm { namespace vm {
Machine::Machine(System* system, Heap* heap, Finder* finder): Machine::Machine(System* system, Heap* heap, Finder* finder,
Processor* processor):
vtable(&javaVMVTable), vtable(&javaVMVTable),
system(system), system(system),
heap(heap), heap(heap),
finder(finder), finder(finder),
processor(processor),
rootThread(0), rootThread(0),
exclusive(0), exclusive(0),
jniReferences(0), jniReferences(0),
@ -1333,7 +1349,7 @@ Machine::dispose()
Thread::Thread(Machine* m, object javaThread, Thread* parent): Thread::Thread(Machine* m, object javaThread, Thread* parent):
vtable(&(m->jniEnvVTable)), vtable(&(m->jniEnvVTable)),
vm(m), m(m),
parent(parent), parent(parent),
peer((parent ? parent->child : 0)), peer((parent ? parent->child : 0)),
child(0), child(0),
@ -1341,12 +1357,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
criticalLevel(0), criticalLevel(0),
systemThread(0), systemThread(0),
javaThread(javaThread), javaThread(javaThread),
code(0),
exception(0), exception(0),
large(0), large(0),
ip(0),
sp(0),
frame(-1),
heapIndex(0), heapIndex(0),
heapOffset(0), heapOffset(0),
protector(0), protector(0),
@ -1370,17 +1382,17 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
Thread* t = this; Thread* t = this;
t->vm->loader = allocate(t, sizeof(void*) * 3); t->m->loader = allocate(t, sizeof(void*) * 3);
memset(t->vm->loader, 0, sizeof(void*) * 2); memset(t->m->loader, 0, sizeof(void*) * 2);
#include "type-initializations.cpp" #include "type-initializations.cpp"
object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType); object arrayClass = arrayBody(t, t->m->types, Machine::ArrayType);
set(t, cast<object>(t->vm->types, 0), arrayClass); set(t, cast<object>(t->m->types, 0), arrayClass);
object loaderClass = arrayBody object loaderClass = arrayBody
(t, t->vm->types, Machine::SystemClassLoaderType); (t, t->m->types, Machine::SystemClassLoaderType);
set(t, cast<object>(t->vm->loader, 0), loaderClass); set(t, cast<object>(t->m->loader, 0), loaderClass);
object objectClass = arrayBody(t, m->types, Machine::JobjectType); object objectClass = arrayBody(t, m->types, Machine::JobjectType);
@ -1453,7 +1465,7 @@ Thread::exit()
{ {
enter(this, Thread::ExclusiveState); enter(this, Thread::ExclusiveState);
if (vm->liveCount == 1) { if (m->liveCount == 1) {
vm::exit(this); vm::exit(this);
} else { } else {
enter(this, Thread::ZombieState); enter(this, Thread::ZombieState);
@ -1465,7 +1477,7 @@ void
Thread::dispose() Thread::dispose()
{ {
if (large) { if (large) {
vm->system->free(large); m->system->free(large);
large = 0; large = 0;
} }
@ -1475,11 +1487,11 @@ Thread::dispose()
} }
#ifdef VM_STRESS #ifdef VM_STRESS
vm->system->free(heap); m->system->free(heap);
heap = 0; heap = 0;
#endif // VM_STRESS #endif // VM_STRESS
vm->system->free(this); m->system->free(this);
} }
void void
@ -1487,9 +1499,9 @@ exit(Thread* t)
{ {
enter(t, Thread::ExitState); 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; object f = *p;
*p = finalizerNext(t, *p); *p = finalizerNext(t, *p);
@ -1497,7 +1509,7 @@ exit(Thread* t)
(t, finalizerTarget(t, f)); (t, finalizerTarget(t, f));
} }
for (object* p = &(t->vm->tenuredFinalizers); *p;) { for (object* p = &(t->m->tenuredFinalizers); *p;) {
object f = *p; object f = *p;
*p = finalizerNext(t, *p); *p = finalizerNext(t, *p);
@ -1505,7 +1517,7 @@ exit(Thread* t)
(t, finalizerTarget(t, f)); (t, finalizerTarget(t, f));
} }
disposeAll(t, t->vm->rootThread); disposeAll(t, t->m->rootThread);
} }
void void
@ -1520,22 +1532,22 @@ enter(Thread* t, Thread::State s)
return; return;
} }
ACQUIRE_RAW(t, t->vm->stateLock); ACQUIRE_RAW(t, t->m->stateLock);
switch (s) { switch (s) {
case Thread::ExclusiveState: { case Thread::ExclusiveState: {
assert(t, t->state == Thread::ActiveState); assert(t, t->state == Thread::ActiveState);
while (t->vm->exclusive) { while (t->m->exclusive) {
// another thread got here first. // another thread got here first.
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
} }
t->state = Thread::ExclusiveState; t->state = Thread::ExclusiveState;
t->vm->exclusive = t; t->m->exclusive = t;
while (t->vm->activeCount > 1) { while (t->m->activeCount > 1) {
t->vm->stateLock->wait(t->systemThread, 0); t->m->stateLock->wait(t->systemThread, 0);
} }
} break; } break;
@ -1543,8 +1555,8 @@ enter(Thread* t, Thread::State s)
case Thread::ZombieState: { case Thread::ZombieState: {
switch (t->state) { switch (t->state) {
case Thread::ExclusiveState: { case Thread::ExclusiveState: {
assert(t, t->vm->exclusive == t); assert(t, t->m->exclusive == t);
t->vm->exclusive = 0; t->m->exclusive = 0;
} break; } break;
case Thread::ActiveState: break; case Thread::ActiveState: break;
@ -1552,38 +1564,38 @@ enter(Thread* t, Thread::State s)
default: abort(t); default: abort(t);
} }
assert(t, t->vm->activeCount > 0); assert(t, t->m->activeCount > 0);
-- t->vm->activeCount; -- t->m->activeCount;
if (s == Thread::ZombieState) { if (s == Thread::ZombieState) {
assert(t, t->vm->liveCount > 0); assert(t, t->m->liveCount > 0);
-- t->vm->liveCount; -- t->m->liveCount;
} }
t->state = s; t->state = s;
t->vm->stateLock->notifyAll(t->systemThread); t->m->stateLock->notifyAll(t->systemThread);
} break; } break;
case Thread::ActiveState: { case Thread::ActiveState: {
switch (t->state) { switch (t->state) {
case Thread::ExclusiveState: { case Thread::ExclusiveState: {
assert(t, t->vm->exclusive == t); assert(t, t->m->exclusive == t);
t->state = s; t->state = s;
t->vm->exclusive = 0; t->m->exclusive = 0;
t->vm->stateLock->notifyAll(t->systemThread); t->m->stateLock->notifyAll(t->systemThread);
} break; } break;
case Thread::NoState: case Thread::NoState:
case Thread::IdleState: { case Thread::IdleState: {
while (t->vm->exclusive) { while (t->m->exclusive) {
t->vm->stateLock->wait(t->systemThread, 0); t->m->stateLock->wait(t->systemThread, 0);
} }
++ t->vm->activeCount; ++ t->m->activeCount;
if (t->state == Thread::NoState) { if (t->state == Thread::NoState) {
++ t->vm->liveCount; ++ t->m->liveCount;
} }
t->state = s; t->state = s;
} break; } break;
@ -1595,8 +1607,8 @@ enter(Thread* t, Thread::State s)
case Thread::ExitState: { case Thread::ExitState: {
switch (t->state) { switch (t->state) {
case Thread::ExclusiveState: { case Thread::ExclusiveState: {
assert(t, t->vm->exclusive == t); assert(t, t->m->exclusive == t);
t->vm->exclusive = 0; t->m->exclusive = 0;
} break; } break;
case Thread::ActiveState: break; case Thread::ActiveState: break;
@ -1604,13 +1616,13 @@ enter(Thread* t, Thread::State s)
default: abort(t); default: abort(t);
} }
assert(t, t->vm->activeCount > 0); assert(t, t->m->activeCount > 0);
-- t->vm->activeCount; -- t->m->activeCount;
t->state = s; t->state = s;
while (t->vm->liveCount > 1) { while (t->m->liveCount > 1) {
t->vm->stateLock->wait(t->systemThread, 0); t->m->stateLock->wait(t->systemThread, 0);
} }
} break; } break;
@ -1625,9 +1637,9 @@ allocate2(Thread* t, unsigned sizeInBytes)
return allocateLarge(t, 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 // another thread wants to enter the exclusive state, either for a
// collection or some other reason. We give it a chance here. // collection or some other reason. We give it a chance here.
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
@ -1637,11 +1649,11 @@ allocate2(Thread* t, unsigned sizeInBytes)
>= Thread::HeapSizeInWords) >= Thread::HeapSizeInWords)
{ {
t->heap = 0; 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<uintptr_t*> t->heap = static_cast<uintptr_t*>
(t->vm->system->tryAllocate(Thread::HeapSizeInBytes)); (t->m->system->tryAllocate(Thread::HeapSizeInBytes));
if (t->heap) { if (t->heap) {
t->vm->heapPool[t->vm->heapPoolIndex++] = t->heap; t->m->heapPool[t->m->heapPoolIndex++] = t->heap;
t->heapOffset += t->heapIndex; t->heapOffset += t->heapIndex;
t->heapIndex = 0; t->heapIndex = 0;
} }
@ -1673,10 +1685,10 @@ make(Thread* t, object class_)
if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) { if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) {
PROTECT(t, instance); PROTECT(t, instance);
ACQUIRE(t, t->vm->referenceLock); ACQUIRE(t, t->m->referenceLock);
jreferenceNextUnsafe(t, instance) = t->vm->weakReferences; jreferenceNextUnsafe(t, instance) = t->m->weakReferences;
t->vm->weakReferences = instance; t->m->weakReferences = instance;
} }
return instance; return instance;
@ -1709,7 +1721,7 @@ stringChars(Thread* t, object string, char* chars)
{ {
object data = stringData(t, string); object data = stringData(t, string);
if (objectClass(t, data) if (objectClass(t, data)
== arrayBody(t, t->vm->types, Machine::ByteArrayType)) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{ {
memcpy(chars, memcpy(chars,
&byteArrayBody(t, data, stringOffset(t, string)), &byteArrayBody(t, data, stringOffset(t, string)),
@ -1865,7 +1877,7 @@ hashMapFindNode(Thread* t, object map, object key,
bool (*equal)(Thread*, object, object)) bool (*equal)(Thread*, object, object))
{ {
bool weak = objectClass(t, map) 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 array = hashMapArray(t, map);
if (array) { if (array) {
@ -1905,7 +1917,7 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
if (oldArray) { if (oldArray) {
bool weak = objectClass(t, map) 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) { for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) {
object next; object next;
@ -1934,7 +1946,7 @@ hashMapInsert(Thread* t, object map, object key, object value,
uint32_t (*hash)(Thread*, object)) uint32_t (*hash)(Thread*, object))
{ {
bool weak = objectClass(t, map) 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 array = hashMapArray(t, map);
PROTECT(t, array); PROTECT(t, array);
@ -1958,8 +1970,8 @@ hashMapInsert(Thread* t, object map, object key, object value,
object r = makeWeakReference(t, 0, 0, 0, 0); object r = makeWeakReference(t, 0, 0, 0, 0);
jreferenceTarget(t, r) = key; jreferenceTarget(t, r) = key;
jreferenceNext(t, r) = t->vm->weakReferences; jreferenceNext(t, r) = t->m->weakReferences;
key = t->vm->weakReferences = r; key = t->m->weakReferences = r;
} }
object n = makeTriple(t, key, value, arrayBody(t, array, index)); 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 (*equal)(Thread*, object, object))
{ {
bool weak = objectClass(t, map) 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 array = hashMapArray(t, map);
object o = 0; object o = 0;
@ -2004,26 +2016,6 @@ hashMapRemove(Thread* t, object map, object key,
return o; 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 object
hashMapIterator(Thread* t, object map) hashMapIterator(Thread* t, object map)
{ {
@ -2186,9 +2178,9 @@ object
findLoadedClass(Thread* t, object spec) findLoadedClass(Thread* t, object spec)
{ {
PROTECT(t, 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); spec, byteArrayHash, byteArrayEqual);
} }
@ -2234,7 +2226,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
0, // fields 0, // fields
0, // methods 0, // methods
0, // static table 0, // static table
t->vm->loader); t->m->loader);
PROTECT(t, class_); PROTECT(t, class_);
unsigned super = s.read2(); unsigned super = s.read2();
@ -2264,14 +2256,14 @@ object
resolveClass(Thread* t, object spec) resolveClass(Thread* t, object spec)
{ {
PROTECT(t, 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); spec, byteArrayHash, byteArrayEqual);
if (class_ == 0) { if (class_ == 0) {
if (byteArrayBody(t, spec, 0) == '[') { if (byteArrayBody(t, spec, 0) == '[') {
class_ = hashMapFind class_ = hashMapFind
(t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); (t, t->m->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual);
if (class_ == 0) { if (class_ == 0) {
class_ = makeArrayClass(t, spec); 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, &byteArrayBody(t, spec, 0), byteArrayLength(t, spec) - 1);
memcpy(file + byteArrayLength(t, spec) - 1, ".class", 7); 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 (region) {
if (Verbose) { if (Verbose) {
@ -2298,7 +2290,7 @@ resolveClass(Thread* t, object spec)
} }
object bootstrapClass = hashMapFind object bootstrapClass = hashMapFind
(t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual); (t, t->m->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual);
if (bootstrapClass) { if (bootstrapClass) {
PROTECT(t, bootstrapClass); PROTECT(t, bootstrapClass);
@ -2313,7 +2305,7 @@ resolveClass(Thread* t, object spec)
if (class_) { if (class_) {
PROTECT(t, class_); PROTECT(t, class_);
hashMapInsert(t, systemClassLoaderMap(t, t->vm->loader), hashMapInsert(t, systemClassLoaderMap(t, t->m->loader),
spec, class_, byteArrayHash); spec, class_, byteArrayHash);
} else if (t->exception == 0) { } else if (t->exception == 0) {
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
@ -2324,6 +2316,27 @@ resolveClass(Thread* t, object spec)
return class_; 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 object
resolveObjectArrayClass(Thread* t, object elementSpec) resolveObjectArrayClass(Thread* t, object elementSpec)
{ {
@ -2444,18 +2457,18 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
{ {
PROTECT(t, target); PROTECT(t, target);
ACQUIRE(t, t->vm->referenceLock); ACQUIRE(t, t->m->referenceLock);
object f = makeFinalizer(t, 0, reinterpret_cast<void*>(finalize), 0); object f = makeFinalizer(t, 0, reinterpret_cast<void*>(finalize), 0);
finalizerTarget(t, f) = target; finalizerTarget(t, f) = target;
finalizerNext(t, f) = t->vm->finalizers; finalizerNext(t, f) = t->m->finalizers;
t->vm->finalizers = f; t->m->finalizers = f;
} }
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o) 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 (p) {
if (DebugMonitors) { if (DebugMonitors) {
@ -2471,8 +2484,8 @@ objectMonitor(Thread* t, object o)
ENTER(t, Thread::ExclusiveState); ENTER(t, Thread::ExclusiveState);
System::Monitor* m; System::Monitor* m;
System::Status s = t->vm->system->make(&m); System::Status s = t->m->system->make(&m);
expect(t, t->vm->system->success(s)); expect(t, t->m->system->success(s));
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "made monitor %p for object %x\n", fprintf(stderr, "made monitor %p for object %x\n",
@ -2481,7 +2494,7 @@ objectMonitor(Thread* t, object o)
} }
p = makePointer(t, m); p = makePointer(t, m);
hashMapInsert(t, t->vm->monitorMap, o, p, objectHash); hashMapInsert(t, t->m->monitorMap, o, p, objectHash);
addFinalizer(t, o, removeMonitor); addFinalizer(t, o, removeMonitor);
@ -2494,13 +2507,13 @@ intern(Thread* t, object s)
{ {
PROTECT(t, 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) { if (n) {
return jreferenceTarget(t, tripleFirst(t, n)); return jreferenceTarget(t, tripleFirst(t, n));
} else { } else {
hashMapInsert(t, t->vm->stringMap, s, 0, stringHash); hashMapInsert(t, t->m->stringMap, s, 0, stringHash);
addFinalizer(t, s, removeString); addFinalizer(t, s, removeString);
return s; return s;
} }
@ -2509,7 +2522,7 @@ intern(Thread* t, object s)
void void
collect(Thread* t, Heap::CollectionType type) collect(Thread* t, Heap::CollectionType type)
{ {
Machine* m = t->vm; Machine* m = t->m;
class Client: public Heap::Client { class Client: public Heap::Client {
public: 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, &copy);
}
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 void
noop() noop()
{ } { }

View File

@ -5,6 +5,7 @@
#include "system.h" #include "system.h"
#include "heap.h" #include "heap.h"
#include "finder.h" #include "finder.h"
#include "processor.h"
#define JNICALL #define JNICALL
@ -65,13 +66,6 @@ const unsigned PrimitiveFlag = 1 << 4;
// method flags: // method flags:
const unsigned ClassInitFlag = 1 << 0; const unsigned ClassInitFlag = 1 << 0;
class Machine;
class Thread;
struct Object { };
typedef Object* object;
typedef Machine JavaVM; typedef Machine JavaVM;
typedef Thread JNIEnv; typedef Thread JNIEnv;
@ -1101,7 +1095,7 @@ class Machine {
#include "type-enums.cpp" #include "type-enums.cpp"
}; };
Machine(System* system, Heap* heap, Finder* finder); Machine(System* system, Heap* heap, Finder* finder, Processor* processor);
~Machine() { ~Machine() {
dispose(); dispose();
@ -1115,6 +1109,7 @@ class Machine {
System* system; System* system;
Heap* heap; Heap* heap;
Finder* finder; Finder* finder;
Processor* processor;
Thread* rootThread; Thread* rootThread;
Thread* exclusive; Thread* exclusive;
Reference* jniReferences; Reference* jniReferences;
@ -1144,13 +1139,6 @@ class Machine {
unsigned heapPoolIndex; 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 void
printTrace(Thread* t, object exception); printTrace(Thread* t, object exception);
@ -1193,9 +1181,10 @@ class Thread {
} }
virtual void run() { 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) { if (t->exception) {
printTrace(t, t->exception); printTrace(t, t->exception);
@ -1216,10 +1205,7 @@ class Thread {
}; };
static const unsigned HeapSizeInBytes = 64 * 1024; static const unsigned HeapSizeInBytes = 64 * 1024;
static const unsigned StackSizeInBytes = 64 * 1024;
static const unsigned HeapSizeInWords = HeapSizeInBytes / BytesPerWord; static const unsigned HeapSizeInWords = HeapSizeInBytes / BytesPerWord;
static const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord;
Thread(Machine* m, object javaThread, Thread* parent); Thread(Machine* m, object javaThread, Thread* parent);
@ -1227,7 +1213,7 @@ class Thread {
void dispose(); void dispose();
JNIEnvVTable* vtable; JNIEnvVTable* vtable;
Machine* vm; Machine* m;
Thread* parent; Thread* parent;
Thread* peer; Thread* peer;
Thread* child; Thread* child;
@ -1235,12 +1221,8 @@ class Thread {
unsigned criticalLevel; unsigned criticalLevel;
System::Thread* systemThread; System::Thread* systemThread;
object javaThread; object javaThread;
object code;
object exception; object exception;
object large; object large;
unsigned ip;
unsigned sp;
int frame;
unsigned heapIndex; unsigned heapIndex;
unsigned heapOffset; unsigned heapOffset;
Protector* protector; Protector* protector;
@ -1253,7 +1235,6 @@ class Thread {
uintptr_t* heap; uintptr_t* heap;
uintptr_t defaultHeap[HeapSizeInWords]; uintptr_t defaultHeap[HeapSizeInWords];
#endif // not VM_STRESS #endif // not VM_STRESS
uintptr_t stack[StackSizeInWords];
}; };
inline object inline object
@ -1362,27 +1343,27 @@ class RawMonitorResource {
inline void NO_RETURN inline void NO_RETURN
abort(Thread* t) abort(Thread* t)
{ {
abort(t->vm->system); abort(t->m->system);
} }
#ifndef NDEBUG #ifndef NDEBUG
inline void inline void
assert(Thread* t, bool v) assert(Thread* t, bool v)
{ {
assert(t->vm->system, v); assert(t->m->system, v);
} }
#endif // not NDEBUG #endif // not NDEBUG
inline void inline void
expect(Thread* t, bool v) expect(Thread* t, bool v)
{ {
expect(t->vm->system, v); expect(t->m->system, v);
} }
inline object inline object
allocateLarge(Thread* t, unsigned sizeInBytes) allocateLarge(Thread* t, unsigned sizeInBytes)
{ {
return t->large = static_cast<object>(t->vm->system->allocate(sizeInBytes)); return t->large = static_cast<object>(t->m->system->allocate(sizeInBytes));
} }
inline object inline object
@ -1403,7 +1384,7 @@ allocate(Thread* t, unsigned sizeInBytes)
if (UNLIKELY(t->heapIndex + ceiling(sizeInBytes, BytesPerWord) if (UNLIKELY(t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
>= Thread::HeapSizeInWords >= Thread::HeapSizeInWords
or t->vm->exclusive)) or t->m->exclusive))
{ {
return allocate2(t, sizeInBytes); return allocate2(t, sizeInBytes);
} else { } else {
@ -1414,9 +1395,9 @@ allocate(Thread* t, unsigned sizeInBytes)
inline void inline void
mark(Thread* t, object& target) mark(Thread* t, object& target)
{ {
if (t->vm->heap->needsMark(reinterpret_cast<void**>(&target))) { if (t->m->heap->needsMark(reinterpret_cast<void**>(&target))) {
ACQUIRE_RAW(t, t->vm->heapLock); ACQUIRE_RAW(t, t->m->heapLock);
t->vm->heap->mark(reinterpret_cast<void**>(&target)); t->m->heap->mark(reinterpret_cast<void**>(&target));
} }
} }
@ -1442,10 +1423,14 @@ arrayBodyUnsafe(Thread*, object, unsigned);
#include "type-declarations.cpp" #include "type-declarations.cpp"
object object
makeTrace(Thread* t, int frame); makeTrace(Thread* t, FrameIterator* it);
object inline object
makeTrace(Thread* t); makeTrace(Thread* t)
{
FrameIterator it; t->m->processor->start(t, &it);
return makeTrace(t, &it);
}
inline object inline object
makeRuntimeException(Thread* t, object message) makeRuntimeException(Thread* t, object message)
@ -1595,268 +1580,6 @@ classInitializer(Thread* t, object class_);
object object
frameMethod(Thread* t, int frame); 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<uintptr_t>(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<object>(t->stack[((t->sp - 1) * 2) + 1]),
t->sp - 1);
}
assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag);
return reinterpret_cast<object>(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<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32)
| static_cast<uint64_t>(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<object>(t->stack[(index * 2) + 1]),
index);
}
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == ObjectTag);
return *reinterpret_cast<object*>(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<uint64_t>(t->stack[(index * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]),
index);
}
return (static_cast<uint64_t>(peekInt(t, index)) << 32)
| static_cast<uint64_t>(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<uintptr_t>(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<object*>(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 inline unsigned
baseSize(Thread* t, object o, object class_) baseSize(Thread* t, object o, object class_)
{ {
@ -1897,8 +1620,8 @@ markHashTaken(Thread* t, object o)
assert(t, not objectExtended(t, o)); assert(t, not objectExtended(t, o));
cast<uintptr_t>(o, 0) |= HashTakenMark; cast<uintptr_t>(o, 0) |= HashTakenMark;
ACQUIRE_RAW(t, t->vm->heapLock); ACQUIRE_RAW(t, t->m->heapLock);
t->vm->heap->pad(o, 1); t->m->heap->pad(o, 1);
} }
inline uint32_t inline uint32_t
@ -1951,7 +1674,7 @@ stringHash(Thread* t, object s)
if (stringHashCode(t, s) == 0 and stringLength(t, s)) { if (stringHashCode(t, s) == 0 and stringLength(t, s)) {
object data = stringData(t, s); object data = stringData(t, s);
if (objectClass(t, data) if (objectClass(t, data)
== arrayBody(t, t->vm->types, Machine::ByteArrayType)) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{ {
stringHashCode(t, s) = hash stringHashCode(t, s) = hash
(&byteArrayBody(t, data, stringOffset(t, s)), stringLength(t, s)); (&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); object data = stringData(t, s);
if (objectClass(t, data) if (objectClass(t, data)
== arrayBody(t, t->vm->types, Machine::ByteArrayType)) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{ {
return byteArrayBody(t, data, i); return byteArrayBody(t, data, i);
} else { } else {
@ -2114,6 +1837,10 @@ parseClass(Thread* t, const uint8_t* data, unsigned length);
object object
resolveClass(Thread* t, object spec); resolveClass(Thread* t, object spec);
object
resolveMethod(Thread* t, const char* className, const char* methodName,
const char* methodSpec);
object object
resolveObjectArrayClass(Thread* t, object elementSpec); resolveObjectArrayClass(Thread* t, object elementSpec);
@ -2122,14 +1849,14 @@ initClass(Thread* t, object c)
{ {
PROTECT(t, c); PROTECT(t, c);
acquire(t, t->vm->classLock); acquire(t, t->m->classLock);
if (classVmFlags(t, c) & NeedInitFlag if (classVmFlags(t, c) & NeedInitFlag
and (classVmFlags(t, c) & InitFlag) == 0) and (classVmFlags(t, c) & InitFlag) == 0)
{ {
classVmFlags(t, c) |= InitFlag; classVmFlags(t, c) |= InitFlag;
run(t, classInitializer(t, c), 0); t->m->processor->invoke(t, classInitializer(t, c), 0);
} else { } 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, classArrayElementSize(t, objectClass(t, array)) == BytesPerWord);
assert(t, classObjectMask(t, objectClass(t, array)) assert(t, classObjectMask(t, objectClass(t, array))
== classObjectMask(t, arrayBody == classObjectMask(t, arrayBody
(t, t->vm->types, Machine::ArrayType))); (t, t->m->types, Machine::ArrayType)));
return cast<object>(array, (2 + index) * BytesPerWord); return cast<object>(array, (2 + index) * BytesPerWord);
} }
@ -2323,6 +2050,16 @@ intern(Thread* t, object s);
void void
exit(Thread* t); 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 } // namespace vm
#endif//MACHINE_H #endif//MACHINE_H

View File

@ -2,7 +2,8 @@
#include "system.h" #include "system.h"
#include "heap.h" #include "heap.h"
#include "finder.h" #include "finder.h"
#include "run.h" #include "processor.h"
#include "machine.h"
using namespace vm; using namespace vm;
@ -15,9 +16,11 @@ run(unsigned heapSize, const char* path, const char* class_, int argc,
System* s = makeSystem(heapSize); System* s = makeSystem(heapSize);
Finder* f = makeFinder(s, path); Finder* f = makeFinder(s, path);
Heap* heap = makeHeap(s); 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(); heap->dispose();
f->dispose(); f->dispose();
s->dispose(); s->dispose();

96
src/processor.h Normal file
View File

@ -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

View File

@ -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

View File

@ -1022,7 +1022,7 @@ writeSubtypeAssertions(Output* out, Object* o)
for (Object* p = typeSubtypes(o); p; p = cdr(p)) { for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
Object* st = car(p); Object* st = car(p);
out->write(" or objectClass(t, o) == arrayBodyUnsafe"); 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(capitalize(typeName(st)));
out->write("Type)"); out->write("Type)");
writeSubtypeAssertions(out, st); writeSubtypeAssertions(out, st);
@ -1061,9 +1061,9 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
if (unsafe) { if (unsafe) {
out->write(" assert(t, true);"); out->write(" assert(t, true);");
} else { } 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("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(capitalize(::typeName(memberOwner(member))));
out->write("Type)"); out->write("Type)");
writeSubtypeAssertions(out, memberOwner(member)); writeSubtypeAssertions(out, memberOwner(member));
@ -1347,7 +1347,7 @@ writeConstructors(Output* out, Object* declarations)
out->write(");\n"); out->write(");\n");
out->write(" cast<object>(o, 0) "); out->write(" cast<object>(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(capitalize(typeName(o)));
out->write("Type);\n"); out->write("Type);\n");
@ -1502,7 +1502,7 @@ writeInitialization(Output* out, Object* type)
} }
if (typeJavaName(type) and typeSuper(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(capitalize(typeName(typeSuper(type))));
out->write("Type);\n"); out->write("Type);\n");
} else { } else {
@ -1514,9 +1514,9 @@ writeInitialization(Output* out, Object* type)
out->write(typeFixedSize(type)); out->write(typeFixedSize(type));
out->write(", "); out->write(", ");
out->write(typeArrayElementSize(type)); 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(capitalize(typeName(type)));
out->write("Type), class_);\n"); out->write("Type), class_);\n");
@ -1566,14 +1566,14 @@ writeInitializations(Output* out, Object* declarations)
{ {
unsigned count = typeCount(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(count);
out->write(" * sizeof(void*)) + sizeof(uintptr_t) + sizeof(void*)));\n"); out->write(" * sizeof(void*)) + sizeof(uintptr_t) + sizeof(void*)));\n");
out->write("cast<object>(t->vm->types, 0) = 0;\n"); out->write("cast<object>(t->m->types, 0) = 0;\n");
out->write("arrayLength(t, t->vm->types) = "); out->write("arrayLength(t, t->m->types) = ");
out->write(count); out->write(count);
out->write(";\n"); 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(count);
out->write(" * sizeof(void*));\n\n"); out->write(" * sizeof(void*));\n\n");
@ -1596,13 +1596,13 @@ writeJavaInitialization(Output* out, Object* type)
out->write(typeJavaName(type)); out->write(typeJavaName(type));
out->write("\");\n"); 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(capitalize(typeName(type)));
out->write("Type);\n"); out->write("Type);\n");
out->write(" set(t, className(t, class_), name);\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("name, class_, byteArrayHash);\n");
out->write("}\n\n"); out->write("}\n\n");

7
test/Instructions.java Normal file
View File

@ -0,0 +1,7 @@
public class Instructions {
public static void main(String[] args) {
int a = 2;
int b = 2;
int c = a + b;
}
}