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

View File

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

View File

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

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

View File

@ -1,6 +1,6 @@
#include "jnienv.h"
#include "machine.h"
#include "run.h"
#include "processor.h"
#include "constants.h"
using namespace vm;
@ -15,7 +15,7 @@ AttachCurrentThread(Machine* m, Thread** t, void*)
{
*t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) {
*t = new (m->system->allocate(sizeof(Thread))) Thread(m, 0, m->rootThread);
*t = m->processor->makeThread(m, 0, m->rootThread);
m->localThread->set(*t);
}
@ -63,7 +63,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
char* chars = static_cast<char*>
(t->vm->system->allocate(stringLength(t, *s) + 1));
(t->m->system->allocate(stringLength(t, *s) + 1));
stringChars(t, *s, chars);
if (isCopy) *isCopy = true;
@ -73,7 +73,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
void JNICALL
ReleaseStringUTFChars(Thread* t, jstring, const char* chars)
{
t->vm->system->free(chars);
t->m->system->free(chars);
}
jstring JNICALL
@ -81,7 +81,7 @@ NewStringUTF(Thread* t, const char* chars)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeString(t, "%s", chars));
return makeLocalReference(t, makeString(t, "%s", chars));
}
jclass JNICALL
@ -92,7 +92,7 @@ FindClass(Thread* t, const char* name)
object n = makeByteArray(t, strlen(name) + 1, false);
memcpy(&byteArrayBody(t, n, 0), name, byteArrayLength(t, n));
return pushReference(t, resolveClass(t, n));
return makeLocalReference(t, resolveClass(t, n));
}
jint JNICALL
@ -122,9 +122,9 @@ ThrowNew(Thread* t, jclass c, const char* message)
}
void JNICALL
DeleteLocalRef(Thread*, jobject)
DeleteLocalRef(Thread* t, jobject r)
{
// do nothing
disposeLocalReference(t, r);
}
jboolean JNICALL
@ -138,7 +138,7 @@ GetObjectClass(Thread* t, jobject o)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, objectClass(t, *o));
return makeLocalReference(t, objectClass(t, *o));
}
jboolean JNICALL
@ -172,18 +172,18 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec)
if (classFlags(t, *c) & ACC_INTERFACE) {
PROTECT(t, method);
ACQUIRE(t, t->vm->referenceLock);
ACQUIRE(t, t->m->referenceLock);
for (unsigned i = 0; i < vectorSize(t, t->vm->jniInterfaceTable); ++i) {
if (method == vectorBody(t, t->vm->jniInterfaceTable, i)) {
for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) {
if (method == vectorBody(t, t->m->jniInterfaceTable, i)) {
return i;
}
}
t->vm->jniInterfaceTable
= vectorAppend(t, t->vm->jniInterfaceTable, method);
t->m->jniInterfaceTable
= vectorAppend(t, t->m->jniInterfaceTable, method);
return (vectorSize(t, t->vm->jniInterfaceTable) - 1) | InterfaceMethodID;
return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID;
} else {
return methodOffset(t, method) + 1;
}
@ -204,7 +204,7 @@ inline object
getMethod(Thread* t, object o, jmethodID m)
{
if (m & InterfaceMethodID) {
return vectorBody(t, t->vm->jniInterfaceTable, m & (~InterfaceMethodID));
return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID));
} else {
return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1);
}
@ -215,7 +215,8 @@ CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, runv(t, getMethod(t, *o, m), *o, true, a));
return makeLocalReference(t, t->m->processor->invokeList
(t, getMethod(t, *o, m), *o, true, a));
}
jobject JNICALL
@ -236,7 +237,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : booleanValue(t, r));
}
@ -258,7 +259,7 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : byteValue(t, r));
}
@ -280,7 +281,7 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : charValue(t, r));
}
@ -302,7 +303,7 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : shortValue(t, r));
}
@ -324,7 +325,7 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : intValue(t, r));
}
@ -346,7 +347,7 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
return (t->exception ? 0 : longValue(t, r));
}
@ -368,7 +369,7 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
jint i = (t->exception ? 0 : floatValue(t, r));
jfloat f; memcpy(&f, &i, 4);
return f;
@ -392,7 +393,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getMethod(t, *o, m), *o, true, a);
object r = t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
jlong i = (t->exception ? 0 : doubleValue(t, r));
jdouble f; memcpy(&f, &i, 4);
return f;
@ -416,7 +417,7 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
runv(t, getMethod(t, *o, m), *o, true, a);
t->m->processor->invokeList(t, getMethod(t, *o, m), *o, true, a);
}
void JNICALL
@ -441,7 +442,8 @@ CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, runv(t, getStaticMethod(t, *c, m), 0, true, a));
return makeLocalReference(t, t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a));
}
jobject JNICALL
@ -462,7 +464,8 @@ CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : booleanValue(t, r));
}
@ -484,7 +487,8 @@ CallStaticByteMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : byteValue(t, r));
}
@ -506,7 +510,8 @@ CallStaticCharMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : charValue(t, r));
}
@ -528,7 +533,8 @@ CallStaticShortMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : shortValue(t, r));
}
@ -550,7 +556,8 @@ CallStaticIntMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : intValue(t, r));
}
@ -572,7 +579,8 @@ CallStaticLongMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
return (t->exception ? 0 : longValue(t, r));
}
@ -594,7 +602,8 @@ CallStaticFloatMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
jint i = (t->exception ? 0 : floatValue(t, r));
jfloat f; memcpy(&f, &i, 4);
return f;
@ -618,7 +627,8 @@ CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
object r = runv(t, getStaticMethod(t, *c, m), 0, true, a);
object r = t->m->processor->invokeList
(t, getStaticMethod(t, *c, m), 0, true, a);
jlong i = (t->exception ? 0 : doubleValue(t, r));
jdouble f; memcpy(&f, &i, 4);
return f;
@ -642,7 +652,7 @@ CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a)
{
ENTER(t, Thread::ActiveState);
runv(t, getStaticMethod(t, *c, m), 0, true, a);
t->m->processor->invokeList(t, getStaticMethod(t, *c, m), 0, true, a);
}
void JNICALL
@ -693,7 +703,7 @@ GetObjectField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, cast<object>(*o, field));
return makeLocalReference(t, cast<object>(*o, field));
}
jboolean JNICALL
@ -837,7 +847,7 @@ GetStaticObjectField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, arrayBody(t, classStaticTable(t, *c), field));
return makeLocalReference(t, arrayBody(t, classStaticTable(t, *c), field));
}
jboolean JNICALL
@ -1003,12 +1013,12 @@ NewGlobalRef(Thread* t, jobject o)
{
ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->vm->referenceLock);
ACQUIRE(t, t->m->referenceLock);
t->vm->jniReferences = new (t->vm->system->allocate(sizeof(Reference)))
Reference(*o, t->vm->jniReferences);
t->m->jniReferences = new (t->m->system->allocate(sizeof(Reference)))
Reference(*o, t->m->jniReferences);
return &(t->vm->jniReferences->target);
return &(t->m->jniReferences->target);
}
void JNICALL
@ -1016,9 +1026,9 @@ DeleteGlobalRef(Thread* t, jobject o)
{
ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->vm->referenceLock);
ACQUIRE(t, t->m->referenceLock);
for (Reference** r = &(t->vm->jniReferences); *r;) {
for (Reference** r = &(t->m->jniReferences); *r;) {
if (&((*r)->target) == o) {
*r = (*r)->next;
break;
@ -1033,7 +1043,7 @@ ExceptionOccurred(Thread* t)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, t->exception);
return makeLocalReference(t, t->exception);
}
void JNICALL
@ -1057,7 +1067,7 @@ NewBooleanArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeBooleanArray(t, length, true));
return makeLocalReference(t, makeBooleanArray(t, length, true));
}
jbyteArray JNICALL
@ -1065,7 +1075,7 @@ NewByteArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeByteArray(t, length, true));
return makeLocalReference(t, makeByteArray(t, length, true));
}
jcharArray JNICALL
@ -1073,7 +1083,7 @@ NewCharArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeCharArray(t, length, true));
return makeLocalReference(t, makeCharArray(t, length, true));
}
jshortArray JNICALL
@ -1081,7 +1091,7 @@ NewShortArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeShortArray(t, length, true));
return makeLocalReference(t, makeShortArray(t, length, true));
}
jintArray JNICALL
@ -1089,7 +1099,7 @@ NewIntArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeIntArray(t, length, true));
return makeLocalReference(t, makeIntArray(t, length, true));
}
jlongArray JNICALL
@ -1097,7 +1107,7 @@ NewLongArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeLongArray(t, length, true));
return makeLocalReference(t, makeLongArray(t, length, true));
}
jfloatArray JNICALL
@ -1105,7 +1115,7 @@ NewFloatArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeFloatArray(t, length, true));
return makeLocalReference(t, makeFloatArray(t, length, true));
}
jdoubleArray JNICALL
@ -1113,7 +1123,7 @@ NewDoubleArray(Thread* t, jsize length)
{
ENTER(t, Thread::ActiveState);
return pushReference(t, makeDoubleArray(t, length, true));
return makeLocalReference(t, makeDoubleArray(t, length, true));
}
jboolean* JNICALL
@ -1122,7 +1132,7 @@ GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
jboolean* p = static_cast<jboolean*>(t->vm->system->allocate(size));
jboolean* p = static_cast<jboolean*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &booleanArrayBody(t, *array, 0), size);
}
@ -1140,7 +1150,7 @@ GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
jbyte* p = static_cast<jbyte*>(t->vm->system->allocate(size));
jbyte* p = static_cast<jbyte*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &byteArrayBody(t, *array, 0), size);
}
@ -1158,7 +1168,7 @@ GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
jchar* p = static_cast<jchar*>(t->vm->system->allocate(size));
jchar* p = static_cast<jchar*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &charArrayBody(t, *array, 0), size);
}
@ -1176,7 +1186,7 @@ GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
jshort* p = static_cast<jshort*>(t->vm->system->allocate(size));
jshort* p = static_cast<jshort*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &shortArrayBody(t, *array, 0), size);
}
@ -1194,7 +1204,7 @@ GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = intArrayLength(t, *array) * sizeof(jint);
jint* p = static_cast<jint*>(t->vm->system->allocate(size));
jint* p = static_cast<jint*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &intArrayBody(t, *array, 0), size);
}
@ -1212,7 +1222,7 @@ GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
jlong* p = static_cast<jlong*>(t->vm->system->allocate(size));
jlong* p = static_cast<jlong*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &longArrayBody(t, *array, 0), size);
}
@ -1230,7 +1240,7 @@ GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
jfloat* p = static_cast<jfloat*>(t->vm->system->allocate(size));
jfloat* p = static_cast<jfloat*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &floatArrayBody(t, *array, 0), size);
}
@ -1248,7 +1258,7 @@ GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy)
ENTER(t, Thread::ActiveState);
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
jdouble* p = static_cast<jdouble*>(t->vm->system->allocate(size));
jdouble* p = static_cast<jdouble*>(t->m->system->allocate(size));
if (size) {
memcpy(p, &doubleArrayBody(t, *array, 0), size);
}
@ -1274,7 +1284,7 @@ ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p,
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1291,7 +1301,7 @@ ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1308,7 +1318,7 @@ ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1325,7 +1335,7 @@ ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1342,7 +1352,7 @@ ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1359,7 +1369,7 @@ ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1376,7 +1386,7 @@ ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode)
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1394,7 +1404,7 @@ ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p,
}
if (mode == 0 or mode == JNI_ABORT) {
t->vm->system->free(p);
t->m->system->free(p);
}
}
@ -1567,7 +1577,7 @@ ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint)
jint JNICALL
GetJavaVM(Thread* t, Machine** m)
{
*m = t->vm;
*m = t->m;
return 0;
}

View File

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

View File

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

View File

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

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

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;
}
}