mirror of
https://github.com/corda/corda.git
synced 2025-01-05 20:54:13 +00:00
lots of JIT bugfixes and a few new instructions
This commit is contained in:
parent
fe24005ff0
commit
b2147c2c99
185
src/compile.cpp
185
src/compile.cpp
@ -67,7 +67,7 @@ resolveTarget(MyThread* t, void* stack, object method)
|
|||||||
if (methodVirtual(t, method)) {
|
if (methodVirtual(t, method)) {
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
object class_ = objectClass
|
object class_ = objectClass
|
||||||
(t, reinterpret_cast<object*>(stack)[parameterFootprint + 1]);
|
(t, reinterpret_cast<object*>(stack)[parameterFootprint]);
|
||||||
|
|
||||||
if (classVmFlags(t, class_) & BootstrapFlag) {
|
if (classVmFlags(t, class_) & BootstrapFlag) {
|
||||||
resolveClass(t, className(t, class_));
|
resolveClass(t, className(t, class_));
|
||||||
@ -366,6 +366,15 @@ class Frame {
|
|||||||
assert(t, sp + 1 <= mapSize(t, method));
|
assert(t, sp + 1 <= mapSize(t, method));
|
||||||
markBit(map, sp++);
|
markBit(map, sp++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void popped(unsigned count) {
|
||||||
|
assert(t, sp >= count);
|
||||||
|
assert(t, sp - count >= localSize(t, method));
|
||||||
|
while (count) {
|
||||||
|
clearBit(map, -- sp);
|
||||||
|
-- count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void poppedInt() {
|
void poppedInt() {
|
||||||
assert(t, sp >= 1);
|
assert(t, sp >= 1);
|
||||||
@ -587,6 +596,11 @@ class Frame {
|
|||||||
pushedObject();
|
pushedObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pushObject() {
|
||||||
|
c->push(1);
|
||||||
|
pushedObject();
|
||||||
|
}
|
||||||
|
|
||||||
void pushLong(Operand* o) {
|
void pushLong(Operand* o) {
|
||||||
c->push2(o);
|
c->push2(o);
|
||||||
pushedInt();
|
pushedInt();
|
||||||
@ -594,12 +608,8 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pop(unsigned count) {
|
void pop(unsigned count) {
|
||||||
assert(t, sp >= count);
|
popped(count);
|
||||||
assert(t, sp - count >= localSize(t, method));
|
c->pop(count);
|
||||||
while (count) {
|
|
||||||
clearBit(map, -- sp);
|
|
||||||
-- count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand* topInt() {
|
Operand* topInt() {
|
||||||
@ -1276,6 +1286,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->release(index);
|
||||||
|
c->release(array);
|
||||||
|
|
||||||
c->jmp(next);
|
c->jmp(next);
|
||||||
|
|
||||||
c->mark(outOfBounds);
|
c->mark(outOfBounds);
|
||||||
@ -1345,6 +1358,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->release(value);
|
||||||
|
c->release(index);
|
||||||
|
c->release(array);
|
||||||
|
|
||||||
c->jmp(next);
|
c->jmp(next);
|
||||||
|
|
||||||
c->mark(outOfBounds);
|
c->mark(outOfBounds);
|
||||||
@ -1397,18 +1414,24 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
(c->constant(reinterpret_cast<intptr_t>(makeBlankObjectArray)),
|
(c->constant(reinterpret_cast<intptr_t>(makeBlankObjectArray)),
|
||||||
3, c->thread(), frame->append(class_), length);
|
3, c->thread(), frame->append(class_), length);
|
||||||
|
|
||||||
|
c->release(length);
|
||||||
|
|
||||||
frame->trace();
|
frame->trace();
|
||||||
|
|
||||||
frame->pushObject(r);
|
frame->pushObject(r);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case areturn:
|
case areturn: {
|
||||||
c->return_(frame->popObject());
|
Operand* result = frame->popObject();
|
||||||
return;
|
c->return_(result);
|
||||||
|
c->release(result);
|
||||||
|
} return;
|
||||||
|
|
||||||
case arraylength:
|
case arraylength: {
|
||||||
frame->pushInt(c->memory(frame->popObject(), ArrayLength));
|
Operand* array = frame->popObject();
|
||||||
break;
|
frame->pushInt(c->memory(array, ArrayLength));
|
||||||
|
c->release(array);
|
||||||
|
} break;
|
||||||
|
|
||||||
case astore:
|
case astore:
|
||||||
frame->storeObject(codeBody(t, code, ip++));
|
frame->storeObject(codeBody(t, code, ip++));
|
||||||
@ -1430,13 +1453,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->storeObject(3);
|
frame->storeObject(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case athrow:
|
case athrow: {
|
||||||
|
Operand* e = frame->popObject();
|
||||||
c->indirectCallNoReturn
|
c->indirectCallNoReturn
|
||||||
(c->constant(reinterpret_cast<intptr_t>(throw_)),
|
(c->constant(reinterpret_cast<intptr_t>(throw_)),
|
||||||
2, c->thread(), frame->popObject());
|
2, c->thread(), e);
|
||||||
|
c->release(e);
|
||||||
|
|
||||||
frame->trace();
|
frame->trace();
|
||||||
break;
|
} return;
|
||||||
|
|
||||||
case bipush:
|
case bipush:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
@ -1486,6 +1511,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToFloat)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(doubleToFloat)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2i: {
|
case d2i: {
|
||||||
@ -1493,6 +1519,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToInt)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(doubleToInt)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2l: {
|
case d2l: {
|
||||||
@ -1500,6 +1527,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToLong)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(doubleToLong)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dadd: {
|
case dadd: {
|
||||||
@ -1508,6 +1536,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(addDouble)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(addDouble)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpg: {
|
case dcmpg: {
|
||||||
@ -1516,6 +1546,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareDoublesG)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(compareDoublesG)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpl: {
|
case dcmpl: {
|
||||||
@ -1524,6 +1556,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareDoublesL)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(compareDoublesL)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dconst_0:
|
case dconst_0:
|
||||||
@ -1540,6 +1574,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(divideDouble)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(divideDouble)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dmul: {
|
case dmul: {
|
||||||
@ -1548,6 +1584,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(multiplyDouble)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(multiplyDouble)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dneg: {
|
case dneg: {
|
||||||
@ -1555,6 +1593,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(negateDouble)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(negateDouble)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::drem: {
|
case vm::drem: {
|
||||||
@ -1563,6 +1602,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(moduloDouble)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(moduloDouble)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dsub: {
|
case dsub: {
|
||||||
@ -1571,6 +1612,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(subtractDouble)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(subtractDouble)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dup:
|
case dup:
|
||||||
@ -1602,6 +1645,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToDouble)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(floatToDouble)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2i: {
|
case f2i: {
|
||||||
@ -1609,6 +1653,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToInt)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(floatToInt)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2l: {
|
case f2l: {
|
||||||
@ -1616,6 +1661,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToLong)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(floatToLong)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fadd: {
|
case fadd: {
|
||||||
@ -1624,6 +1670,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(addFloat)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(addFloat)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpg: {
|
case fcmpg: {
|
||||||
@ -1632,6 +1680,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareFloatsG)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(compareFloatsG)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpl: {
|
case fcmpl: {
|
||||||
@ -1640,6 +1690,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareFloatsL)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(compareFloatsL)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fconst_0:
|
case fconst_0:
|
||||||
@ -1660,6 +1712,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(divideFloat)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(divideFloat)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fmul: {
|
case fmul: {
|
||||||
@ -1668,6 +1722,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(multiplyFloat)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(multiplyFloat)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fneg: {
|
case fneg: {
|
||||||
@ -1675,6 +1731,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(negateFloat)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(negateFloat)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::frem: {
|
case vm::frem: {
|
||||||
@ -1683,6 +1740,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(moduloFloat)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(moduloFloat)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fsub: {
|
case fsub: {
|
||||||
@ -1691,6 +1750,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(subtractFloat)), 2, a, b));
|
(c->constant(reinterpret_cast<intptr_t>(subtractFloat)), 2, a, b));
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case getfield:
|
case getfield:
|
||||||
@ -1742,6 +1803,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
default:
|
default:
|
||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instruction != getstatic) {
|
||||||
|
c->release(table);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case goto_: {
|
case goto_: {
|
||||||
@ -1775,6 +1840,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(intToDouble)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(intToDouble)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2f: {
|
case i2f: {
|
||||||
@ -1782,11 +1848,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(intToFloat)), 1, a));
|
(c->constant(reinterpret_cast<intptr_t>(intToFloat)), 1, a));
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2l:
|
case i2l: {
|
||||||
frame->pushLong(frame->popInt());
|
Operand* a = frame->popInt();
|
||||||
break;
|
frame->pushLong(a);
|
||||||
|
c->release(a);
|
||||||
|
} break;
|
||||||
|
|
||||||
case i2s: {
|
case i2s: {
|
||||||
Operand* top = frame->topInt();
|
Operand* top = frame->topInt();
|
||||||
@ -1796,11 +1865,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case iadd: {
|
case iadd: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->add(a, frame->topInt());
|
c->add(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iand: {
|
case iand: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->and_(a, frame->topInt());
|
c->and_(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iconst_m1:
|
case iconst_m1:
|
||||||
@ -1834,6 +1905,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case idiv: {
|
case idiv: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->div(a, frame->topInt());
|
c->div(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case if_acmpeq:
|
case if_acmpeq:
|
||||||
@ -1844,6 +1916,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
Operand* a = frame->popObject();
|
Operand* a = frame->popObject();
|
||||||
Operand* b = frame->popObject();
|
Operand* b = frame->popObject();
|
||||||
c->cmp(a, b);
|
c->cmp(a, b);
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
|
|
||||||
Operand* target = c->logicalIp(newIp);
|
Operand* target = c->logicalIp(newIp);
|
||||||
if (instruction == if_acmpeq) {
|
if (instruction == if_acmpeq) {
|
||||||
@ -1868,6 +1942,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
Operand* b = frame->popInt();
|
Operand* b = frame->popInt();
|
||||||
c->cmp(a, b);
|
c->cmp(a, b);
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
|
|
||||||
Operand* target = c->logicalIp(newIp);
|
Operand* target = c->logicalIp(newIp);
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
@ -1904,7 +1980,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
uint32_t newIp = (ip - 3) + codeReadInt16(t, code, ip);
|
uint32_t newIp = (ip - 3) + codeReadInt16(t, code, ip);
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
c->cmp(0, frame->popInt());
|
Operand* a = frame->popInt();
|
||||||
|
c->cmp(c->constant(0), a);
|
||||||
|
c->release(a);
|
||||||
|
|
||||||
Operand* target = c->logicalIp(newIp);
|
Operand* target = c->logicalIp(newIp);
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
@ -1937,7 +2015,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
uint32_t newIp = (ip - 3) + codeReadInt16(t, code, ip);
|
uint32_t newIp = (ip - 3) + codeReadInt16(t, code, ip);
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
c->cmp(0, frame->popObject());
|
Operand* a = frame->popInt();
|
||||||
|
c->cmp(c->constant(0), a);
|
||||||
|
c->release(a);
|
||||||
|
|
||||||
Operand* target = c->logicalIp(newIp);
|
Operand* target = c->logicalIp(newIp);
|
||||||
if (instruction == ifnull) {
|
if (instruction == ifnull) {
|
||||||
@ -1985,6 +2065,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case imul: {
|
case imul: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->mul(a, frame->topInt());
|
c->mul(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case instanceof: {
|
case instanceof: {
|
||||||
@ -2120,11 +2201,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case ior: {
|
case ior: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->or_(a, frame->topInt());
|
c->or_(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case irem: {
|
case irem: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->rem(a, frame->topInt());
|
c->rem(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ireturn:
|
case ireturn:
|
||||||
@ -2135,11 +2218,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case ishl: {
|
case ishl: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->shl(a, frame->topInt());
|
c->shl(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ishr: {
|
case ishr: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->shr(a, frame->topInt());
|
c->shr(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case istore:
|
case istore:
|
||||||
@ -2170,16 +2255,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case isub: {
|
case isub: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->sub(a, frame->topInt());
|
c->sub(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iushr: {
|
case iushr: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->ushr(a, frame->topInt());
|
c->ushr(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ixor: {
|
case ixor: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->xor_(a, frame->topInt());
|
c->xor_(a, frame->topInt());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case jsr:
|
case jsr:
|
||||||
@ -2195,6 +2283,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case ladd: {
|
case ladd: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->sub(a, frame->topLong());
|
c->sub(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lcmp: {
|
case lcmp: {
|
||||||
@ -2207,6 +2296,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
Operand* result = c->temporary();
|
Operand* result = c->temporary();
|
||||||
|
|
||||||
c->cmp(a, b);
|
c->cmp(a, b);
|
||||||
|
c->release(a);
|
||||||
|
c->release(b);
|
||||||
|
|
||||||
c->jl(less);
|
c->jl(less);
|
||||||
c->jg(greater);
|
c->jg(greater);
|
||||||
|
|
||||||
@ -2276,6 +2368,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case ldiv_: {
|
case ldiv_: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->div(a, frame->topLong());
|
c->div(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lload:
|
case lload:
|
||||||
@ -2306,6 +2399,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case lmul: {
|
case lmul: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->mul(a, frame->topLong());
|
c->mul(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lneg:
|
case lneg:
|
||||||
@ -2351,31 +2445,39 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
(c->directCall
|
(c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(lookUpAddress)),
|
(c->constant(reinterpret_cast<intptr_t>(lookUpAddress)),
|
||||||
4, key, start, c->constant(pairCount), default_));
|
4, key, start, c->constant(pairCount), default_));
|
||||||
|
|
||||||
|
c->release(key);
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
case lor: {
|
case lor: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->or_(a, frame->topLong());
|
c->or_(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lrem: {
|
case lrem: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->rem(a, frame->topLong());
|
c->rem(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lreturn:
|
case lreturn:
|
||||||
case dreturn:
|
case dreturn: {
|
||||||
|
Operand* a = frame->popLong();
|
||||||
c->return_(frame->popLong());
|
c->return_(frame->popLong());
|
||||||
return;
|
c->release(a);
|
||||||
|
} return;
|
||||||
|
|
||||||
case lshl: {
|
case lshl: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->shl(a, frame->topLong());
|
c->shl(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lshr: {
|
case lshr: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->shr(a, frame->topLong());
|
c->shr(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lstore:
|
case lstore:
|
||||||
@ -2406,30 +2508,37 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case lsub: {
|
case lsub: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->sub(a, frame->topLong());
|
c->sub(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lushr: {
|
case lushr: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->ushr(a, frame->topLong());
|
c->ushr(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lxor: {
|
case lxor: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
c->xor_(a, frame->topLong());
|
c->xor_(a, frame->topLong());
|
||||||
|
c->release(a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case monitorenter: {
|
case monitorenter: {
|
||||||
|
Operand* a = frame->popObject();
|
||||||
c->indirectCall
|
c->indirectCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(acquireMonitorForObject)),
|
(c->constant(reinterpret_cast<intptr_t>(acquireMonitorForObject)),
|
||||||
2, c->thread(), frame->popObject());
|
2, c->thread(), a);
|
||||||
|
c->release(a);
|
||||||
|
|
||||||
frame->trace();
|
frame->trace();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case monitorexit: {
|
case monitorexit: {
|
||||||
|
Operand* a = frame->popObject();
|
||||||
c->indirectCall
|
c->indirectCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(releaseMonitorForObject)),
|
(c->constant(reinterpret_cast<intptr_t>(releaseMonitorForObject)),
|
||||||
2, c->thread(), frame->popObject());
|
2, c->thread(), a);
|
||||||
|
c->release(a);
|
||||||
|
|
||||||
frame->trace();
|
frame->trace();
|
||||||
} break;
|
} break;
|
||||||
@ -2486,6 +2595,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
|
|
||||||
Operand* size = frame->popInt();
|
Operand* size = frame->popInt();
|
||||||
c->cmp(0, size);
|
c->cmp(0, size);
|
||||||
|
c->release(size);
|
||||||
|
|
||||||
c->jge(nonnegative);
|
c->jge(nonnegative);
|
||||||
|
|
||||||
compileThrowNew(t, frame, Machine::NegativeArraySizeExceptionType);
|
compileThrowNew(t, frame, Machine::NegativeArraySizeExceptionType);
|
||||||
@ -2582,7 +2693,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ObjectField: {
|
case ObjectField: {
|
||||||
value = frame->popLong();
|
value = frame->popObject();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
@ -2620,11 +2731,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
case ObjectField:
|
case ObjectField:
|
||||||
c->directCall
|
c->directCall
|
||||||
(c->constant(reinterpret_cast<intptr_t>(set)),
|
(c->constant(reinterpret_cast<intptr_t>(set)),
|
||||||
4, c->thread(), table, fieldOffset(t, field), value);
|
4, c->thread(), table, c->constant(fieldOffset(t, field)), value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instruction != putstatic) {
|
||||||
|
c->release(table);
|
||||||
|
}
|
||||||
|
c->release(value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case return_:
|
case return_:
|
||||||
@ -2687,6 +2803,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
|
|
||||||
c->mark(defaultCase);
|
c->mark(defaultCase);
|
||||||
c->jmp(default_);
|
c->jmp(default_);
|
||||||
|
|
||||||
|
c->release(key);
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
case wide: {
|
case wide: {
|
||||||
@ -2884,7 +3002,7 @@ compile(MyThread* t, Compiler* c, object method)
|
|||||||
|
|
||||||
uintptr_t map[Frame::mapSizeInWords(t, method)];
|
uintptr_t map[Frame::mapSizeInWords(t, method)];
|
||||||
Frame frame2(&frame, map);
|
Frame frame2(&frame, map);
|
||||||
frame2.pushedObject();
|
frame2.pushObject();
|
||||||
|
|
||||||
compile(t, &frame2, exceptionHandlerIp(eh));
|
compile(t, &frame2, exceptionHandlerIp(eh));
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
@ -3169,17 +3287,12 @@ compileDefault(MyThread* t, Compiler* c)
|
|||||||
object
|
object
|
||||||
compileNative(MyThread* t, Compiler* c)
|
compileNative(MyThread* t, Compiler* c)
|
||||||
{
|
{
|
||||||
c->prologue();
|
|
||||||
|
|
||||||
c->mov(c->base(), c->memory(c->thread(), difference(&(t->base), t)));
|
c->mov(c->base(), c->memory(c->thread(), difference(&(t->base), t)));
|
||||||
c->mov(c->stack(), c->memory(c->thread(), difference(&(t->stack), t)));
|
c->mov(c->stack(), c->memory(c->thread(), difference(&(t->stack), t)));
|
||||||
|
|
||||||
c->call
|
c->directCall
|
||||||
(c->directCall
|
(c->constant(reinterpret_cast<intptr_t>(invokeNative)), 1, c->thread());
|
||||||
(c->constant(reinterpret_cast<intptr_t>(invokeNative)),
|
|
||||||
1, c->thread()));
|
|
||||||
|
|
||||||
c->epilogue();
|
|
||||||
c->ret();
|
c->ret();
|
||||||
|
|
||||||
return finish(t, c);
|
return finish(t, c);
|
||||||
@ -3698,7 +3811,7 @@ findTraceNode(MyThread* t, void* address)
|
|||||||
& (arrayLength(t, p->addressTable) - 1);
|
& (arrayLength(t, p->addressTable) - 1);
|
||||||
|
|
||||||
for (object n = arrayBody(t, p->addressTable, index);
|
for (object n = arrayBody(t, p->addressTable, index);
|
||||||
n; n = tripleThird(t, n))
|
n; n = traceNodeNext(t, n))
|
||||||
{
|
{
|
||||||
intptr_t k = traceNodeAddress(t, n);
|
intptr_t k = traceNodeAddress(t, n);
|
||||||
|
|
||||||
|
404
src/compiler.cpp
404
src/compiler.cpp
@ -64,7 +64,7 @@ class IpTask {
|
|||||||
virtual ~IpTask() { }
|
virtual ~IpTask() { }
|
||||||
|
|
||||||
virtual void run(Context* c, unsigned ip, unsigned start, unsigned end,
|
virtual void run(Context* c, unsigned ip, unsigned start, unsigned end,
|
||||||
uint8_t* code, unsigned offset) = 0;
|
unsigned offset) = 0;
|
||||||
|
|
||||||
virtual Priority priority() {
|
virtual Priority priority() {
|
||||||
return LowPriority;
|
return LowPriority;
|
||||||
@ -96,32 +96,53 @@ class MyPromise: public Promise {
|
|||||||
public:
|
public:
|
||||||
MyPromise(intptr_t key): key(key) { }
|
MyPromise(intptr_t key): key(key) { }
|
||||||
|
|
||||||
virtual unsigned value(Compiler*);
|
virtual intptr_t value(Compiler*);
|
||||||
|
|
||||||
virtual unsigned value(Context*) = 0;
|
virtual intptr_t value(Context*) = 0;
|
||||||
|
|
||||||
|
virtual bool resolved(Context*) = 0;
|
||||||
|
|
||||||
intptr_t key;
|
intptr_t key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ResolvedPromise: public MyPromise {
|
||||||
|
public:
|
||||||
|
ResolvedPromise(intptr_t key): MyPromise(key) { }
|
||||||
|
|
||||||
|
virtual intptr_t value(Context*) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved(Context*) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class PoolPromise: public MyPromise {
|
class PoolPromise: public MyPromise {
|
||||||
public:
|
public:
|
||||||
PoolPromise(intptr_t key): MyPromise(key) { }
|
PoolPromise(intptr_t key): MyPromise(key) { }
|
||||||
|
|
||||||
virtual unsigned value(Context*);
|
virtual intptr_t value(Context*);
|
||||||
|
virtual bool resolved(Context*);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodePromise: public MyPromise {
|
class CodePromise: public MyPromise {
|
||||||
public:
|
public:
|
||||||
CodePromise(intptr_t key): MyPromise(key) { }
|
CodePromise(intptr_t key, bool absolute):
|
||||||
|
MyPromise(key), absolute(absolute)
|
||||||
|
{ }
|
||||||
|
|
||||||
virtual unsigned value(Context*);
|
virtual intptr_t value(Context*);
|
||||||
|
virtual bool resolved(Context*);
|
||||||
|
|
||||||
|
bool absolute;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodePromiseTask: public IpTask {
|
class CodePromiseTask: public IpTask {
|
||||||
public:
|
public:
|
||||||
CodePromiseTask(CodePromise* p, IpTask* next): IpTask(next), p(p) { }
|
CodePromiseTask(CodePromise* p, IpTask* next): IpTask(next), p(p) { }
|
||||||
|
|
||||||
virtual void run(Context*, unsigned, unsigned start, unsigned, uint8_t*,
|
virtual void run(Context*, unsigned, unsigned start, unsigned,
|
||||||
unsigned offset)
|
unsigned offset)
|
||||||
{
|
{
|
||||||
p->key = offset + (p->key - start);
|
p->key = offset + (p->key - start);
|
||||||
@ -136,9 +157,14 @@ class CodePromiseTask: public IpTask {
|
|||||||
|
|
||||||
class IpPromise: public MyPromise {
|
class IpPromise: public MyPromise {
|
||||||
public:
|
public:
|
||||||
IpPromise(intptr_t key): MyPromise(key) { }
|
IpPromise(intptr_t key, bool absolute):
|
||||||
|
MyPromise(key), absolute(absolute)
|
||||||
|
{ }
|
||||||
|
|
||||||
virtual unsigned value(Context*);
|
virtual intptr_t value(Context*);
|
||||||
|
virtual bool resolved(Context*);
|
||||||
|
|
||||||
|
bool absolute;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyOperand: public Operand {
|
class MyOperand: public Operand {
|
||||||
@ -182,7 +208,7 @@ class MyOperand: public Operand {
|
|||||||
|
|
||||||
virtual void release(Context*) { /* ignore */ }
|
virtual void release(Context*) { /* ignore */ }
|
||||||
|
|
||||||
virtual void setAbsolute(Context* c, intptr_t) { abort(c); }
|
virtual void setImmediate(Context* c, intptr_t) { abort(c); }
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation) { abort(c); }
|
virtual void apply(Context* c, Operation) { abort(c); }
|
||||||
|
|
||||||
@ -229,17 +255,21 @@ class RegisterOperand: public MyOperand {
|
|||||||
|
|
||||||
class ImmediateOperand: public MyOperand {
|
class ImmediateOperand: public MyOperand {
|
||||||
public:
|
public:
|
||||||
ImmediateOperand(intptr_t value):
|
ImmediateOperand(MyPromise* value):
|
||||||
value(value)
|
value(value)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual void setImmediate(Context*, intptr_t v) {
|
||||||
|
value->key = v;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation);
|
virtual void apply(Context* c, Operation operation);
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||||
operand->accept(c, operation, this);
|
operand->accept(c, operation, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t value;
|
MyPromise* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbsoluteOperand: public MyOperand {
|
class AbsoluteOperand: public MyOperand {
|
||||||
@ -254,10 +284,6 @@ class AbsoluteOperand: public MyOperand {
|
|||||||
operand->accept(c, operation, this);
|
operand->accept(c, operation, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setAbsolute(Context*, intptr_t v) {
|
|
||||||
value->key = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyPromise* value;
|
MyPromise* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -358,7 +384,8 @@ class Context {
|
|||||||
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
|
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
|
||||||
stack(0),
|
stack(0),
|
||||||
ipTable(0),
|
ipTable(0),
|
||||||
reserved(0)
|
reserved(0),
|
||||||
|
output(0)
|
||||||
{
|
{
|
||||||
ipMappings.appendAddress
|
ipMappings.appendAddress
|
||||||
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
|
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
|
||||||
@ -390,6 +417,7 @@ class Context {
|
|||||||
StackOperand* stack;
|
StackOperand* stack;
|
||||||
IpMapping** ipTable;
|
IpMapping** ipTable;
|
||||||
unsigned reserved;
|
unsigned reserved;
|
||||||
|
uint8_t* output;
|
||||||
RegisterOperand* registers[RegisterCount];
|
RegisterOperand* registers[RegisterCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -413,10 +441,17 @@ expect(Context* c, bool v)
|
|||||||
expect(c->s, v);
|
expect(c->s, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImmediateOperand*
|
||||||
|
immediate(Context* c, MyPromise* p)
|
||||||
|
{
|
||||||
|
return new (c->zone.allocate(sizeof(ImmediateOperand))) ImmediateOperand(p);
|
||||||
|
}
|
||||||
|
|
||||||
ImmediateOperand*
|
ImmediateOperand*
|
||||||
immediate(Context* c, intptr_t v)
|
immediate(Context* c, intptr_t v)
|
||||||
{
|
{
|
||||||
return new (c->zone.allocate(sizeof(ImmediateOperand))) ImmediateOperand(v);
|
return immediate(c, new (c->zone.allocate(sizeof(ResolvedPromise)))
|
||||||
|
ResolvedPromise(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsoluteOperand*
|
AbsoluteOperand*
|
||||||
@ -463,10 +498,8 @@ temporary(Context* c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
StackOperand*
|
StackOperand*
|
||||||
push(Context* c, MyOperand* v)
|
pushed(Context* c)
|
||||||
{
|
{
|
||||||
v->apply(c, MyOperand::push);
|
|
||||||
|
|
||||||
int index = (c->stack ?
|
int index = (c->stack ?
|
||||||
c->stack->index + (c->stack->footprint() / BytesPerWord) :
|
c->stack->index + (c->stack->footprint() / BytesPerWord) :
|
||||||
0);
|
0);
|
||||||
@ -478,6 +511,36 @@ push(Context* c, MyOperand* v)
|
|||||||
StackOperand(base, index, c->stack);
|
StackOperand(base, index, c->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
push(Context* c, int count)
|
||||||
|
{
|
||||||
|
while (count) {
|
||||||
|
-- count;
|
||||||
|
pushed(c);
|
||||||
|
}
|
||||||
|
immediate(c, count * BytesPerWord)->apply
|
||||||
|
(c, MyOperand::sub, register_(c, rsp));
|
||||||
|
}
|
||||||
|
|
||||||
|
StackOperand*
|
||||||
|
push(Context* c, MyOperand* v)
|
||||||
|
{
|
||||||
|
v->apply(c, MyOperand::push);
|
||||||
|
return pushed(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pop(Context* c, int count)
|
||||||
|
{
|
||||||
|
while (count) {
|
||||||
|
count -= (c->stack->footprint() / BytesPerWord);
|
||||||
|
assert(c, count >= 0);
|
||||||
|
c->stack = c->stack->next;
|
||||||
|
}
|
||||||
|
immediate(c, count * BytesPerWord)->apply
|
||||||
|
(c, MyOperand::add, register_(c, rsp));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pop(Context* c, MyOperand* dst)
|
pop(Context* c, MyOperand* dst)
|
||||||
{
|
{
|
||||||
@ -641,6 +704,12 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
c->code.append(0xc0 | (operand->value << 3) | value);
|
c->code.append(0xc0 | (operand->value << 3) | value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmp:
|
||||||
|
rex(c);
|
||||||
|
c->code.append(0x39);
|
||||||
|
c->code.append(0xc0 | (operand->value << 3) | value);
|
||||||
|
break;
|
||||||
|
|
||||||
case mov:
|
case mov:
|
||||||
if (value != operand->value) {
|
if (value != operand->value) {
|
||||||
rex(c);
|
rex(c);
|
||||||
@ -658,50 +727,66 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
ImmediateOperand* operand)
|
ImmediateOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case add:
|
case add: {
|
||||||
if (operand->value) {
|
intptr_t v = operand->value->value(c);
|
||||||
assert(c, isInt8(operand->value)); // todo
|
if (v) {
|
||||||
|
assert(c, isInt8(v)); // todo
|
||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0x83);
|
c->code.append(0x83);
|
||||||
c->code.append(0xc0 | value);
|
c->code.append(0xc0 | value);
|
||||||
c->code.append(operand->value);
|
c->code.append(v);
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case and_:
|
case and_: {
|
||||||
if (operand->value) {
|
intptr_t v = operand->value->value(c);
|
||||||
|
if (v) {
|
||||||
rex(c);
|
rex(c);
|
||||||
if (isInt8(operand->value)) {
|
if (isInt8(v)) {
|
||||||
c->code.append(0x83);
|
c->code.append(0x83);
|
||||||
c->code.append(0xe0 | value);
|
c->code.append(0xe0 | value);
|
||||||
c->code.append(operand->value);
|
c->code.append(v);
|
||||||
} else {
|
} else {
|
||||||
assert(c, isInt32(operand->value));
|
assert(c, isInt32(v));
|
||||||
|
|
||||||
c->code.append(0x81);
|
c->code.append(0x81);
|
||||||
c->code.append(0xe0 | value);
|
c->code.append(0xe0 | value);
|
||||||
c->code.append(operand->value);
|
c->code.append(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case mov:
|
case cmp: {
|
||||||
|
intptr_t v = operand->value->value(c);
|
||||||
|
if (v) {
|
||||||
|
assert(c, isInt8(v)); // todo
|
||||||
|
|
||||||
|
rex(c);
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xf8 | value);
|
||||||
|
c->code.append(v);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mov: {
|
||||||
|
intptr_t v = operand->value->value(c);
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0xb8 | value);
|
c->code.append(0xb8 | value);
|
||||||
c->code.appendAddress(operand->value);
|
c->code.appendAddress(v);
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case sub:
|
case sub: {
|
||||||
if (operand->value) {
|
intptr_t v = operand->value->value(c);
|
||||||
assert(c, isInt8(operand->value)); // todo
|
if (v) {
|
||||||
|
assert(c, isInt8(v)); // todo
|
||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0x83);
|
c->code.append(0x83);
|
||||||
c->code.append(0xe8 | value);
|
c->code.append(0xe8 | value);
|
||||||
c->code.append(operand->value);
|
c->code.append(v);
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
@ -729,10 +814,10 @@ class AbsoluteMovTask: public IpTask {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void run(Context* c UNUSED, unsigned, unsigned start, unsigned,
|
virtual void run(Context* c UNUSED, unsigned, unsigned start, unsigned,
|
||||||
uint8_t* code, unsigned offset)
|
unsigned offset)
|
||||||
{
|
{
|
||||||
uint8_t* instruction = code + offset + (this->start - start);
|
uint8_t* instruction = c->output + offset + (this->start - start);
|
||||||
intptr_t v = reinterpret_cast<intptr_t>(code + promise->value(c));
|
intptr_t v = reinterpret_cast<intptr_t>(c->output + promise->value(c));
|
||||||
memcpy(instruction + (BytesPerWord / 8) + 1, &v, BytesPerWord);
|
memcpy(instruction + (BytesPerWord / 8) + 1, &v, BytesPerWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,36 +849,47 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectCallTask: public IpTask {
|
class DirectJumpTask: public IpTask {
|
||||||
public:
|
public:
|
||||||
DirectCallTask(unsigned start, uint8_t* address, IpTask* next):
|
DirectJumpTask(unsigned start, unsigned offset, MyPromise* address,
|
||||||
IpTask(next), start(start), address(address)
|
IpTask* next):
|
||||||
|
IpTask(next), start(start), offset(offset), address(address)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void run(Context* c UNUSED, unsigned, unsigned start, unsigned,
|
virtual void run(Context* c UNUSED, unsigned, unsigned start, unsigned,
|
||||||
uint8_t* code, unsigned offset)
|
unsigned offset)
|
||||||
{
|
{
|
||||||
uint8_t* instruction = code + offset + (this->start - start);
|
uint8_t* instruction = c->output + offset + (this->start - start);
|
||||||
assert(c, *instruction == 0xe8);
|
intptr_t v = reinterpret_cast<uint8_t*>(address->value(c))
|
||||||
|
- instruction - 4 - this->offset;
|
||||||
intptr_t v = address - instruction - 5;
|
|
||||||
assert(c, isInt32(v));
|
assert(c, isInt32(v));
|
||||||
|
|
||||||
int32_t v32 = v;
|
int32_t v32 = v;
|
||||||
memcpy(instruction + 1, &v32, 4);
|
memcpy(instruction + this->offset, &v32, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned start;
|
unsigned start;
|
||||||
uint8_t* address;
|
unsigned offset;
|
||||||
|
MyPromise* address;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
addDirectCallTask(Context* c, intptr_t v)
|
addDirectJumpTask(Context* c, unsigned offset, MyPromise* p)
|
||||||
{
|
{
|
||||||
IpMapping* mapping = currentMapping(c);
|
IpMapping* mapping = currentMapping(c);
|
||||||
mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
|
mapping->task = new (c->zone.allocate(sizeof(DirectJumpTask)))
|
||||||
DirectCallTask
|
DirectJumpTask(c->code.length(), offset, p, mapping->task);
|
||||||
(c->code.length(), reinterpret_cast<uint8_t*>(v), mapping->task);
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
immediateConditional(Context* c, unsigned condition,
|
||||||
|
ImmediateOperand* operand)
|
||||||
|
{
|
||||||
|
addDirectJumpTask(c, 2, operand->value);
|
||||||
|
|
||||||
|
c->code.append(0x0f);
|
||||||
|
c->code.append(condition);
|
||||||
|
c->code.append4(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -807,44 +903,83 @@ ImmediateOperand::apply(Context* c, Operation operation)
|
|||||||
apply(c, call);
|
apply(c, call);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case call: {
|
case call:
|
||||||
addDirectCallTask(c, value);
|
addDirectJumpTask(c, 1, value);
|
||||||
|
|
||||||
c->code.append(0xE8);
|
c->code.append(0xe8);
|
||||||
c->code.append4(0);
|
c->code.append4(0);
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case push:
|
case jmp:
|
||||||
if (isInt8(value)) {
|
addDirectJumpTask(c, 1, value);
|
||||||
|
|
||||||
|
c->code.append(0xe9);
|
||||||
|
c->code.append4(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case je:
|
||||||
|
immediateConditional(c, 0x84, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case jne:
|
||||||
|
immediateConditional(c, 0x85, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case jg:
|
||||||
|
immediateConditional(c, 0x8f, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case jge:
|
||||||
|
immediateConditional(c, 0x8d, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case jl:
|
||||||
|
immediateConditional(c, 0x8c, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case jle:
|
||||||
|
immediateConditional(c, 0x8e, this);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case push: {
|
||||||
|
intptr_t v = value->value(c);
|
||||||
|
if (isInt8(v)) {
|
||||||
c->code.append(0x6a);
|
c->code.append(0x6a);
|
||||||
c->code.append(value);
|
c->code.append(v);
|
||||||
} else if (isInt32(value)) {
|
} else if (isInt32(v)) {
|
||||||
c->code.append(0x68);
|
c->code.append(0x68);
|
||||||
c->code.append4(value);
|
c->code.append4(v);
|
||||||
} else {
|
} else {
|
||||||
RegisterOperand* tmp = temporary(c);
|
RegisterOperand* tmp = temporary(c);
|
||||||
tmp->accept(c, mov, this);
|
tmp->accept(c, mov, this);
|
||||||
tmp->apply(c, push);
|
tmp->apply(c, push);
|
||||||
tmp->release(c);
|
tmp->release(c);
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
absoluteApply(Context* c, MyOperand::Operation operation,
|
||||||
|
AbsoluteOperand* operand)
|
||||||
|
{
|
||||||
|
addAbsoluteMovTask(c, operand->value);
|
||||||
|
|
||||||
|
RegisterOperand* tmp = temporary(c);
|
||||||
|
tmp->accept(c, MyOperand::mov, immediate(c, 0));
|
||||||
|
memory(c, tmp, 0, 0, 1)->apply(c, operation);
|
||||||
|
tmp->release(c);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AbsoluteOperand::apply(Context* c, Operation operation)
|
AbsoluteOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case push: {
|
case push:
|
||||||
addAbsoluteMovTask(c, value);
|
absoluteApply(c, operation, this);
|
||||||
|
break;
|
||||||
RegisterOperand* tmp = temporary(c);
|
|
||||||
tmp->accept(c, mov, immediate(c, 0));
|
|
||||||
memory(c, tmp, 0, 0, 1)->apply(c, push);
|
|
||||||
tmp->release(c);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
@ -884,15 +1019,21 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
RegisterOperand* operand)
|
RegisterOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
|
case add:
|
||||||
|
rex(c);
|
||||||
|
encode(c, 0x01, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
||||||
|
displacement);
|
||||||
|
break;
|
||||||
|
|
||||||
case mov:
|
case mov:
|
||||||
rex(c);
|
rex(c);
|
||||||
encode(c, 0x89, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
encode(c, 0x89, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
||||||
displacement);
|
displacement);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case add:
|
case sub:
|
||||||
rex(c);
|
rex(c);
|
||||||
encode(c, 0x01, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
encode(c, 0x29, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
||||||
displacement);
|
displacement);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -905,13 +1046,28 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
ImmediateOperand* operand)
|
ImmediateOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case mov:
|
case add: {
|
||||||
assert(c, isInt32(operand->value)); // todo
|
rex(c);
|
||||||
|
intptr_t v = operand->value->value(c);
|
||||||
|
unsigned i = (isInt8(v) ? 0x83 : 0x81);
|
||||||
|
encode(c, i, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
||||||
|
if (isInt8(v)) {
|
||||||
|
c->code.append(v);
|
||||||
|
} else if (isInt32(v)) {
|
||||||
|
c->code.append4(v);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mov: {
|
||||||
|
intptr_t v = operand->value->value(c);
|
||||||
|
assert(c, isInt32(v)); // todo
|
||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
encode(c, 0xc7, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
encode(c, 0xc7, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
||||||
c->code.append4(operand->value);
|
c->code.append4(v);
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
@ -935,30 +1091,46 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
intptr_t
|
||||||
PoolPromise::value(Context* c)
|
PoolPromise::value(Context* c)
|
||||||
{
|
{
|
||||||
if (c->ipTable) {
|
if (resolved(c)) {
|
||||||
return c->code.length() + key;
|
return c->code.length() + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
bool
|
||||||
|
PoolPromise::resolved(Context* c)
|
||||||
|
{
|
||||||
|
return c->output != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t
|
||||||
CodePromise::value(Context* c)
|
CodePromise::value(Context* c)
|
||||||
{
|
{
|
||||||
if (c->ipTable) {
|
if (resolved(c)) {
|
||||||
return key;
|
if (absolute) {
|
||||||
|
return reinterpret_cast<intptr_t>(c->output + key);
|
||||||
|
} else {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
bool
|
||||||
|
CodePromise::resolved(Context* c)
|
||||||
|
{
|
||||||
|
return c->output != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t
|
||||||
IpPromise::value(Context* c)
|
IpPromise::value(Context* c)
|
||||||
{
|
{
|
||||||
if (c->ipTable) {
|
if (resolved(c)) {
|
||||||
unsigned bottom = 0;
|
unsigned bottom = 0;
|
||||||
unsigned top = c->ipMappings.length() / BytesPerWord;
|
unsigned top = c->ipMappings.length() / BytesPerWord;
|
||||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||||
@ -966,7 +1138,11 @@ IpPromise::value(Context* c)
|
|||||||
IpMapping* mapping = c->ipTable[middle];
|
IpMapping* mapping = c->ipTable[middle];
|
||||||
|
|
||||||
if (key == mapping->ip) {
|
if (key == mapping->ip) {
|
||||||
return mapping->start;
|
if (absolute) {
|
||||||
|
return reinterpret_cast<intptr_t>(c->output + mapping->start);
|
||||||
|
} else {
|
||||||
|
return mapping->start;
|
||||||
|
}
|
||||||
} else if (key < mapping->ip) {
|
} else if (key < mapping->ip) {
|
||||||
top = middle;
|
top = middle;
|
||||||
} else if (key > mapping->ip) {
|
} else if (key > mapping->ip) {
|
||||||
@ -978,17 +1154,23 @@ IpPromise::value(Context* c)
|
|||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
runTasks(Context* c, uint8_t* out, IpTask::Priority priority)
|
IpPromise::resolved(Context* c)
|
||||||
{
|
{
|
||||||
uint8_t* p = out;
|
return c->output != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
runTasks(Context* c, IpTask::Priority priority)
|
||||||
|
{
|
||||||
|
uint8_t* p = c->output;
|
||||||
for (unsigned i = 0; i < c->ipMappings.length() / BytesPerWord; ++i) {
|
for (unsigned i = 0; i < c->ipMappings.length() / BytesPerWord; ++i) {
|
||||||
IpMapping* mapping = c->ipTable[i];
|
IpMapping* mapping = c->ipTable[i];
|
||||||
int length = mapping->end - mapping->start;
|
int length = mapping->end - mapping->start;
|
||||||
|
|
||||||
for (IpTask* t = mapping->task; t; t = t->next) {
|
for (IpTask* t = mapping->task; t; t = t->next) {
|
||||||
if (t->priority() == priority) {
|
if (t->priority() == priority) {
|
||||||
t->run(c, mapping->ip, mapping->start, mapping->end, out, p - out);
|
t->run(c, mapping->ip, mapping->start, mapping->end, p - c->output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,10 +1191,10 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
virtual Promise* codeOffset() {
|
virtual Promise* codeOffset() {
|
||||||
if (c.code.length() == 0) {
|
if (c.code.length() == 0) {
|
||||||
return new (c.zone.allocate(sizeof(CodePromise))) CodePromise(0);
|
return new (c.zone.allocate(sizeof(CodePromise))) CodePromise(0, false);
|
||||||
} else {
|
} else {
|
||||||
CodePromise* p = new (c.zone.allocate(sizeof(CodePromise)))
|
CodePromise* p = new (c.zone.allocate(sizeof(CodePromise)))
|
||||||
CodePromise(c.code.length());
|
CodePromise(c.code.length(), false);
|
||||||
|
|
||||||
IpMapping* mapping = currentMapping(&c);
|
IpMapping* mapping = currentMapping(&c);
|
||||||
mapping->task = new (c.zone.allocate(sizeof(CodePromiseTask)))
|
mapping->task = new (c.zone.allocate(sizeof(CodePromiseTask)))
|
||||||
@ -1032,6 +1214,10 @@ class MyCompiler: public Compiler {
|
|||||||
return immediate(&c, v);
|
return immediate(&c, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void push(unsigned count) {
|
||||||
|
::push(&c, count);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void push(Operand* v) {
|
virtual void push(Operand* v) {
|
||||||
::push(&c, static_cast<MyOperand*>(v));
|
::push(&c, static_cast<MyOperand*>(v));
|
||||||
}
|
}
|
||||||
@ -1054,6 +1240,10 @@ class MyCompiler: public Compiler {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void pop(unsigned count) {
|
||||||
|
::pop(&c, count);
|
||||||
|
}
|
||||||
|
|
||||||
virtual Operand* pop() {
|
virtual Operand* pop() {
|
||||||
return ::pop(&c);
|
return ::pop(&c);
|
||||||
}
|
}
|
||||||
@ -1097,12 +1287,12 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* label() {
|
virtual Operand* label() {
|
||||||
return absolute
|
return immediate
|
||||||
(&c, new (c.zone.allocate(sizeof(CodePromise))) CodePromise(0));
|
(&c, new (c.zone.allocate(sizeof(CodePromise))) CodePromise(0, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void mark(Operand* label) {
|
virtual void mark(Operand* label) {
|
||||||
static_cast<MyOperand*>(label)->setAbsolute(&c, c.code.length());
|
static_cast<MyOperand*>(label)->setImmediate(&c, c.code.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* indirectCall
|
virtual Operand* indirectCall
|
||||||
@ -1304,7 +1494,8 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void reserve(unsigned size) {
|
virtual void reserve(unsigned size) {
|
||||||
sub(constant(size * BytesPerWord), stack());
|
immediate(&c, size * BytesPerWord)->apply
|
||||||
|
(&c, MyOperand::sub, register_(&c, rsp));
|
||||||
c.reserved = size;
|
c.reserved = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,11 +1511,12 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* logicalIp(unsigned ip) {
|
virtual Operand* logicalIp(unsigned ip) {
|
||||||
return absolute(&c, static_cast<MyPromise*>(logicalIpToOffset(ip)));
|
return immediate
|
||||||
|
(&c, new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* logicalIpToOffset(unsigned ip) {
|
virtual Promise* logicalIpToOffset(unsigned ip) {
|
||||||
return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip);
|
return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned codeSize() {
|
virtual unsigned codeSize() {
|
||||||
@ -1336,6 +1528,8 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void writeTo(uint8_t* out) {
|
virtual void writeTo(uint8_t* out) {
|
||||||
|
c.output = out;
|
||||||
|
|
||||||
unsigned tableSize = (c.ipMappings.length() / BytesPerWord);
|
unsigned tableSize = (c.ipMappings.length() / BytesPerWord);
|
||||||
|
|
||||||
c.ipTable = static_cast<IpMapping**>
|
c.ipTable = static_cast<IpMapping**>
|
||||||
@ -1371,8 +1565,8 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
memcpy(p, c.constantPool.data, c.constantPool.length());
|
memcpy(p, c.constantPool.data, c.constantPool.length());
|
||||||
|
|
||||||
runTasks(&c, out, IpTask::HighPriority);
|
runTasks(&c, IpTask::HighPriority);
|
||||||
runTasks(&c, out, IpTask::LowPriority);
|
runTasks(&c, IpTask::LowPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updateCall(void* returnAddress, void* newTarget) {
|
virtual void updateCall(void* returnAddress, void* newTarget) {
|
||||||
@ -1394,7 +1588,7 @@ class MyCompiler: public Compiler {
|
|||||||
Context c;
|
Context c;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned
|
intptr_t
|
||||||
MyPromise::value(Compiler* compiler)
|
MyPromise::value(Compiler* compiler)
|
||||||
{
|
{
|
||||||
return value(&(static_cast<MyCompiler*>(compiler)->c));
|
return value(&(static_cast<MyCompiler*>(compiler)->c));
|
||||||
|
@ -13,7 +13,7 @@ class Promise {
|
|||||||
public:
|
public:
|
||||||
virtual ~Promise() { }
|
virtual ~Promise() { }
|
||||||
|
|
||||||
virtual unsigned value(Compiler*) = 0;
|
virtual intptr_t value(Compiler*) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Compiler {
|
class Compiler {
|
||||||
@ -49,8 +49,10 @@ class Compiler {
|
|||||||
virtual void return_(Operand*) = 0;
|
virtual void return_(Operand*) = 0;
|
||||||
virtual void ret() = 0;
|
virtual void ret() = 0;
|
||||||
|
|
||||||
|
virtual void push(unsigned count) = 0;
|
||||||
virtual void push(Operand*) = 0;
|
virtual void push(Operand*) = 0;
|
||||||
virtual void push2(Operand*) = 0;
|
virtual void push2(Operand*) = 0;
|
||||||
|
virtual void pop(unsigned count) = 0;
|
||||||
virtual Operand* pop() = 0;
|
virtual Operand* pop() = 0;
|
||||||
virtual Operand* pop2() = 0;
|
virtual Operand* pop2() = 0;
|
||||||
virtual void pop(Operand*) = 0;
|
virtual void pop(Operand*) = 0;
|
||||||
|
@ -15,7 +15,7 @@ public class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// boolean v = Boolean.valueOf("true");
|
boolean v = Boolean.valueOf("true");
|
||||||
|
|
||||||
// ClassLoader.getSystemClassLoader().toString();
|
// ClassLoader.getSystemClassLoader().toString();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user