lots of JIT bugfixes and a few new instructions

This commit is contained in:
Joel Dice 2007-12-12 15:19:13 -07:00
parent fe24005ff0
commit b2147c2c99
4 changed files with 452 additions and 143 deletions

View File

@ -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);

View File

@ -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));

View File

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

View File

@ -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();