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