mirror of
https://github.com/corda/corda.git
synced 2025-05-31 22:50:53 +00:00
sketch of Frame class implementation for new JIT code
This commit is contained in:
parent
2eeff1d50e
commit
37a1aa72f9
638
src/compile2.cpp
638
src/compile2.cpp
@ -1,22 +1,506 @@
|
|||||||
Operand*
|
uintptr_t*
|
||||||
add(Compiler* c, Buffer* objectPool, object o)
|
makeCodeMask(MyThread* t, unsigned length)
|
||||||
{
|
{
|
||||||
Operand* result = c->append(c->constant(0));
|
unsigned size = ceiling(codeLength(t, code), BytesPerWord)
|
||||||
objectPool->appendAddress(c->poolOffset(result));
|
* BytesPerWord;
|
||||||
objectPool->appendAddress(o);
|
uintptr_t* mask = static_cast<uintptr_t*>(t->m->system->allocate(size));
|
||||||
return result;
|
memset(mask, 0, size);
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Frame {
|
||||||
|
public:
|
||||||
|
class MyProtector: public Thread::Protector {
|
||||||
|
public:
|
||||||
|
MyProtector(MyThread* t, Frame* frame): Protector(t), frame(frame) { }
|
||||||
|
|
||||||
|
virtual void visit(Heap::Visitor* v) {
|
||||||
|
v->visit(&(frame->method));
|
||||||
|
|
||||||
|
if (next == 0) {
|
||||||
|
Buffer* pool = frame->objectPool;
|
||||||
|
for (unsigned i = 1; i < pool->length(); i += BytesPerWord * 2) {
|
||||||
|
v->visit(reinterpret_cast<object*>(&(pool->getAddress(i))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame* frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
Frame(MyThread* t, Compiler* c, object method, uintptr_t* map,
|
||||||
|
Buffer* objectPool):
|
||||||
|
next(0),
|
||||||
|
t(t),
|
||||||
|
c(c),
|
||||||
|
method(method),
|
||||||
|
map(map),
|
||||||
|
objectPool(objectPool),
|
||||||
|
codeMask(makeCodeMask(t, codeLength(t, methodCode(t, method)))),
|
||||||
|
sp(localSize(t, method)),
|
||||||
|
protector(t, this)
|
||||||
|
{
|
||||||
|
memset(map, 0, mapSizeInBytes(t, method));
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame(Frame* f, uintptr_t* map):
|
||||||
|
next(f),
|
||||||
|
t(f->t),
|
||||||
|
c(f->c),
|
||||||
|
method(f->method),
|
||||||
|
map(map),
|
||||||
|
objectPool(f->objectPool),
|
||||||
|
codeMask(f->codeMask),
|
||||||
|
sp(f->sp),
|
||||||
|
protector(t, this)
|
||||||
|
{
|
||||||
|
memcpy(map, f->map, mapSizeInBytes(t, method));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Frame() {
|
||||||
|
t->m->system->free(codeMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* append(object o) {
|
||||||
|
Operand* result = c->append(c->constant(0));
|
||||||
|
objectPool->appendAddress(c->poolOffset(result));
|
||||||
|
objectPool->appendAddress(o);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned parameterFootprint(Thread* t, object method) {
|
||||||
|
return methodParameterFootprint(t, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned localSize(Thread* t, object method) {
|
||||||
|
return codeMaxLocals(t, methodCode(t, method))
|
||||||
|
- parameterFootprint(t, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned stackSize(Thread* t, object method) {
|
||||||
|
return codeMaxStack(t, methodCode(t, method));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned mapSize(Thread* t, object method) {
|
||||||
|
return stackSize(t, method) + localSize(t, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned mapSizeInWords(Thread* t, object method) {
|
||||||
|
return ceiling(mapSize(t, method), BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned mapSizeInBytes(Thread* t, object method) {
|
||||||
|
return mapSizeInWords(t, method) * BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushedInt() {
|
||||||
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
|
assert(t, getBit(map, sp) == 0);
|
||||||
|
++ sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushedObject() {
|
||||||
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
|
markBit(map, sp++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void poppedInt() {
|
||||||
|
assert(t, sp >= 1);
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
assert(t, getBit(map, sp - 1) == 0);
|
||||||
|
-- sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void poppedObject() {
|
||||||
|
assert(t, sp >= 1);
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
assert(t, getBit(map, sp - 1) != 0);
|
||||||
|
clearBit(map, -- sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void storedInt(unsigned index) {
|
||||||
|
assert(t, index < localSize());
|
||||||
|
clearBit(map, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void storedObject(unsigned index) {
|
||||||
|
assert(t, index < localSize());
|
||||||
|
markBit(map, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupped() {
|
||||||
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
if (getBit(map, sp - 1)) {
|
||||||
|
markBit(map, sp);
|
||||||
|
}
|
||||||
|
++ sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void duppedX1() {
|
||||||
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 2 >= localSize(t, method));
|
||||||
|
|
||||||
|
unsigned b2 = getBit(map, sp - 2);
|
||||||
|
unsigned b1 = getBit(map, sp - 1);
|
||||||
|
|
||||||
|
if (b2) {
|
||||||
|
markBit(map, sp - 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1) {
|
||||||
|
markBit(map, sp - 2);
|
||||||
|
markBit(map, sp);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
++ sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void duppedX2() {
|
||||||
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 3 >= localSize(t, method));
|
||||||
|
|
||||||
|
unsigned b3 = getBit(map, sp - 3);
|
||||||
|
unsigned b2 = getBit(map, sp - 2);
|
||||||
|
unsigned b1 = getBit(map, sp - 1);
|
||||||
|
|
||||||
|
if (b3) {
|
||||||
|
markBit(map, sp - 2);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b2) {
|
||||||
|
markBit(map, sp - 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1) {
|
||||||
|
markBit(map, sp - 3);
|
||||||
|
markBit(map, sp);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
++ sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupped2() {
|
||||||
|
assert(t, sp + 2 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 2 >= localSize());
|
||||||
|
|
||||||
|
unsigned b2 = getBit(map, sp - 2);
|
||||||
|
unsigned b1 = getBit(map, sp - 1);
|
||||||
|
|
||||||
|
if (b2) {
|
||||||
|
markBit(map, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1) {
|
||||||
|
markBit(map, sp + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupped2X1() {
|
||||||
|
assert(t, sp + 2 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 3 >= localSize(t, method));
|
||||||
|
|
||||||
|
unsigned b3 = getBit(map, sp - 3);
|
||||||
|
unsigned b2 = getBit(map, sp - 2);
|
||||||
|
unsigned b1 = getBit(map, sp - 1);
|
||||||
|
|
||||||
|
if (b3) {
|
||||||
|
markBit(map, sp - 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b2) {
|
||||||
|
markBit(map, sp - 3);
|
||||||
|
markBit(map, sp);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1) {
|
||||||
|
markBit(map, sp - 2);
|
||||||
|
markBit(map, sp + 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupped2X2() {
|
||||||
|
assert(t, sp + 2 <= mapSize(t, method));
|
||||||
|
assert(t, sp - 4 >= localSize(t, method));
|
||||||
|
|
||||||
|
unsigned b4 = getBit(map, sp - 4);
|
||||||
|
unsigned b3 = getBit(map, sp - 3);
|
||||||
|
unsigned b2 = getBit(map, sp - 2);
|
||||||
|
unsigned b1 = getBit(map, sp - 1);
|
||||||
|
|
||||||
|
if (b4) {
|
||||||
|
markBit(map, sp - 2);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b3) {
|
||||||
|
markBit(map, sp - 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b2) {
|
||||||
|
markBit(map, sp - 4);
|
||||||
|
markBit(map, sp);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1) {
|
||||||
|
markBit(map, sp - 3);
|
||||||
|
markBit(map, sp + 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapped() {
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
assert(t, sp - 2 >= localSize(t, method));
|
||||||
|
|
||||||
|
bool savedBit = getBit(map, sp - 1);
|
||||||
|
if (getBit(map, sp - 2)) {
|
||||||
|
markBit(map, sp - 1);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedBit) {
|
||||||
|
markBit(map, sp - 2);
|
||||||
|
} else {
|
||||||
|
clearBit(map, sp - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushInt(Operand* o) {
|
||||||
|
c->push(o);
|
||||||
|
pushedInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushObject(Operand* o) {
|
||||||
|
c->push(o);
|
||||||
|
pushedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushLong(Operand* o) {
|
||||||
|
c->push2(o);
|
||||||
|
pushedInt();
|
||||||
|
pushedInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop(unsigned count) {
|
||||||
|
assert(t, sp >= count);
|
||||||
|
assert(t, sp - count >= localSize());
|
||||||
|
while (count) {
|
||||||
|
clearBit(map, -- sp);
|
||||||
|
-- count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* topInt() {
|
||||||
|
assert(t, sp >= 1);
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
assert(t, getBit(map, sp - 1) == 0);
|
||||||
|
return c->stack(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* topLong() {
|
||||||
|
assert(t, sp >= 2);
|
||||||
|
assert(t, sp - 2 >= localSize(t, method));
|
||||||
|
assert(t, getBit(map, sp - 1) == 0);
|
||||||
|
assert(t, getBit(map, sp - 2) == 0);
|
||||||
|
return c->stack2(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* topObject() {
|
||||||
|
assert(t, sp >= 1);
|
||||||
|
assert(t, sp - 1 >= localSize(t, method));
|
||||||
|
assert(t, getBit(map, sp - 1) != 0);
|
||||||
|
return c->stack(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* popInt() {
|
||||||
|
poppedInt();
|
||||||
|
return c->pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* popLong() {
|
||||||
|
poppedInt();
|
||||||
|
poppedInt();
|
||||||
|
return c->pop2();
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* popObject() {
|
||||||
|
poppedObject();
|
||||||
|
return c->pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void popInt(Operand* o) {
|
||||||
|
c->pop(o);
|
||||||
|
poppedInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void popLong(Operand* o) {
|
||||||
|
c->pop2(o);
|
||||||
|
poppedInt();
|
||||||
|
poppedInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void popObject(Operand* o) {
|
||||||
|
c->pop(o);
|
||||||
|
poppedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadInt(unsigned index) {
|
||||||
|
pushInt(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadLong(unsigned index) {
|
||||||
|
pushLong(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadObject(unsigned index) {
|
||||||
|
pushObject(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeInt(unsigned index) {
|
||||||
|
popInt(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
storedInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeLong(unsigned index) {
|
||||||
|
popLong(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
storedInt(index);
|
||||||
|
storedInt(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeObject(unsigned index) {
|
||||||
|
popObject(c->offset(c->base(), localOffset(t, index, method)));
|
||||||
|
storedObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dup() {
|
||||||
|
c->push(c->stack(0));
|
||||||
|
dupped();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupX1() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
Operand* b = c->stack(1);
|
||||||
|
|
||||||
|
c->mov(a, b);
|
||||||
|
c->mov(b, a);
|
||||||
|
c->push(a);
|
||||||
|
|
||||||
|
duppedX1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dupX2() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
Operand* b = c->stack(1);
|
||||||
|
Operand* c = c->stack(2);
|
||||||
|
|
||||||
|
c->mov(a, c);
|
||||||
|
c->mov(c, b);
|
||||||
|
c->mov(b, a);
|
||||||
|
c->push(a);
|
||||||
|
|
||||||
|
duppedX2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dup2() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
|
||||||
|
c->push(a);
|
||||||
|
c->push(a);
|
||||||
|
|
||||||
|
dupped2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dup2X1() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
Operand* b = c->stack(1);
|
||||||
|
Operand* c = c->stack(2);
|
||||||
|
|
||||||
|
c->mov(b, c);
|
||||||
|
c->mov(a, b);
|
||||||
|
c->mov(c, a);
|
||||||
|
c->push(b);
|
||||||
|
c->push(a);
|
||||||
|
|
||||||
|
dupped2X1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dup2X2() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
Operand* b = c->stack(1);
|
||||||
|
Operand* c = c->stack(2);
|
||||||
|
Operand* d = c->stack(3);
|
||||||
|
|
||||||
|
c->mov(b, d);
|
||||||
|
c->mov(a, c);
|
||||||
|
c->mov(d, b);
|
||||||
|
c->mov(c, a);
|
||||||
|
c->push(b);
|
||||||
|
c->push(a);
|
||||||
|
|
||||||
|
dupped2X2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap() {
|
||||||
|
Operand* a = c->stack(0);
|
||||||
|
Operand* b = c->stack(1);
|
||||||
|
Operand* tmp = c->temporary();
|
||||||
|
|
||||||
|
c->mov(a, tmp);
|
||||||
|
c->mov(b, a);
|
||||||
|
c->mov(tmp, b);
|
||||||
|
|
||||||
|
swapped();
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame* next;
|
||||||
|
MyThread* t;
|
||||||
|
Compiler* c;
|
||||||
|
object method;
|
||||||
|
Buffer* objectPool;
|
||||||
|
uintptr_t codeMask;
|
||||||
|
unsigned sp;
|
||||||
|
MyProtector protector;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
compileThrowNew(MyThread* t, Frame* frame, Machine::Type type)
|
||||||
|
{
|
||||||
|
Operand* class_ = frame->append(arrayBody(t, t->m->types, type));
|
||||||
|
c->indirectCallNoReturn(throwNew, 2, frame->c->thread(), class_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compileThrowNew(MyThread* t, Compiler* c, Buffer* objectPool,
|
pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result)
|
||||||
Machine::Type type)
|
|
||||||
{
|
|
||||||
Operand* class_ = add(c, objectPool, arrayBody(t, t->m->types, type));
|
|
||||||
c->indirectCallNoReturn(throwNew, 2, c->thread(), class_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pushReturnValue(MyThread* t, Frame* f, unsigned code, Operand* result)
|
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -48,9 +532,10 @@ pushReturnValue(MyThread* t, Frame* f, unsigned code, Operand* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compileDirectInvoke(MyThread* t, Compiler* c, Frame* frame, object target)
|
compileDirectInvoke(MyThread* t, Frame* frame, object target)
|
||||||
{
|
{
|
||||||
Operand* result = c->alignedCall(compiledCode(methodCompiled(t, target)));
|
Operand* result = frame->c->alignedCall
|
||||||
|
(compiledCode(methodCompiled(t, target)));
|
||||||
|
|
||||||
frame->pop(methodParameterFootprint(t, target));
|
frame->pop(methodParameterFootprint(t, target));
|
||||||
|
|
||||||
@ -58,13 +543,14 @@ compileDirectInvoke(MyThread* t, Compiler* c, Frame* frame, object target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
||||||
uintptr_t* codeMask, Buffer* objectPool, unsigned ip)
|
|
||||||
{
|
{
|
||||||
Frame myFrame(initialFrame);
|
uintptr_t map[Frame::mapSizeInWords(t, initialFrame->method)];
|
||||||
|
Frame myFrame(initialFrame, map);
|
||||||
Frame* frame = &myFrame;
|
Frame* frame = &myFrame;
|
||||||
|
Compiler* c = frame->c;
|
||||||
|
|
||||||
object code = methodCode(t, method);
|
object code = methodCode(t, frame->method);
|
||||||
PROTECT(t, code);
|
PROTECT(t, code);
|
||||||
|
|
||||||
while (ip < codeLength(t, code)) {
|
while (ip < codeLength(t, code)) {
|
||||||
@ -142,8 +628,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->jmp(next);
|
c->jmp(next);
|
||||||
|
|
||||||
c->mark(outOfBounds);
|
c->mark(outOfBounds);
|
||||||
compileThrowNew(t, c, objectPool,
|
compileThrowNew(t, frame, Machine::ArrayIndexOutOfBoundsExceptionType);
|
||||||
Machine::ArrayIndexOutOfBoundsExceptionType);
|
|
||||||
|
|
||||||
c->mark(next);
|
c->mark(next);
|
||||||
} break;
|
} break;
|
||||||
@ -219,8 +704,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
c->mark(outOfBounds);
|
c->mark(outOfBounds);
|
||||||
compileThrowNew(t, c, objectPool,
|
compileThrowNew(t, frame, Machine::ArrayIndexOutOfBoundsExceptionType);
|
||||||
Machine::ArrayIndexOutOfBoundsExceptionType);
|
|
||||||
|
|
||||||
c->mark(next);
|
c->mark(next);
|
||||||
} break;
|
} break;
|
||||||
@ -261,13 +745,12 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->cmp(c->constant(0), length);
|
c->cmp(c->constant(0), length);
|
||||||
jge(nonnegative);
|
jge(nonnegative);
|
||||||
|
|
||||||
compileThrowNew(t, c, objectPool,
|
compileThrowNew(t, frame, Machine::NegativeArraySizeExceptionType);
|
||||||
Machine::NegativeArraySizeExceptionType);
|
|
||||||
|
|
||||||
c->mark(nonnegative);
|
c->mark(nonnegative);
|
||||||
|
|
||||||
c->indirectCall(makeBlankObjectArray, 3,
|
c->indirectCall(makeBlankObjectArray, 3,
|
||||||
c->thread(), add(c, objectPool, class_), length);
|
c->thread(), frame->append(class_), length);
|
||||||
|
|
||||||
frame->pushObject(array);
|
frame->pushObject(array);
|
||||||
} break;
|
} break;
|
||||||
@ -325,7 +808,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->cmp(c->constant(0), tmp);
|
c->cmp(c->constant(0), tmp);
|
||||||
je(next);
|
je(next);
|
||||||
|
|
||||||
Operand* class_ = add(c, objectPool, class_);
|
Operand* class_ = frame->append(class_);
|
||||||
|
|
||||||
c->mov(c->dereference(tmp), tmp);
|
c->mov(c->dereference(tmp), tmp);
|
||||||
c->and_(c->constant(PointerMask), tmp);
|
c->and_(c->constant(PointerMask), tmp);
|
||||||
@ -338,7 +821,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
cmp(0, result);
|
cmp(0, result);
|
||||||
jne(next);
|
jne(next);
|
||||||
|
|
||||||
compileThrowNew(t, c, objectPool, Machine::ClassCastExceptionType);
|
compileThrowNew(t, frame, Machine::ClassCastExceptionType);
|
||||||
|
|
||||||
c->mark(next);
|
c->mark(next);
|
||||||
} break;
|
} break;
|
||||||
@ -524,7 +1007,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
initClass(t, fieldClass(t, field));
|
initClass(t, fieldClass(t, field));
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
table = add(c, objectPool, classStaticTable(t, fieldClass(t, field)));
|
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
||||||
} else {
|
} else {
|
||||||
table = frame->popObject();
|
table = frame->popObject();
|
||||||
}
|
}
|
||||||
@ -666,7 +1149,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->jne(target);
|
c->jne(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -705,7 +1188,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -742,7 +1225,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -760,7 +1243,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->jne(target);
|
c->jne(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -820,7 +1303,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->cmp(c->constant(0), tmp);
|
c->cmp(c->constant(0), tmp);
|
||||||
je(zero);
|
je(zero);
|
||||||
|
|
||||||
Operand* class_ = add(c, objectPool, class_);
|
Operand* class_ = frame->append(class_);
|
||||||
|
|
||||||
c->mov(c->dereference(tmp), tmp);
|
c->mov(c->dereference(tmp), tmp);
|
||||||
c->and_(c->constant(PointerMask), tmp);
|
c->and_(c->constant(PointerMask), tmp);
|
||||||
@ -849,21 +1332,20 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
unsigned parameterFootprint
|
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
||||||
= methodParameterFootprint(t, target) * BytesPerWord;
|
|
||||||
|
|
||||||
unsigned instance = parameterFootprint - BytesPerWord;
|
unsigned instance = parameterFootprint - 1;
|
||||||
|
|
||||||
Operand* found = c->directCall(findInterfaceMethodFromInstance, 3,
|
Operand* found = c->directCall(findInterfaceMethodFromInstance, 3,
|
||||||
t->thread(),
|
t->thread(),
|
||||||
add(c, objectPool, target),
|
frame->append(target),
|
||||||
c->offset(t->stack(), instance));
|
c->stack(instance));
|
||||||
|
|
||||||
c->mov(c->offset(found, MethodCompiled), found);
|
c->mov(c->offset(found, MethodCompiled), found);
|
||||||
|
|
||||||
Operand* result = c->call(c->offset(found, CompiledBody));
|
Operand* result = c->call(c->offset(found, CompiledBody));
|
||||||
|
|
||||||
frame->pop(methodParameterFootprint(t, target));
|
frame->pop(parameterFootprint);
|
||||||
|
|
||||||
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
||||||
} break;
|
} break;
|
||||||
@ -879,7 +1361,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
target = findMethod(t, target, classSuper(t, class_));
|
target = findMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
compileDirectInvoke(t, c, frame, target);
|
compileDirectInvoke(t, frame, target);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case invokestatic: {
|
case invokestatic: {
|
||||||
@ -892,7 +1374,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
initClass(t, methodClass(t, target));
|
initClass(t, methodClass(t, target));
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
compileDirectInvoke(t, c, frame, target);
|
compileDirectInvoke(t, frame, target);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case invokevirtual: {
|
case invokevirtual: {
|
||||||
@ -901,14 +1383,13 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
unsigned parameterFootprint
|
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
||||||
= methodParameterFootprint(t, target) * BytesPerWord;
|
|
||||||
|
|
||||||
unsigned instance = parameterFootprint - BytesPerWord;
|
unsigned instance = parameterFootprint - 1;
|
||||||
|
|
||||||
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
|
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
|
||||||
|
|
||||||
Operand* instance = c->offset(c->stack(), instance);
|
Operand* instance = c->stack(instance);
|
||||||
Operand* class_ = c->temporary();
|
Operand* class_ = c->temporary();
|
||||||
|
|
||||||
c->mov(c->dereference(instance), class_);
|
c->mov(c->dereference(instance), class_);
|
||||||
@ -916,7 +1397,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
|
|
||||||
Operand* result = c->call(c->offset(class_, offset));
|
Operand* result = c->call(c->offset(class_, offset));
|
||||||
|
|
||||||
frame->pop(methodParameterFootprint(t, target));
|
frame->pop(parameterFootprint);
|
||||||
|
|
||||||
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
pushReturnValue(t, frame, methodReturnCode(t, target), result);
|
||||||
} break;
|
} break;
|
||||||
@ -1056,9 +1537,9 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
object class_ = resolveClassInPool(t, pool, index - 1);
|
object class_ = resolveClassInPool(t, pool, index - 1);
|
||||||
if (UNLIKELY(exception)) return;
|
if (UNLIKELY(exception)) return;
|
||||||
|
|
||||||
frame->pushObject(add(c, objectPool, class_));
|
frame->pushObject(frame->append(class_));
|
||||||
} else {
|
} else {
|
||||||
frame->pushObject(add(c, objectPool, v));
|
frame->pushObject(frame->append(v));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
frame->pushInt(c->constant(singletonValue(t, pool, index - 1)));
|
frame->pushInt(c->constant(singletonValue(t, pool, index - 1)));
|
||||||
@ -1124,7 +1605,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
||||||
assert(t, defaultIp < codeLength(t, code));
|
assert(t, defaultIp < codeLength(t, code));
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, defaultIp);
|
compile(t, frame, defaultIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
||||||
@ -1138,7 +1619,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
int32_t newIp = base + codeReadInt32(t, code, index);
|
int32_t newIp = base + codeReadInt32(t, code, index);
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
Operand* result = c->append(c->constant(key));
|
Operand* result = c->append(c->constant(key));
|
||||||
@ -1240,7 +1721,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
Operand* result = c->indirectCall
|
Operand* result = c->indirectCall
|
||||||
(makeMultidimensionalArray, 3,
|
(makeMultidimensionalArray, 3,
|
||||||
c->thread(),
|
c->thread(),
|
||||||
c->offset(c->stack(), dimensions - 1),
|
c->stack(dimensions - 1),
|
||||||
c->constant(dimensions));
|
c->constant(dimensions));
|
||||||
|
|
||||||
frame->pop(dimensions);
|
frame->pop(dimensions);
|
||||||
@ -1261,11 +1742,11 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
||||||
result = c->indirectCall(makeNewWeakReference, 2,
|
result = c->indirectCall(makeNewWeakReference, 2,
|
||||||
c->thread(),
|
c->thread(),
|
||||||
add(c, objectPool, class_));
|
frame->append(class_));
|
||||||
} else {
|
} else {
|
||||||
result = c->indirectCall(makeNew, 2,
|
result = c->indirectCall(makeNew, 2,
|
||||||
c->thread(),
|
c->thread(),
|
||||||
add(c, objectPool, class_));
|
frame->append(class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->pushObject(result);
|
frame->pushObject(result);
|
||||||
@ -1280,8 +1761,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->cmp(0, size);
|
c->cmp(0, size);
|
||||||
c->jge(nonnegative);
|
c->jge(nonnegative);
|
||||||
|
|
||||||
compileThrowNew(t, c, objectPool,
|
compileThrowNew(t, frame, Machine::NegativeArraySizeExceptionType);
|
||||||
Machine::NegativeArraySizeExceptionType);
|
|
||||||
|
|
||||||
c->mark(nonnegative);
|
c->mark(nonnegative);
|
||||||
|
|
||||||
@ -1379,7 +1859,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
Operand* table;
|
Operand* table;
|
||||||
|
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
table = add(c, objectPool, staticTable);
|
table = frame->append(staticTable);
|
||||||
} else {
|
} else {
|
||||||
table = frame->popObject();
|
table = frame->popObject();
|
||||||
}
|
}
|
||||||
@ -1437,7 +1917,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
||||||
assert(t, defaultIp < codeLength(t, code));
|
assert(t, defaultIp < codeLength(t, code));
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, defaultIp);
|
compile(t, frame, defaultIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
||||||
@ -1451,7 +1931,7 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
int32_t newIp = base + codeReadInt32(t, code, index);
|
int32_t newIp = base + codeReadInt32(t, code, index);
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
compile(t, frame, newIp);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
Operand* result = c->append(c->logicalIp(newIp));
|
Operand* result = c->append(c->logicalIp(newIp));
|
||||||
@ -1534,35 +2014,11 @@ compile(MyThread* t, Compiler* compiler, object method)
|
|||||||
|
|
||||||
compiler->prologue(parameterFootptrint, localFootprint);
|
compiler->prologue(parameterFootptrint, localFootprint);
|
||||||
|
|
||||||
unsigned codeMaskSize
|
|
||||||
= ceiling(codeLength(t, code), BytesPerWord)
|
|
||||||
* BytesPerWord;
|
|
||||||
|
|
||||||
uintptr_t* codeMask = static_cast<uintptr_t*>
|
|
||||||
(t->m->system->allocate(codeMaskSize));
|
|
||||||
|
|
||||||
RESOURCE(t, codeMask);
|
|
||||||
|
|
||||||
memset(codeMask, 0, codeMaskSize);
|
|
||||||
|
|
||||||
Buffer objectPool;
|
Buffer objectPool;
|
||||||
|
uintptr_t map[Frame::mapSizeInWords(t, method)];
|
||||||
|
Frame frame(t, compiler, method, map, objectPool);
|
||||||
|
|
||||||
class MyProtector: public Thread::Protector {
|
compile(t, &frame, 0);
|
||||||
public:
|
|
||||||
MyProtector(MyThread* t, Buffer* pool): Protector(t), pool(pool) { }
|
|
||||||
|
|
||||||
virtual void visit(Heap::Visitor* v) {
|
|
||||||
for (unsigned i = 1; i < pool->length(); i += BytesPerWord * 2) {
|
|
||||||
v->visit(reinterpret_cast<object*>(&(pool->getAddress(i))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer* pool;
|
|
||||||
} protector(t, objectPool);
|
|
||||||
|
|
||||||
Frame frame(compiler);
|
|
||||||
|
|
||||||
compile(t, c, &stack, method, codeMask, &objectPool, 0);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
object eht = codeExceptionHandlerTable(t, methodCode(t, method));
|
object eht = codeExceptionHandlerTable(t, methodCode(t, method));
|
||||||
@ -1575,10 +2031,10 @@ compile(MyThread* t, Compiler* compiler, object method)
|
|||||||
assert(t, getBit(codeMask, exceptionHandlerStart(eh)));
|
assert(t, getBit(codeMask, exceptionHandlerStart(eh)));
|
||||||
|
|
||||||
Frame frame2(&frame);
|
Frame frame2(&frame);
|
||||||
stack2.pushObject();
|
frame2.pushObject();
|
||||||
|
|
||||||
compile(t, c, &stack, method, codeMask, &objectPool,
|
compile(t, &frame2, exceptionHandlerIp(eh));
|
||||||
exceptionHandlerIp(eh));
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user