more work on new JIT code

This commit is contained in:
Joel Dice 2007-11-21 15:15:33 -07:00
parent a017dab73a
commit 856935acc2
2 changed files with 502 additions and 199 deletions

View File

@ -5,16 +5,28 @@
using namespace vm;
extern "C" uint64_t
vmInvoke(void* thread, void* function, void* stack, unsigned stackSize,
unsigned returnType);
extern "C" void
vmCall();
extern "C" void NO_RETURN
vmJump(void* address, void* base, void* stack);
namespace {
class MyThread: public Thread {
public:
MyThread(Machine* m, object javaThread, Thread* parent):
Thread(m, javaThread, parent),
base(0)
caller(0),
reference(0)
{ }
void* base;
void* caller;
Reference* reference;
};
uintptr_t*
@ -93,7 +105,7 @@ class Frame {
}
Operand* append(object o) {
Operand* result = c->append(c->constant(0));
Operand* result = c->poolAppend(c->constant(0));
objectPool->appendAddress(c->poolOffset(result));
objectPool->appendAddress(reinterpret_cast<uintptr_t>(o));
return result;
@ -408,35 +420,35 @@ class Frame {
void loadInt(unsigned index) {
assert(t, index < localSize());
assert(t, getBit(map, index) == 0);
pushInt(c->offset(c->base(), localOffset(t, index, method)));
pushInt(c->memory(c->base(), localOffset(t, index, method)));
}
void loadLong(unsigned index) {
assert(t, index < localSize() - 1);
assert(t, getBit(map, index) == 0);
assert(t, getBit(map, index + 1) == 0);
pushLong(c->offset(c->base(), localOffset(t, index, method)));
pushLong(c->memory(c->base(), localOffset(t, index, method)));
}
void loadObject(unsigned index) {
assert(t, index < localSize());
assert(t, getBit(map, index) != 0);
pushObject(c->offset(c->base(), localOffset(t, index, method)));
pushObject(c->memory(c->base(), localOffset(t, index, method)));
}
void storeInt(unsigned index) {
popInt(c->offset(c->base(), localOffset(t, index, method)));
popInt(c->memory(c->base(), localOffset(t, index, method)));
storedInt(index);
}
void storeLong(unsigned index) {
popLong(c->offset(c->base(), localOffset(t, index, method)));
popLong(c->memory(c->base(), localOffset(t, index, method)));
storedInt(index);
storedInt(index + 1);
}
void storeObject(unsigned index) {
popObject(c->offset(c->base(), localOffset(t, index, method)));
popObject(c->memory(c->base(), localOffset(t, index, method)));
storedObject(index);
}
@ -444,7 +456,7 @@ class Frame {
assert(t, index < localSize());
assert(t, getBit(map, index) == 0);
c->add(c->constant(count),
c->offset(c->base(), localOffset(t, index, method)));
c->memory(c->base(), localOffset(t, index, method)));
}
void dup() {
@ -524,6 +536,8 @@ class Frame {
c->mov(s1, s0);
c->mov(tmp, s1);
c->release(tmp);
swapped();
}
@ -945,47 +959,34 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->cmp(c->constant(0), index);
c->jl(outOfBounds);
c->cmp(c->offset(index, ArrayLength), index);
c->cmp(c->memory(array, ArrayLength), index);
c->jge(outOfBounds);
c->add(c->constant(ArrayBody), array);
switch (instruction) {
case aaload:
frame->pushObject(c->memory(array, ArrayBody, index, BytesPerWord));
break;
case faload:
case iaload:
c->shl(c->constant(log(BytesPerWord)), index);
c->add(index, array);
if (instruction == aaload) {
frame->pushObject(c->dereference(array));
} else {
frame->pushInt(c->dereference4(array));
}
frame->pushInt(c->select4(c->memory(array, ArrayBody, index, 4)));
break;
case baload:
c->add(index, array);
frame->pushInt(c->dereference1(array));
frame->pushInt(c->select1(c->memory(array, ArrayBody, index, 1)));
break;
case caload:
c->shl(c->constant(1), index);
c->add(index, array);
frame->pushInt(c->dereference2z(array));
frame->pushInt(c->select2z(c->memory(array, ArrayBody, index, 2)));
break;
case daload:
case laload:
c->shl(c->constant(3), index);
c->add(index, array);
frame->pushLong(c->dereference8(array));
frame->pushInt(c->select8(c->memory(array, ArrayBody, index, 8)));
break;
case saload:
c->shl(c->constant(1), index);
c->add(index, array);
frame->pushInt(c->dereference2(array));
frame->pushInt(c->select2(c->memory(array, ArrayBody, index, 2)));
break;
}
@ -1023,7 +1024,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->cmp(c->constant(0), index);
c->jl(outOfBounds);
c->cmp(c->offset(index, BytesPerWord), index);
c->cmp(c->memory(array, BytesPerWord), index);
c->jge(outOfBounds);
switch (instruction) {
@ -1037,32 +1038,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case fastore:
case iastore:
c->shl(c->constant(log(BytesPerWord)), index);
c->add(c->constant(ArrayBody), index);
c->add(index, array);
c->mov(value, c->dereference4(array));
c->mov(value, c->select4(c->memory(array, ArrayBody, index, 4)));
break;
case bastore:
c->add(c->constant(ArrayBody), index);
c->add(index, array);
c->mov(value, c->dereference1(array));
c->mov(value, c->select1(c->memory(array, ArrayBody, index, 1)));
break;
case castore:
case sastore:
c->shl(c->constant(1), index);
c->add(c->constant(ArrayBody), index);
c->add(index, array);
c->mov(value, c->dereference2(array));
c->mov(value, c->select2(c->memory(array, ArrayBody, index, 2)));
break;
case dastore:
case lastore:
c->shl(c->constant(3), index);
c->add(c->constant(ArrayBody), index);
c->add(index, array);
c->mov(value, c->dereference8(array));
c->mov(value, c->select8(c->memory(array, ArrayBody, index, 8)));
break;
}
@ -1121,11 +1111,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case areturn:
c->epilogue(frame->popObject());
c->epilogue();
c->return_(frame->popObject());
return;
case arraylength:
frame->pushInt(c->offset(frame->popObject(), ArrayLength));
frame->pushInt(c->memory(frame->popObject(), ArrayLength));
break;
case astore:
@ -1176,7 +1167,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* classOperand = frame->append(class_);
c->mov(c->dereference(tmp), tmp);
c->mov(c->memory(tmp), tmp);
c->and_(c->constant(PointerMask), tmp);
c->cmp(classOperand, tmp);
@ -1186,6 +1177,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
(c->constant(reinterpret_cast<intptr_t>(isAssignableFrom)),
2, classOperand, tmp);
c->release(tmp);
c->cmp(0, result);
c->jne(next);
@ -1427,29 +1420,29 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
frame->pushInt(c->offset1(table, fieldOffset(t, field)));
frame->pushInt(c->select1(c->memory(table, fieldOffset(t, field))));
break;
case CharField:
frame->pushInt(c->offset2z(table, fieldOffset(t, field)));
frame->pushInt(c->select2z(c->memory(table, fieldOffset(t, field))));
break;
case ShortField:
frame->pushInt(c->offset2(table, fieldOffset(t, field)));
frame->pushInt(c->select2(c->memory(table, fieldOffset(t, field))));
break;
case FloatField:
case IntField:
frame->pushInt(c->offset4(table, fieldOffset(t, field)));
frame->pushInt(c->select4(c->memory(table, fieldOffset(t, field))));
break;
case DoubleField:
case LongField:
frame->pushLong(c->offset8(table, fieldOffset(t, field)));
frame->pushLong(c->select8(c->memory(table, fieldOffset(t, field))));
break;
case ObjectField:
frame->pushObject(c->offset(table, fieldOffset(t, field)));
frame->pushObject(c->memory(c->memory(table, fieldOffset(t, field))));
break;
default:
@ -1721,7 +1714,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* classOperand = frame->append(class_);
c->mov(c->dereference(tmp), tmp);
c->mov(c->memory(tmp), tmp);
c->and_(c->constant(PointerMask), tmp);
c->cmp(classOperand, tmp);
@ -1734,6 +1727,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
(c->directCall
(c->constant(reinterpret_cast<intptr_t>(isAssignableFrom)),
2, classOperand, tmp), result);
c->release(tmp);
c->jmp(next);
c->mark(zero);
@ -1742,6 +1738,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->mark(next);
frame->pushInt(result);
c->release(result);
} break;
case invokeinterface: {
@ -1760,9 +1758,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
(reinterpret_cast<intptr_t>(findInterfaceMethodFromInstance)),
3, c->thread(), frame->append(target), c->stack(instance));
c->mov(c->offset(found, MethodCompiled), found);
c->mov(c->memory(found, MethodCompiled), found);
Operand* result = c->call(c->offset(found, SingletonBody));
Operand* result = c->call(c->memory(found, SingletonBody));
frame->pop(parameterFootprint);
@ -1809,10 +1807,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* instance = c->stack(parameterFootprint - 1);
Operand* class_ = c->temporary();
c->mov(c->dereference(instance), class_);
c->mov(c->memory(instance), class_);
c->and_(c->constant(PointerMask), class_);
Operand* result = c->call(c->offset(class_, offset));
Operand* result = c->call(c->memory(class_, offset));
c->release(class_);
frame->pop(parameterFootprint);
@ -1831,7 +1831,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case ireturn:
case freturn:
c->epilogue(frame->popInt());
c->epilogue();
c->return_(frame->popInt());
return;
case ishl: {
@ -1924,6 +1925,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->mark(next);
frame->pushInt(result);
c->release(result);
} break;
case lconst_0:
@ -2025,7 +2028,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
compile(t, frame, defaultIp);
if (UNLIKELY(t->exception)) return;
Operand* default_ = c->append(c->logicalIp(defaultIp));
Operand* default_ = c->poolAppend(c->logicalIp(defaultIp));
int32_t pairCount = codeReadInt32(t, code, ip);
@ -2039,8 +2042,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return;
Operand* result = c->append(c->constant(key));
c->append(c->logicalIp(newIp));
Operand* result = c->poolAppend(c->constant(key));
c->poolAppend(c->logicalIp(newIp));
if (i == 0) {
start = result;
@ -2065,7 +2068,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lreturn:
case dreturn:
c->epilogue(frame->popLong());
c->epilogue();
c->return_(frame->popLong());
return;
case lshl: {
@ -2288,22 +2292,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
c->mov(value, c->offset1(table, fieldOffset(t, field)));
c->mov(value, c->select1(c->memory(table, fieldOffset(t, field))));
break;
case CharField:
case ShortField:
c->mov(value, c->offset2(table, fieldOffset(t, field)));
c->mov(value, c->select2(c->memory(table, fieldOffset(t, field))));
break;
case FloatField:
case IntField:
c->mov(value, c->offset4(table, fieldOffset(t, field)));
c->mov(value, c->select4(c->memory(table, fieldOffset(t, field))));
break;
case DoubleField:
case LongField:
c->mov(value, c->offset8(table, fieldOffset(t, field)));
c->mov(value, c->select8(c->memory(table, fieldOffset(t, field))));
break;
case ObjectField:
@ -2318,6 +2322,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case return_:
c->epilogue();
c->ret();
return;
case sipush:
@ -2342,7 +2347,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
compile(t, frame, defaultIp);
if (UNLIKELY(t->exception)) return;
Operand* default_ = c->append(c->logicalIp(defaultIp));
Operand* default_ = c->poolAppend(c->logicalIp(defaultIp));
int32_t bottom = codeReadInt32(t, code, ip);
int32_t top = codeReadInt32(t, code, ip);
@ -2356,7 +2361,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return;
Operand* result = c->append(c->logicalIp(newIp));
Operand* result = c->poolAppend(c->logicalIp(newIp));
if (i == 0) {
start = result;
}
@ -2370,8 +2375,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->cmp(c->constant(top), key);
c->jg(defaultCase);
c->shl(c->constant(2), key);
c->jmp(c->offset(start, key));
c->shl(c->constant(1), key);
c->jmp(c->memory(start, 0, key, BytesPerWord));
c->mark(defaultCase);
c->jmp(default_);
@ -2422,19 +2427,46 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
}
object
compile(MyThread* t, Compiler* compiler, object method)
finish(MyThread* t, Compiler* c, Buffer* objectPool)
{
unsigned count = ceiling(c->size(), BytesPerWord);
unsigned size = count + singletonMaskSize(count);
object result = allocate2(t, size * BytesPerWord, true, true);
initSingleton(t, result, size, true);
singletonMask(t, result)[0] = 1;
c->writeTo(&singletonValue(t, result, 0));
if (objectPool) {
for (unsigned i = 0; i < objectPool->length(); i += BytesPerWord * 2) {
uintptr_t index = c->poolOffset() + objectPool->getAddress(i);
object value = reinterpret_cast<object>(objectPool->getAddress(i));
singletonMarkObject(t, result, index);
set(t, result, SingletonBody + (index * BytesPerWord), value);
}
}
return result;
}
object
compile(MyThread* t, Compiler* c, object method)
{
PROTECT(t, method);
c->prologue();
object code = methodCode(t, method);
PROTECT(t, code);
compiler->prologue(methodParameterFootprint(t, method),
codeMaxLocals(t, code));
unsigned footprint = methodParameterFootprint(t, method);
unsigned locals = codeMaxLocals(t, code);
c->reserve(locals > footprint ? locals - footprint : 0);
Buffer objectPool(t->m->system, 256);
uintptr_t map[Frame::mapSizeInWords(t, method)];
Frame frame(t, compiler, method, map, &objectPool);
Frame frame(t, c, method, map, &objectPool);
compile(t, &frame, 0);
if (UNLIKELY(t->exception)) return 0;
@ -2457,29 +2489,237 @@ compile(MyThread* t, Compiler* compiler, object method)
}
}
unsigned count = ceiling(compiler->size(), BytesPerWord);
unsigned size = count + singletonMaskSize(count);
object result = allocate2(t, size * BytesPerWord, true, true);
initSingleton(t, result, size, true);
singletonMask(t, result)[0] = 1;
return finish(t, c, &objectPool);
}
compiler->writeTo(&singletonValue(t, result, 0));
void
compile(MyThread* t, object method);
for (unsigned i = 0; i < objectPool.length(); i += BytesPerWord * 2) {
uintptr_t index = compiler->poolOffset() + objectPool.getAddress(i);
object value = reinterpret_cast<object>(objectPool.getAddress(i));
void*
compileMethod(MyThread* t);
singletonMarkObject(t, result, index);
set(t, result, SingletonBody + (index * BytesPerWord), value);
void*
invokeNative(MyThread* t);
void
visitStack(MyThread* t, Heap::Visitor* v);
object
compileDefault(MyThread* t, Compiler* c)
{
c->prologue();
unsigned caller
= reinterpret_cast<uintptr_t>(&(t->caller))
- reinterpret_cast<uintptr_t>(t);
c->mov(c->base(), c->memory(c->thread(), caller));
c->epilogue();
c->jmp
(c->directCall
(c->constant(reinterpret_cast<intptr_t>(compileMethod)),
1, c->thread()));
return finish(t, c, 0);
}
object
compileNative(MyThread* t, Compiler* c)
{
c->prologue();
unsigned caller
= reinterpret_cast<uintptr_t>(&(t->caller))
- reinterpret_cast<uintptr_t>(t);
c->mov(c->base(), c->memory(c->thread(), caller));
c->call
(c->directCall
(c->constant(reinterpret_cast<intptr_t>(invokeNative)),
1, c->thread()));
c->epilogue();
c->ret();
return finish(t, c, 0);
}
class ArgumentList {
public:
ArgumentList(Thread* t, uintptr_t* array, bool* objectMask, object this_,
const char* spec, bool indirectObjects, va_list arguments):
t(static_cast<MyThread*>(t)),
array(array),
objectMask(objectMask),
position(0),
protector(this)
{
if (this_) {
addObject(this_);
}
for (MethodSpecIterator it(t, spec); it.hasNext();) {
switch (*it.next()) {
case 'L':
case '[':
if (indirectObjects) {
object* v = va_arg(arguments, object*);
addObject(v ? *v : 0);
} else {
addObject(va_arg(arguments, object));
}
break;
case 'J':
case 'D':
addLong(va_arg(arguments, uint64_t));
break;
default:
addInt(va_arg(arguments, uint32_t));
break;
}
}
}
return result;
ArgumentList(Thread* t, uintptr_t* array, bool* objectMask, object this_,
const char* spec, object arguments):
t(static_cast<MyThread*>(t)),
array(array),
objectMask(objectMask),
position(0),
protector(this)
{
if (this_) {
addObject(this_);
}
unsigned index = 0;
for (MethodSpecIterator it(t, spec); it.hasNext();) {
switch (*it.next()) {
case 'L':
case '[':
addObject(objectArrayBody(t, arguments, index++));
break;
case 'J':
case 'D':
addLong(cast<int64_t>(objectArrayBody(t, arguments, index++),
BytesPerWord));
break;
default:
addInt(cast<int32_t>(objectArrayBody(t, arguments, index++),
BytesPerWord));
break;
}
}
}
void addObject(object v) {
array[position] = reinterpret_cast<uintptr_t>(v);
objectMask[position] = true;
++ position;
}
void addInt(uintptr_t v) {
array[position] = v;
objectMask[position] = false;
++ position;
}
void addLong(uint64_t v) {
memcpy(array + position, &v, 8);
objectMask[position] = false;
objectMask[position] = false;
position += 2;
}
MyThread* t;
uintptr_t* array;
bool* objectMask;
unsigned position;
class MyProtector: public Thread::Protector {
public:
MyProtector(ArgumentList* list): Protector(list->t), list(list) { }
virtual void visit(Heap::Visitor* v) {
for (unsigned i = 0; i < list->position; ++i) {
if (list->objectMask[i]) {
v->visit(reinterpret_cast<object*>(list->array + i));
}
}
}
ArgumentList* list;
} protector;
};
object
invoke(Thread* thread, object method, ArgumentList* arguments)
{
MyThread* t = static_cast<MyThread*>(thread);
unsigned returnCode = methodReturnCode(t, method);
unsigned returnType = fieldType(t, returnCode);
Reference* reference = t->reference;
void* caller = t->caller;
uint64_t result = vmInvoke
(t, &singletonValue(t, methodCompiled(t, method), 0), arguments->array,
arguments->position * BytesPerWord, returnType);
t->caller = caller;
while (t->reference != reference) {
dispose(t, t->reference);
}
object r;
switch (returnCode) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField:
r = makeInt(t, result);
break;
case LongField:
case DoubleField:
r = makeLong(t, result);
break;
case ObjectField:
r = (result == 0 ? 0 :
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
break;
case VoidField:
r = 0;
break;
default:
abort(t);
};
return r;
}
class MyProcessor: public Processor {
public:
MyProcessor(System* s):
s(s)
s(s),
defaultCompiled(0),
nativeCompiled(0),
addressTree(0),
indirectCaller(0)
{ }
virtual Thread*
@ -2491,6 +2731,24 @@ class MyProcessor: public Processor {
return t;
}
object getDefaultCompiled(MyThread* t) {
if (defaultCompiled == 0) {
Compiler* c = makeCompiler(t->m->system, 0);
defaultCompiled = compileDefault(t, c);
c->dispose();
}
return defaultCompiled;
}
object getNativeCompiled(MyThread* t) {
if (nativeCompiled == 0) {
Compiler* c = makeCompiler(t->m->system, 0);
nativeCompiled = compileNative(t, c);
c->dispose();
}
return nativeCompiled;
}
virtual object
makeMethod(vm::Thread* t,
uint8_t vmFlags,
@ -2505,7 +2763,9 @@ class MyProcessor: public Processor {
object code)
{
object compiled
= ((flags & ACC_NATIVE) ? nativeCompiled : defaultCompiled);
= ((flags & ACC_NATIVE)
? getNativeCompiled(static_cast<MyThread*>(t))
: getDefaultCompiled(static_cast<MyThread*>(t)));
return vm::makeMethod
(t, vmFlags, returnCode, parameterCount, parameterFootprint, flags,
@ -2537,7 +2797,10 @@ class MyProcessor: public Processor {
for (unsigned i = 0; i < vtableLength; ++i) {
object compiled
= ((flags & ACC_NATIVE) ? nativeCompiled : defaultCompiled);
= ((flags & ACC_NATIVE)
? getNativeCompiled(static_cast<MyThread*>(t))
: getDefaultCompiled(static_cast<MyThread*>(t)));
classVtable(t, c, i) = &singletonBody(t, compiled, 0);
}
@ -2568,9 +2831,9 @@ class MyProcessor: public Processor {
MyThread* t = static_cast<MyThread*>(vmt);
if (t == t->m->rootThread) {
visit(&defaultCompiled);
visit(&nativeCompiled);
visit(&addressTree);
v->visit(&defaultCompiled);
v->visit(&nativeCompiled);
v->visit(&addressTree);
}
for (Reference* r = t->reference; r; r = r->next) {
@ -2581,70 +2844,39 @@ class MyProcessor: public Processor {
}
virtual uintptr_t
frameStart(Thread* vmt)
frameStart(Thread* t)
{
return reinterpret_cast<uintptr_t>
(::frameStart(static_cast<MyThread*>(vmt)));
abort(t);
}
virtual uintptr_t
frameNext(Thread*, uintptr_t frame)
frameNext(Thread* t, uintptr_t)
{
return reinterpret_cast<uintptr_t>
(::frameNext(reinterpret_cast<void*>(frame)));
abort(t);
}
virtual bool
frameValid(Thread*, uintptr_t frame)
frameValid(Thread* t, uintptr_t)
{
return ::frameValid(reinterpret_cast<void*>(frame));
abort(t);
}
virtual object
frameMethod(Thread*, uintptr_t frame)
frameMethod(Thread* t, uintptr_t)
{
return ::frameMethod(reinterpret_cast<void*>(frame));
abort(t);
}
virtual unsigned
frameIp(Thread* t, uintptr_t frame)
frameIp(Thread* t, uintptr_t)
{
void* f = reinterpret_cast<void*>(frame);
return addressOffset(t, ::frameMethod(f), ::frameAddress(f));
abort(t);
}
virtual int
lineNumber(Thread* t, object method, unsigned ip)
lineNumber(Thread* t, object, unsigned)
{
if (methodFlags(t, method) & ACC_NATIVE) {
return NativeLine;
}
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
if (compiledLineNumberCount(t, code)) {
unsigned bottom = 0;
unsigned top = compiledLineNumberCount(t, code);
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
NativeLineNumber* ln = compiledLineNumber(t, code, middle);
if (ip >= nativeLineNumberIp(ln)
and (middle + 1 == compiledLineNumberCount(t, code)
or ip < nativeLineNumberIp
(compiledLineNumber(t, code, middle + 1))))
{
return nativeLineNumberLine(ln);
} else if (ip < nativeLineNumberIp(ln)) {
top = middle;
} else if (ip > nativeLineNumberIp(ln)) {
bottom = middle + 1;
}
}
abort(t);
} else {
return UnknownLine;
}
abort(t);
}
virtual object*
@ -2681,12 +2913,20 @@ class MyProcessor: public Processor {
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method) + FrameFootprint;
unsigned size = methodParameterFootprint(t, method);
uintptr_t array[size];
bool objectMask[size];
ArgumentList list(t, array, objectMask, this_, spec, arguments);
return ::invoke(t, method, &list);
PROTECT(t, method);
compile(static_cast<MyThread*>(t), method);
if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list);
}
return 0;
}
virtual object
@ -2701,13 +2941,21 @@ class MyProcessor: public Processor {
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method) + FrameFootprint;
unsigned size = methodParameterFootprint(t, method);
uintptr_t array[size];
bool objectMask[size];
ArgumentList list
(t, array, objectMask, this_, spec, indirectObjects, arguments);
return ::invoke(t, method, &list);
PROTECT(t, method);
compile(static_cast<MyThread*>(t), method);
if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list);
}
return 0;
}
virtual object
@ -2717,7 +2965,7 @@ class MyProcessor: public Processor {
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
unsigned size = parameterFootprint(t, methodSpec, false) + FrameFootprint;
unsigned size = parameterFootprint(t, methodSpec, false);
uintptr_t array[size];
bool objectMask[size];
ArgumentList list
@ -2727,34 +2975,72 @@ class MyProcessor: public Processor {
if (LIKELY(t->exception == 0)) {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
return ::invoke(t, method, &list);
} else {
return 0;
PROTECT(t, method);
compile(static_cast<MyThread*>(t), method);
if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list);
}
}
return 0;
}
virtual void dispose() {
if (methodStub_) {
s->free(methodStub_);
}
if (nativeInvoker_) {
s->free(nativeInvoker_);
}
if (caller_) {
s->free(caller_);
if (indirectCaller) {
s->free(indirectCaller);
}
s->free(this);
}
System* s;
Compiled* methodStub_;
Compiled* nativeInvoker_;
Compiled* caller_;
object defaultCompiled;
object nativeCompiled;
object addressTree;
void* indirectCaller;
};
void
compile(MyThread* t, object method)
{
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
object stub = p->getDefaultCompiled(t);
if (methodCompiled(t, method) == stub) {
PROTECT(t, method);
ACQUIRE(t, t->m->classLock);
if (methodCompiled(t, method) == stub) {
if (p->indirectCaller == 0) {
Compiler* c = makeCompiler(t->m->system, 0);
unsigned caller
= reinterpret_cast<uintptr_t>(&(t->caller))
- reinterpret_cast<uintptr_t>(t);
c->mov(c->base(), c->memory(c->thread(), caller));
c->jmp(c->indirectTarget());
p->indirectCaller = t->m->system->allocate(c->size());
c->writeTo(p->indirectCaller);
}
PROTECT(t, method);
Compiler* c = makeCompiler(t->m->system, p->indirectCaller);
object compiled = compile(t, c, method);
set(t, method, MethodCompiled, compiled);
c->dispose();
}
}
}
} // namespace
namespace vm {

View File

@ -1,6 +1,8 @@
#ifndef COMPILER_H
#define COMPILER_H
#include "system.h"
namespace vm {
class Operand { };
@ -9,10 +11,12 @@ class Compiler {
public:
virtual ~Compiler() { }
virtual Operand* append(Operand*) = 0;
virtual Operand* constant(intptr_t) = 0;
virtual Operand* poolAppend(Operand*) = 0;
virtual unsigned poolOffset() = 0;
virtual unsigned poolOffset(Operand*) = 0;
virtual Operand* constant(intptr_t) = 0;
virtual void push(Operand*) = 0;
virtual void push2(Operand*) = 0;
virtual Operand* stack() = 0;
@ -22,17 +26,30 @@ class Compiler {
virtual Operand* pop2() = 0;
virtual void pop(Operand*) = 0;
virtual void pop2(Operand*) = 0;
virtual Operand* base() = 0;
virtual Operand* thread() = 0;
virtual Operand* indirectTarget() = 0;
virtual Operand* temporary() = 0;
virtual void release(Operand*) = 0;
virtual Operand* label() = 0;
virtual void mark(Operand*) = 0;
virtual Operand* call(Operand*) = 0;
virtual Operand* alignedCall(Operand*) = 0;
virtual Operand* indirectCall(Operand*, unsigned, ...) = 0;
virtual Operand* indirectCallNoReturn(Operand*, unsigned, ...) = 0;
virtual Operand* directCall(Operand*, unsigned, ...) = 0;
virtual void mov(Operand*, Operand*) = 0;
virtual void cmp(Operand*, Operand*) = 0;
virtual Operand* indirectCall
(Operand* address, unsigned argumentCount, ...) = 0;
virtual Operand* indirectCallNoReturn
(Operand* address, unsigned argumentCount, ...) = 0;
virtual Operand* directCall
(Operand* address, unsigned argumentCount, ...) = 0;
virtual void return_(Operand*) = 0;
virtual void ret() = 0;
virtual void mov(Operand* src, Operand* dst) = 0;
virtual void cmp(Operand* subtrahend, Operand* minuend) = 0;
virtual void jl(Operand*) = 0;
virtual void jg(Operand*) = 0;
virtual void jle(Operand*) = 0;
@ -40,47 +57,47 @@ class Compiler {
virtual void je(Operand*) = 0;
virtual void jne(Operand*) = 0;
virtual void jmp(Operand*) = 0;
virtual void add(Operand*, Operand*) = 0;
virtual void sub(Operand*, Operand*) = 0;
virtual void mul(Operand*, Operand*) = 0;
virtual void div(Operand*, Operand*) = 0;
virtual void rem(Operand*, Operand*) = 0;
virtual void shl(Operand*, Operand*) = 0;
virtual void shr(Operand*, Operand*) = 0;
virtual void ushr(Operand*, Operand*) = 0;
virtual void and_(Operand*, Operand*) = 0;
virtual void or_(Operand*, Operand*) = 0;
virtual void xor_(Operand*, Operand*) = 0;
virtual void add(Operand* v, Operand* dst) = 0;
virtual void sub(Operand* v, Operand* dst) = 0;
virtual void mul(Operand* v, Operand* dst) = 0;
virtual void div(Operand* v, Operand* dst) = 0;
virtual void rem(Operand* v, Operand* dst) = 0;
virtual void shl(Operand* v, Operand* dst) = 0;
virtual void shr(Operand* v, Operand* dst) = 0;
virtual void ushr(Operand* v, Operand* dst) = 0;
virtual void and_(Operand* v, Operand* dst) = 0;
virtual void or_(Operand* v, Operand* dst) = 0;
virtual void xor_(Operand* v, Operand* dst) = 0;
virtual void neg(Operand*) = 0;
virtual void mark(Operand*) = 0;
virtual Operand* offset(Operand*, Operand*) = 0;
virtual Operand* offset(Operand*, unsigned) = 0;
virtual Operand* offset1(Operand*, unsigned) = 0;
virtual Operand* offset2(Operand*, unsigned) = 0;
virtual Operand* offset2z(Operand*, unsigned) = 0;
virtual Operand* offset4(Operand*, unsigned) = 0;
virtual Operand* offset8(Operand*, unsigned) = 0;
virtual Operand* dereference(Operand*) = 0;
virtual Operand* dereference1(Operand*) = 0;
virtual Operand* dereference2(Operand*) = 0;
virtual Operand* dereference2z(Operand*) = 0;
virtual Operand* dereference4(Operand*) = 0;
virtual Operand* dereference8(Operand*) = 0;
virtual Operand* select(Operand*) = 0;
virtual Operand* memory(Operand* base) = 0;
virtual Operand* memory(Operand* base, unsigned displacement) = 0;
virtual Operand* memory(Operand* base, unsigned displacement,
Operand* index, unsigned scale) = 0;
virtual Operand* select1(Operand*) = 0;
virtual Operand* select2(Operand*) = 0;
virtual Operand* select2z(Operand*) = 0;
virtual Operand* select4(Operand*) = 0;
virtual Operand* select8(Operand*) = 0;
virtual void prologue(unsigned, unsigned) = 0;
virtual void epilogue(Operand*) = 0;
virtual void reserve(unsigned) = 0;
virtual void prologue() = 0;
virtual void epilogue() = 0;
virtual Operand* logicalIp(unsigned) = 0;
virtual void startLogicalIp(unsigned) = 0;
virtual Operand* logicalIp(unsigned) = 0;
virtual unsigned size() = 0;
virtual unsigned writeTo(uintptr_t*) = 0;
virtual void writeTo(void*) = 0;
virtual void dispose() = 0;
};
Compiler*
makeCompiler(System* system, void* indirectCaller);
} // namespace vm
#endif//COMPILER_H