lots of JIT bugfixes and cleanups

This commit is contained in:
Joel Dice 2007-12-15 17:24:15 -07:00
parent 924a588cdf
commit 796a64a426
6 changed files with 480 additions and 307 deletions

View File

@ -28,7 +28,7 @@ src = src
classpath = classpath classpath = classpath
test = test test = test
input = $(test-build)/Misc.class input = $(test-build)/Enums.class
build-cxx = g++ build-cxx = g++
build-cc = gcc build-cc = gcc

View File

@ -617,6 +617,8 @@ Java_java_lang_Throwable_trace(Thread* t, jclass, jint skipCount)
t->m->processor->walkStack(t, &v); t->m->processor->walkStack(t, &v);
if (v.trace == 0) v.trace = makeArray(t, 0, true);
return makeLocalReference(t, v.trace); return makeLocalReference(t, v.trace);
} }

View File

@ -188,7 +188,9 @@ class MyStackWalker: public Processor::StackWalker {
if (nativeMethod) { if (nativeMethod) {
return 0; return 0;
} else { } else {
return traceNodeAddress(t, node); intptr_t start = reinterpret_cast<intptr_t>
(&singletonValue(t, methodCompiled(t, traceNodeMethod(t, node)), 0));
return traceNodeAddress(t, node) - start;
} }
} }
@ -244,19 +246,21 @@ localOffset(MyThread* t, int v, object method)
class PoolElement { class PoolElement {
public: public:
PoolElement(object value, Promise* offset): value(value), offset(offset) { } PoolElement(object value, Promise* address):
value(value), address(address)
{ }
object value; object value;
Promise* offset; Promise* address;
}; };
class TraceElement { class TraceElement {
public: public:
TraceElement(object target, Promise* offset, bool virtualCall): TraceElement(object target, Promise* machineIp, bool virtualCall):
target(target), offset(offset), virtualCall(virtualCall) { } target(target), machineIp(machineIp), virtualCall(virtualCall) { }
object target; object target;
Promise* offset; Promise* machineIp;
bool virtualCall; bool virtualCall;
uint8_t map[0]; uint8_t map[0];
}; };
@ -292,6 +296,7 @@ class Frame {
next(0), next(0),
t(t), t(t),
c(c), c(c),
stack(0),
method(method), method(method),
map(map), map(map),
objectPool(objectPool), objectPool(objectPool),
@ -308,6 +313,7 @@ class Frame {
next(f), next(f),
t(f->t), t(f->t),
c(f->c), c(f->c),
stack(f->stack),
method(f->method), method(f->method),
map(map), map(map),
objectPool(f->objectPool), objectPool(f->objectPool),
@ -327,9 +333,9 @@ class Frame {
} }
Operand* append(object o) { Operand* append(object o) {
new (objectPool->allocate(sizeof(PoolElement))) Promise* p = c->poolAppend(0);
PoolElement(o, c->poolOffset()); new (objectPool->allocate(sizeof(PoolElement))) PoolElement(o, p);
return c->poolAppend(c->constant(0)); return c->absolute(p);
} }
static unsigned parameterFootprint(Thread* t, object method) { static unsigned parameterFootprint(Thread* t, object method) {
@ -578,7 +584,7 @@ class Frame {
void trace(object target, bool virtualCall) { void trace(object target, bool virtualCall) {
TraceElement* e = new (traceLog->allocate(traceSizeInBytes(t, method))) TraceElement* e = new (traceLog->allocate(traceSizeInBytes(t, method)))
TraceElement(target, c->codeOffset(), virtualCall); TraceElement(target, c->machineIp(), virtualCall);
memcpy(e->map, map, mapSizeInWords(t, method) * BytesPerWord); memcpy(e->map, map, mapSizeInWords(t, method) * BytesPerWord);
} }
@ -586,42 +592,46 @@ class Frame {
trace(0, false); trace(0, false);
} }
Operand* machineIp(unsigned logicalIp) {
return c->promiseConstant(c->machineIp(logicalIp));
}
void startLogicalIp(unsigned ip) { void startLogicalIp(unsigned ip) {
c->startLogicalIp(ip); c->startLogicalIp(ip);
this->ip = ip; this->ip = ip;
} }
void pushInt(Operand* o) { void pushInt(Operand* o) {
c->push(o); stack = c->push(stack, o);
pushedInt(); pushedInt();
} }
void pushObject(Operand* o) { void pushObject(Operand* o) {
c->push(o); stack = c->push(stack, o);
pushedObject(); pushedObject();
} }
void pushObject() { void pushObject() {
c->push(1); stack = c->push(stack, 1);
pushedObject(); pushedObject();
} }
void pushLong(Operand* o) { void pushLong(Operand* o) {
c->push2(o); stack = c->push2(stack, o);
pushedInt(); pushedInt();
pushedInt(); pushedInt();
} }
void pop(unsigned count) { void pop(unsigned count) {
popped(count); popped(count);
c->pop(count); stack = c->pop(stack, count);
} }
Operand* topInt() { Operand* topInt() {
assert(t, sp >= 1); assert(t, sp >= 1);
assert(t, sp - 1 >= localSize(t, method)); assert(t, sp - 1 >= localSize(t, method));
assert(t, getBit(map, sp - 1) == 0); assert(t, getBit(map, sp - 1) == 0);
return c->stack(0); return c->stack(stack, 0);
} }
Operand* topLong() { Operand* topLong() {
@ -629,45 +639,47 @@ class Frame {
assert(t, sp - 2 >= localSize(t, method)); assert(t, sp - 2 >= localSize(t, method));
assert(t, getBit(map, sp - 1) == 0); assert(t, getBit(map, sp - 1) == 0);
assert(t, getBit(map, sp - 2) == 0); assert(t, getBit(map, sp - 2) == 0);
return c->stack(1); return c->stack(stack, 1);
} }
Operand* topObject() { Operand* topObject() {
assert(t, sp >= 1); assert(t, sp >= 1);
assert(t, sp - 1 >= localSize(t, method)); assert(t, sp - 1 >= localSize(t, method));
assert(t, getBit(map, sp - 1) != 0); assert(t, getBit(map, sp - 1) != 0);
return c->stack(0); return c->stack(stack, 0);
} }
Operand* popInt() { Operand* popInt() {
poppedInt(); Operand* tmp = c->temporary();
return c->pop(); popInt(tmp);
return tmp;
} }
Operand* popLong() { Operand* popLong() {
poppedInt(); Operand* tmp = c->temporary();
poppedInt(); popLong(tmp);
return c->pop2(); return tmp;
} }
Operand* popObject() { Operand* popObject() {
poppedObject(); Operand* tmp = c->temporary();
return c->pop(); popObject(tmp);
return tmp;
} }
void popInt(Operand* o) { void popInt(Operand* o) {
c->pop(o); stack = c->pop(stack, o);
poppedInt(); poppedInt();
} }
void popLong(Operand* o) { void popLong(Operand* o) {
c->pop2(o); stack = c->pop2(stack, o);
poppedInt(); poppedInt();
poppedInt(); poppedInt();
} }
void popObject(Operand* o) { void popObject(Operand* o) {
c->pop(o); stack = c->pop(stack, o);
poppedObject(); poppedObject();
} }
@ -712,83 +724,84 @@ class Frame {
} }
void increment(unsigned index, unsigned count) { void increment(unsigned index, unsigned count) {
assert(t, index < localSize(t, method)); assert(t, index < codeMaxLocals(t, methodCode(t, method)));
assert(t, getBit(map, index) == 0); assert(t, index < parameterFootprint(t, method)
or getBit(map, index - parameterFootprint(t, method)) == 0);
c->add(c->constant(count), c->add(c->constant(count),
c->memory(c->base(), localOffset(t, index, method))); c->memory(c->base(), localOffset(t, index, method)));
} }
void dup() { void dup() {
c->push(c->stack(0)); stack = c->push(stack, c->stack(stack, 0));
dupped(); dupped();
} }
void dupX1() { void dupX1() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
Operand* s1 = c->stack(1); Operand* s1 = c->stack(stack, 1);
c->mov(s0, s1); c->mov(s0, s1);
c->mov(s1, s0); c->mov(s1, s0);
c->push(s0); stack = c->push(stack, s0);
duppedX1(); duppedX1();
} }
void dupX2() { void dupX2() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
Operand* s1 = c->stack(1); Operand* s1 = c->stack(stack, 1);
Operand* s2 = c->stack(2); Operand* s2 = c->stack(stack, 2);
c->mov(s0, s2); c->mov(s0, s2);
c->mov(s2, s1); c->mov(s2, s1);
c->mov(s1, s0); c->mov(s1, s0);
c->push(s0); stack = c->push(stack, s0);
duppedX2(); duppedX2();
} }
void dup2() { void dup2() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
c->push(s0); stack = c->push(stack, s0);
c->push(s0); stack = c->push(stack, s0);
dupped2(); dupped2();
} }
void dup2X1() { void dup2X1() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
Operand* s1 = c->stack(1); Operand* s1 = c->stack(stack, 1);
Operand* s2 = c->stack(2); Operand* s2 = c->stack(stack, 2);
c->mov(s1, s2); c->mov(s1, s2);
c->mov(s0, s1); c->mov(s0, s1);
c->mov(s2, s0); c->mov(s2, s0);
c->push(s1); stack = c->push(stack, s1);
c->push(s0); stack = c->push(stack, s0);
dupped2X1(); dupped2X1();
} }
void dup2X2() { void dup2X2() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
Operand* s1 = c->stack(1); Operand* s1 = c->stack(stack, 1);
Operand* s2 = c->stack(2); Operand* s2 = c->stack(stack, 2);
Operand* s3 = c->stack(3); Operand* s3 = c->stack(stack, 3);
c->mov(s1, s3); c->mov(s1, s3);
c->mov(s0, s2); c->mov(s0, s2);
c->mov(s3, s1); c->mov(s3, s1);
c->mov(s2, s0); c->mov(s2, s0);
c->push(s1); stack = c->push(stack, s1);
c->push(s0); stack = c->push(stack, s0);
dupped2X2(); dupped2X2();
} }
void swap() { void swap() {
Operand* s0 = c->stack(0); Operand* s0 = c->stack(stack, 0);
Operand* s1 = c->stack(1); Operand* s1 = c->stack(stack, 1);
Operand* tmp = c->temporary(); Operand* tmp = c->temporary();
c->mov(s0, tmp); c->mov(s0, tmp);
@ -803,6 +816,7 @@ class Frame {
Frame* next; Frame* next;
MyThread* t; MyThread* t;
Compiler* c; Compiler* c;
Stack* stack;
object method; object method;
uintptr_t* map; uintptr_t* map;
Vector* objectPool; Vector* objectPool;
@ -1818,7 +1832,7 @@ 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->jmp(c->logicalIp(newIp)); c->jmp(frame->machineIp(newIp));
ip = newIp; ip = newIp;
} break; } break;
@ -1826,7 +1840,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
uint32_t newIp = (ip - 5) + codeReadInt32(t, code, ip); uint32_t newIp = (ip - 5) + codeReadInt32(t, code, ip);
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
c->jmp(c->logicalIp(newIp)); c->jmp(frame->machineIp(newIp));
ip = newIp; ip = newIp;
} break; } break;
@ -1930,7 +1944,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->release(a); c->release(a);
c->release(b); c->release(b);
Operand* target = c->logicalIp(newIp); Operand* target = frame->machineIp(newIp);
if (instruction == if_acmpeq) { if (instruction == if_acmpeq) {
c->je(target); c->je(target);
} else { } else {
@ -1956,7 +1970,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->release(a); c->release(a);
c->release(b); c->release(b);
Operand* target = c->logicalIp(newIp); Operand* target = frame->machineIp(newIp);
switch (instruction) { switch (instruction) {
case if_icmpeq: case if_icmpeq:
c->je(target); c->je(target);
@ -1995,7 +2009,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->cmp(c->constant(0), a); c->cmp(c->constant(0), a);
c->release(a); c->release(a);
Operand* target = c->logicalIp(newIp); Operand* target = frame->machineIp(newIp);
switch (instruction) { switch (instruction) {
case ifeq: case ifeq:
c->je(target); c->je(target);
@ -2026,11 +2040,11 @@ 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));
Operand* a = frame->popInt(); Operand* a = frame->popObject();
c->cmp(c->constant(0), a); c->cmp(c->constant(0), a);
c->release(a); c->release(a);
Operand* target = c->logicalIp(newIp); Operand* target = frame->machineIp(newIp);
if (instruction == ifnull) { if (instruction == ifnull) {
c->je(target); c->je(target);
} else { } else {
@ -2145,7 +2159,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* found = c->directCall Operand* found = c->directCall
(c->constant (c->constant
(reinterpret_cast<intptr_t>(findInterfaceMethodFromInstance)), (reinterpret_cast<intptr_t>(findInterfaceMethodFromInstance)),
3, c->thread(), frame->append(target), c->stack(instance)); 3, c->thread(), frame->append(target),
c->stack(frame->stack, instance));
c->mov(c->memory(found, MethodCompiled), found); c->mov(c->memory(found, MethodCompiled), found);
@ -2195,7 +2210,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord); unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
Operand* instance = c->stack(parameterFootprint - 1); Operand* instance = c->stack(frame->stack, parameterFootprint - 1);
Operand* class_ = c->temporary(); Operand* class_ = c->temporary();
c->mov(c->memory(instance), class_); c->mov(c->memory(instance), class_);
@ -2432,30 +2447,28 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
uint32_t defaultIp = base + codeReadInt32(t, code, ip); uint32_t defaultIp = base + codeReadInt32(t, code, ip);
assert(t, defaultIp < codeLength(t, code)); assert(t, defaultIp < codeLength(t, code));
compile(t, frame, defaultIp); Operand* default_ = c->absolute
if (UNLIKELY(t->exception)) return; (c->poolAppendPromise(c->machineIp(defaultIp)));
Operand* default_ = c->poolAppend(c->logicalIp(defaultIp));
int32_t pairCount = codeReadInt32(t, code, ip); int32_t pairCount = codeReadInt32(t, code, ip);
Operand* start; Operand* start = 0;
uint32_t ipTable[pairCount];
for (int32_t i = 0; i < pairCount; ++i) { for (int32_t i = 0; i < pairCount; ++i) {
unsigned index = ip + (i * 8); unsigned index = ip + (i * 8);
int32_t key = codeReadInt32(t, code, index); int32_t key = codeReadInt32(t, code, index);
uint32_t newIp = base + codeReadInt32(t, code, index); uint32_t newIp = base + codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
compile(t, frame, newIp); ipTable[i] = newIp;
if (UNLIKELY(t->exception)) return;
Operand* result = c->poolAppend(c->constant(key));
c->poolAppend(c->logicalIp(newIp));
Promise* p = c->poolAppend(key);
if (i == 0) { if (i == 0) {
start = result; start = c->promiseConstant(p);
} }
c->poolAppendPromise(c->machineIp(newIp));
} }
assert(t, start);
c->jmp c->jmp
(c->directCall (c->directCall
@ -2463,6 +2476,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
4, key, start, c->constant(pairCount), default_)); 4, key, start, c->constant(pairCount), default_));
c->release(key); c->release(key);
for (int32_t i = 0; i < pairCount; ++i) {
compile(t, frame, ipTable[i]);
if (UNLIKELY(t->exception)) return;
}
compile(t, frame, defaultIp);
if (UNLIKELY(t->exception)) return;
} return; } return;
case lor: { case lor: {
@ -2611,7 +2632,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* size = frame->popInt(); Operand* size = frame->popInt();
c->cmp(c->constant(0), size); c->cmp(c->constant(0), size);
c->release(size);
c->jge(nonnegative); c->jge(nonnegative);
@ -2658,7 +2678,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Operand* result = c->indirectCall Operand* result = c->indirectCall
(c->constant(reinterpret_cast<intptr_t>(makeBlankArray)), (c->constant(reinterpret_cast<intptr_t>(makeBlankArray)),
2, c->constant(reinterpret_cast<intptr_t>(constructor)), size); 3, c->thread(), c->constant(reinterpret_cast<intptr_t>(constructor)),
size);
c->release(size);
frame->trace(); frame->trace();
@ -2783,28 +2806,24 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
uint32_t defaultIp = base + codeReadInt32(t, code, ip); uint32_t defaultIp = base + codeReadInt32(t, code, ip);
assert(t, defaultIp < codeLength(t, code)); assert(t, defaultIp < codeLength(t, code));
compile(t, frame, defaultIp);
if (UNLIKELY(t->exception)) return;
Operand* default_ = c->poolAppend(c->logicalIp(defaultIp));
int32_t bottom = codeReadInt32(t, code, ip); int32_t bottom = codeReadInt32(t, code, ip);
int32_t top = codeReadInt32(t, code, ip); int32_t top = codeReadInt32(t, code, ip);
Operand* start; Operand* start = 0;
for (int32_t i = 0; i < bottom - top + 1; ++i) { uint32_t ipTable[top - bottom + 1];
for (int32_t i = 0; i < top - bottom + 1; ++i) {
unsigned index = ip + (i * 4); unsigned index = ip + (i * 4);
uint32_t newIp = base + codeReadInt32(t, code, index); uint32_t newIp = base + codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
compile(t, frame, newIp); ipTable[i] = newIp;
if (UNLIKELY(t->exception)) return;
Operand* result = c->poolAppend(c->logicalIp(newIp)); Promise* p = c->poolAppendPromise(c->machineIp(newIp));
if (i == 0) { if (i == 0) {
start = result; start = c->promiseConstant(p);
} }
} }
assert(t, start);
Operand* defaultCase = c->label(); Operand* defaultCase = c->label();
@ -2814,13 +2833,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->cmp(c->constant(top), key); c->cmp(c->constant(top), key);
c->jg(defaultCase); c->jg(defaultCase);
c->shl(c->constant(1), key); c->sub(c->constant(bottom), key);
c->jmp(c->memory(start, 0, key, BytesPerWord)); c->jmp(c->memory(start, 0, key, BytesPerWord));
c->mark(defaultCase); c->mark(defaultCase);
c->jmp(default_); c->jmp(frame->machineIp(defaultIp));
c->release(key); c->release(key);
for (int32_t i = 0; i < top - bottom + 1; ++i) {
compile(t, frame, ipTable[i]);
if (UNLIKELY(t->exception)) return;
}
compile(t, frame, defaultIp);
if (UNLIKELY(t->exception)) return;
} return; } return;
case wide: { case wide: {
@ -2887,10 +2914,12 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
for (unsigned i = 0; i < objectPool->length(); i += sizeof(PoolElement)) { for (unsigned i = 0; i < objectPool->length(); i += sizeof(PoolElement)) {
PoolElement* e = objectPool->peek<PoolElement>(i); PoolElement* e = objectPool->peek<PoolElement>(i);
intptr_t offset = e->address->value(c)
- reinterpret_cast<intptr_t>(start);
singletonMarkObject(t, result, e->offset->value(c) / BytesPerWord); singletonMarkObject(t, result, offset / BytesPerWord);
set(t, result, SingletonBody + e->offset->value(c), e->value); set(t, result, SingletonBody + offset, e->value);
} }
unsigned traceSize = Frame::traceSizeInBytes(t, method); unsigned traceSize = Frame::traceSizeInBytes(t, method);
@ -2899,9 +2928,8 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
TraceElement* e = traceLog->peek<TraceElement>(i); TraceElement* e = traceLog->peek<TraceElement>(i);
object node = makeTraceNode object node = makeTraceNode
(t, reinterpret_cast<intptr_t>(start + e->offset->value(c)), (t, e->machineIp->value(c), 0, method, e->target, e->virtualCall,
0, method, e->target, e->virtualCall, mapSize / BytesPerWord, mapSize / BytesPerWord, false);
false);
if (mapSize) { if (mapSize) {
memcpy(&traceNodeMap(t, node, 0), e->map, mapSize); memcpy(&traceNodeMap(t, node, 0), e->map, mapSize);
@ -2927,16 +2955,16 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
(t, newTable, i); (t, newTable, i);
exceptionHandlerStart(newHandler) exceptionHandlerStart(newHandler)
= c->logicalIpToOffset(exceptionHandlerStart(oldHandler)) = c->machineIp(exceptionHandlerStart(oldHandler))->value(c)
->value(c); - reinterpret_cast<intptr_t>(start);
exceptionHandlerEnd(newHandler) exceptionHandlerEnd(newHandler)
= c->logicalIpToOffset(exceptionHandlerEnd(oldHandler)) = c->machineIp(exceptionHandlerEnd(oldHandler))->value(c)
->value(c); - reinterpret_cast<intptr_t>(start);
exceptionHandlerIp(newHandler) exceptionHandlerIp(newHandler)
= c->logicalIpToOffset(exceptionHandlerIp(oldHandler)) = c->machineIp(exceptionHandlerIp(oldHandler))->value(c)
->value(c); - reinterpret_cast<intptr_t>(start);
exceptionHandlerCatchType(newHandler) exceptionHandlerCatchType(newHandler)
= exceptionHandlerCatchType(oldHandler); = exceptionHandlerCatchType(oldHandler);
@ -2957,8 +2985,9 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
LineNumber* oldLine = lineNumberTableBody(t, oldTable, i); LineNumber* oldLine = lineNumberTableBody(t, oldTable, i);
LineNumber* newLine = lineNumberTableBody(t, newTable, i); LineNumber* newLine = lineNumberTableBody(t, newTable, i);
lineNumberIp(newLine) = c->logicalIpToOffset(lineNumberIp(oldLine)) lineNumberIp(newLine)
->value(c); = c->machineIp(lineNumberIp(oldLine))->value(c)
- reinterpret_cast<intptr_t>(start);
lineNumberLine(newLine) = lineNumberLine(oldLine); lineNumberLine(newLine) = lineNumberLine(oldLine);
} }
@ -2979,10 +3008,10 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
if (false and if (false and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
"java/lang/Boolean") == 0 and "Enums") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"booleanValue") == 0) "checkFaceCard") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3474,8 +3503,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
break; break;
case ObjectField: case ObjectField:
r = (result == 0 ? 0 : r = reinterpret_cast<object>(result);
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
break; break;
case VoidField: case VoidField:

View File

@ -36,13 +36,14 @@ enum SelectionType {
const bool Verbose = false; const bool Verbose = false;
const unsigned RegisterCount = BytesPerWord * 2; const unsigned RegisterCount = BytesPerWord * 2;
const unsigned GprParameterCount = 6;
class Context; class Context;
class MyOperand;
class ImmediateOperand; class ImmediateOperand;
class AbsoluteOperand; class AbsoluteOperand;
class RegisterOperand; class RegisterOperand;
class MemoryOperand; class MemoryOperand;
class StackOperand;
class CodePromise; class CodePromise;
class MyPromise; class MyPromise;
@ -64,6 +65,16 @@ isInt32(intptr_t v)
return v == static_cast<int32_t>(v); return v == static_cast<int32_t>(v);
} }
class RegisterNode {
public:
RegisterNode(Register value, RegisterNode* next):
value(value), next(next)
{ }
Register value;
RegisterNode* next;
};
class Task { class Task {
public: public:
Task(Task* next): next(next) { } Task(Task* next): next(next) { }
@ -105,6 +116,17 @@ class Segment {
Event* event; Event* event;
}; };
class MyStack: public Stack {
public:
MyStack(MyOperand* value, int index, MyStack* next):
value(value), index(index), next(next)
{ }
MyOperand* value;
int index;
MyStack* next;
};
class MyOperand: public Operand { class MyOperand: public Operand {
public: public:
enum Operation { enum Operation {
@ -144,9 +166,12 @@ class MyOperand: public Operand {
virtual Register asRegister(Context* c) { abort(c); } virtual Register asRegister(Context* c) { abort(c); }
virtual RegisterNode* dependencies(Context*, RegisterNode* next)
{ return next; }
virtual void release(Context*) { /* ignore */ } virtual void release(Context*) { /* ignore */ }
virtual void setLabelValue(Context* c, CodePromise*) { abort(c); } virtual void setLabelValue(Context* c, MyPromise*) { abort(c); }
virtual void apply(Context*, Operation) = 0; virtual void apply(Context*, Operation) = 0;
@ -181,6 +206,8 @@ class RegisterOperand: public MyOperand {
return value; return value;
} }
virtual RegisterNode* dependencies(Context* c, RegisterNode* next);
void acquire(Context* c UNUSED) { void acquire(Context* c UNUSED) {
assert(c, not reserved); assert(c, not reserved);
// fprintf(stderr, "acquire %d\n", value); // fprintf(stderr, "acquire %d\n", value);
@ -253,7 +280,9 @@ class AddressOperand: public MyOperand {
promise(promise) promise(promise)
{ } { }
virtual void setLabelValue(Context*, CodePromise*); virtual Register asRegister(Context* c);
virtual void setLabelValue(Context*, MyPromise*);
virtual void apply(Context*, Operation); virtual void apply(Context*, Operation);
virtual void apply(Context* c, Operation, MyOperand*) { abort(c); } virtual void apply(Context* c, Operation, MyOperand*) { abort(c); }
@ -313,6 +342,15 @@ class MemoryOperand: public MyOperand {
virtual Register asRegister(Context*); virtual Register asRegister(Context*);
virtual RegisterNode* dependencies(Context* c, RegisterNode* next) {
next = base->dependencies(c, next);
if (index) {
return index->dependencies(c, next);
} else {
return next;
}
}
virtual void apply(Context*, Operation); virtual void apply(Context*, Operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) { virtual void apply(Context* c, Operation operation, MyOperand* operand) {
@ -404,6 +442,10 @@ class WrapperOperand: public MyOperand {
return base->asRegister(c); return base->asRegister(c);
} }
virtual RegisterNode* dependencies(Context* c, RegisterNode* next) {
return base->dependencies(c, next);
}
virtual void apply(Context* c, Operation operation) { virtual void apply(Context* c, Operation operation) {
base->apply(c, operation); base->apply(c, operation);
} }
@ -461,16 +503,6 @@ class WrapperOperand: public MyOperand {
MyOperand* base; MyOperand* base;
}; };
class StackOperand: public WrapperOperand {
public:
StackOperand(MyOperand* base, int index, StackOperand* next):
WrapperOperand(base), index(index), next(next)
{ }
int index;
StackOperand* next;
};
class TemporaryOperand: public WrapperOperand { class TemporaryOperand: public WrapperOperand {
public: public:
TemporaryOperand(MyOperand* base): TemporaryOperand(MyOperand* base):
@ -497,7 +529,6 @@ class Context {
zone(s, 8 * 1024), zone(s, 8 * 1024),
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)), indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
segmentTable(0), segmentTable(0),
stack(0),
reserved(0), reserved(0),
codeLength(-1) codeLength(-1)
{ {
@ -529,7 +560,6 @@ class Context {
Zone zone; Zone zone;
intptr_t indirectCaller; intptr_t indirectCaller;
Segment** segmentTable; Segment** segmentTable;
StackOperand* stack;
unsigned reserved; unsigned reserved;
int codeLength; int codeLength;
RegisterOperand* registers[RegisterCount]; RegisterOperand* registers[RegisterCount];
@ -585,7 +615,7 @@ class PoolPromise: public MyPromise {
virtual intptr_t value(Context* c) { virtual intptr_t value(Context* c) {
if (resolved(c)) { if (resolved(c)) {
return c->codeLength + key; return reinterpret_cast<intptr_t>(c->code.data + c->codeLength + key);
} }
abort(c); abort(c);
@ -600,17 +630,13 @@ class PoolPromise: public MyPromise {
class CodePromise: public MyPromise { class CodePromise: public MyPromise {
public: public:
CodePromise(bool absolute): CodePromise():
offset(-1), absolute(absolute) offset(-1)
{ } { }
virtual intptr_t value(Context* c) { virtual intptr_t value(Context* c) {
if (resolved(c)) { if (resolved(c)) {
if (absolute) {
return reinterpret_cast<intptr_t>(c->code.data + offset); return reinterpret_cast<intptr_t>(c->code.data + offset);
} else {
return offset;
}
} }
abort(c); abort(c);
@ -621,13 +647,12 @@ class CodePromise: public MyPromise {
} }
intptr_t offset; intptr_t offset;
bool absolute;
}; };
class IpPromise: public MyPromise { class IpPromise: public MyPromise {
public: public:
IpPromise(intptr_t logicalIp, bool absolute): IpPromise(intptr_t logicalIp):
logicalIp(logicalIp), absolute(absolute) logicalIp(logicalIp)
{ } { }
virtual intptr_t value(Context* c) { virtual intptr_t value(Context* c) {
@ -639,11 +664,7 @@ class IpPromise: public MyPromise {
Segment* s = c->segmentTable[middle]; Segment* s = c->segmentTable[middle];
if (logicalIp == s->logicalIp) { if (logicalIp == s->logicalIp) {
if (absolute) {
return reinterpret_cast<intptr_t>(c->code.data + s->offset); return reinterpret_cast<intptr_t>(c->code.data + s->offset);
} else {
return s->offset;
}
} else if (logicalIp < s->logicalIp) { } else if (logicalIp < s->logicalIp) {
top = middle; top = middle;
} else if (logicalIp > s->logicalIp) { } else if (logicalIp > s->logicalIp) {
@ -660,7 +681,6 @@ class IpPromise: public MyPromise {
} }
intptr_t logicalIp; intptr_t logicalIp;
bool absolute;
}; };
AddressOperand* AddressOperand*
@ -837,6 +857,99 @@ class ReleaseEvent: public Event {
MyOperand* operand; MyOperand* operand;
}; };
class Movement {
public:
MyOperand* source;
Register destination;
RegisterNode* dependencies;
};
void
push(Context* c, Movement* table, unsigned size)
{
int pushed[size];
unsigned pushIndex = 0;
for (unsigned i = 0; i < size; ++i) {
Movement* mi = table + i;
for (unsigned j = i + 1; j < size; ++j) {
Movement* mj = table + j;
for (RegisterNode* d = mj->dependencies; d; d = d->next) {
if (mi->destination == d->value) {
mi->source->apply(c, MyOperand::push);
pushed[pushIndex++] = i;
goto loop;
}
}
}
mi->source->apply(c, MyOperand::mov, register_(c, mi->destination));
loop:;
}
for (int i = pushIndex - 1; i >= 0; --i) {
register_(c, table[pushed[i]].destination)->apply
(c, MyOperand::pop);
}
}
Register
gpRegister(Context* c, unsigned index)
{
switch (index) {
case 0:
return rdi;
case 1:
return rsi;
case 2:
return rdx;
case 3:
return rcx;
case 4:
return r8;
case 5:
return r9;
default:
abort(c);
}
}
class ArgumentEvent: public Event {
public:
ArgumentEvent(MyOperand** arguments, unsigned count, Event* next):
Event(next),
arguments(arguments),
count(count)
{ }
virtual void run(Context* c) {
if (BytesPerWord == 8) {
const unsigned size = min(count, GprParameterCount);
Movement moveTable[size];
for (int i = count - 1; i >= 0; --i) {
if (static_cast<unsigned>(i) < GprParameterCount) {
Movement* m = moveTable + (size - i - 1);
m->source = arguments[i];
m->destination = gpRegister(c, i);
m->dependencies = arguments[i]->dependencies(c, 0);
} else {
arguments[i]->apply(c, MyOperand::push);
}
}
push(c, moveTable, size);
} else {
for (int i = count - 1; i >= 0; --i) {
arguments[i]->apply(c, MyOperand::push);
}
}
}
MyOperand** arguments;
unsigned count;
};
void void
appendOperation(Context* c, MyOperand::Operation operation) appendOperation(Context* c, MyOperand::Operation operation)
{ {
@ -877,105 +990,88 @@ appendRelease(Context* c, Operand* operand)
ReleaseEvent(operand, s->event); ReleaseEvent(operand, s->event);
} }
StackOperand* void
pushed(Context* c) appendArgumentEvent(Context* c, MyOperand** arguments, unsigned count)
{ {
int index = (c->stack ? Segment* s = currentSegment(c);
c->stack->index + (c->stack->footprint() / BytesPerWord) : s->event = new (c->zone.allocate(sizeof(ArgumentEvent)))
0); ArgumentEvent(arguments, count, s->event);
MyOperand* base = memory
(c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1);
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
StackOperand(base, index, c->stack);
} }
void MyStack*
push(Context* c, int count) pushed(Context* c, MyStack* stack)
{
int index = (stack ?
stack->index + (stack->value->footprint() / BytesPerWord) :
0);
MyOperand* value = memory
(c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1);
return new (c->zone.allocate(sizeof(MyStack))) MyStack(value, index, stack);
}
MyStack*
push(Context* c, MyStack* stack, int count)
{ {
appendOperation appendOperation
(c, MyOperand::sub, immediate(c, count * BytesPerWord), register_(c, rsp)); (c, MyOperand::sub, immediate(c, count * BytesPerWord), register_(c, rsp));
while (count) { while (count) {
-- count; -- count;
pushed(c); stack = pushed(c, stack);
}
} }
StackOperand* return stack;
push(Context* c, MyOperand* v) }
MyStack*
push(Context* c, MyStack* stack, MyOperand* v)
{ {
appendOperation(c, MyOperand::push, v); appendOperation(c, MyOperand::push, v);
return pushed(c); return pushed(c, stack);
} }
void MyStack*
pop(Context* c, int count) pop(Context* c, MyStack* stack, int count)
{ {
appendOperation appendOperation
(c, MyOperand::add, immediate(c, count * BytesPerWord), register_(c, rsp)); (c, MyOperand::add, immediate(c, count * BytesPerWord), register_(c, rsp));
while (count) { while (count) {
count -= (c->stack->footprint() / BytesPerWord); count -= (stack->value->footprint() / BytesPerWord);
assert(c, count >= 0); assert(c, count >= 0);
c->stack = c->stack->next; stack = stack->next;
}
} }
void return stack;
pop(Context* c, MyOperand* dst) }
MyStack*
pop(Context* c, MyStack* stack, MyOperand* dst)
{ {
appendOperation(c, MyOperand::pop, dst); appendOperation(c, MyOperand::pop, dst);
c->stack = c->stack->next; return stack->next;
}
Register
gpRegister(Context* c, unsigned index)
{
switch (index) {
case 0:
return rdi;
case 1:
return rsi;
case 2:
return rdx;
case 3:
return rcx;
case 4:
return r8;
case 5:
return r9;
default:
abort(c);
}
} }
unsigned unsigned
pushArguments(Context* c, unsigned count, va_list list) pushArguments(Context* c, unsigned count, va_list list)
{ {
MyOperand* arguments[count]; MyOperand** arguments = static_cast<MyOperand**>
(c->zone.allocate(count * BytesPerWord));
unsigned footprint = 0; unsigned footprint = 0;
for (unsigned i = 0; i < count; ++i) { for (unsigned i = 0; i < count; ++i) {
arguments[i] = va_arg(list, MyOperand*); arguments[i] = va_arg(list, MyOperand*);
footprint += pad(arguments[i]->footprint()); footprint += pad(arguments[i]->footprint());
} }
const int GprCount = 6; appendArgumentEvent(c, arguments, count);
for (int i = count - 1; i >= 0; --i) {
if (BytesPerWord == 8 and i < GprCount) {
appendOperation
(c, MyOperand::mov, arguments[i], register_(c, gpRegister(c, i)));
} else {
appendOperation(c, MyOperand::push, arguments[i]);
}
}
if (BytesPerWord == 8) { if (BytesPerWord == 8) {
if (footprint > GprCount * BytesPerWord) { if (footprint > GprParameterCount * BytesPerWord) {
return footprint - GprCount * BytesPerWord; return footprint - GprParameterCount * BytesPerWord;
} else { } else {
return 0; return 0;
} }
@ -1038,6 +1134,13 @@ encode(Context* c, uint8_t instruction, int a, MemoryOperand* b, bool rex)
encode(c, instruction, a, r, b->displacement, index, b->scale); encode(c, instruction, a, r, b->displacement, index, b->scale);
} }
RegisterNode*
RegisterOperand::dependencies(Context* c, RegisterNode* next)
{
return new (c->zone.allocate(sizeof(RegisterNode)))
RegisterNode(value, next);
}
void void
RegisterOperand::apply(Context* c, Operation operation) RegisterOperand::apply(Context* c, Operation operation)
{ {
@ -1142,7 +1245,6 @@ RegisterOperand::accept(Context* c, Operation operation,
} break; } break;
case and_: { case and_: {
if (operand->value) {
rex(c); rex(c);
if (isInt8(operand->value)) { if (isInt8(operand->value)) {
c->code.append(0x83); c->code.append(0x83);
@ -1155,7 +1257,6 @@ RegisterOperand::accept(Context* c, Operation operation,
c->code.append(0xe0 | value); c->code.append(0xe0 | value);
c->code.append(operand->value); c->code.append(operand->value);
} }
}
} break; } break;
case cmp: { case cmp: {
@ -1173,6 +1274,22 @@ RegisterOperand::accept(Context* c, Operation operation,
c->code.appendAddress(operand->value); c->code.appendAddress(operand->value);
} break; } break;
case shl: {
if (operand->value) {
rex(c);
if (operand->value == 1) {
c->code.append(0xd1);
c->code.append(0xe0 | value);
} else {
assert(c, isInt8(operand->value));
c->code.append(0xc1);
c->code.append(0xe0 | value);
c->code.append(operand->value);
}
}
} break;
case sub: { case sub: {
if (operand->value) { if (operand->value) {
assert(c, isInt8(operand->value)); // todo assert(c, isInt8(operand->value)); // todo
@ -1243,9 +1360,7 @@ ImmediateOperand*
value(Context* c, AbsoluteOperand* operand) value(Context* c, AbsoluteOperand* operand)
{ {
if (c->codeLength >= 0) { if (c->codeLength >= 0) {
return immediate return immediate(c, operand->promise->value(c));
(c, reinterpret_cast<intptr_t>
(c->code.data + operand->promise->value(c)));
} else { } else {
return immediate(c, 0); return immediate(c, 0);
} }
@ -1306,7 +1421,7 @@ conditional(Context* c, unsigned condition, AddressOperand* operand)
} }
void void
AddressOperand::setLabelValue(Context*, CodePromise* p) AddressOperand::setLabelValue(Context*, MyPromise* p)
{ {
promise = p; promise = p;
} }
@ -1358,6 +1473,22 @@ AddressOperand::apply(Context* c, Operation operation)
} }
} }
Register
AddressOperand::asRegister(Context* c)
{
intptr_t v;
if (c->codeLength >= 0) {
v = promise->value(c);
} else {
v = 0;
}
RegisterOperand* tmp = temporary(c);
tmp->accept(c, mov, immediate(c, v));
tmp->release(c);
return tmp->value;
}
void void
ImmediateOperand::apply(Context* c, Operation operation) ImmediateOperand::apply(Context* c, Operation operation)
{ {
@ -1436,6 +1567,10 @@ MemoryOperand::apply(Context* c, Operation operation)
encode(c, 0xff, 2, this, false); encode(c, 0xff, 2, this, false);
break; break;
case jmp:
encode(c, 0xff, 4, this, false);
break;
case neg: case neg:
encode(c, 0xf7, 2, this, true); encode(c, 0xf7, 2, this, true);
break; break;
@ -1472,6 +1607,10 @@ MemoryOperand::accept(Context* c, Operation operation,
RegisterOperand* operand) RegisterOperand* operand)
{ {
switch (operation) { switch (operation) {
case and_: {
encode(c, 0x21, operand->value, this, true);
} break;
case add: { case add: {
encode(c, 0x01, operand->value, this, true); encode(c, 0x01, operand->value, this, true);
} break; } break;
@ -1656,14 +1795,8 @@ class MyCompiler: public Compiler {
c(s, indirectCaller) c(s, indirectCaller)
{ } { }
virtual Promise* poolOffset() { virtual Promise* machineIp() {
return new (c.zone.allocate(sizeof(PoolPromise))) CodePromise* p = new (c.zone.allocate(sizeof(CodePromise))) CodePromise();
PoolPromise(c.constantPool.length());
}
virtual Promise* codeOffset() {
CodePromise* p = new (c.zone.allocate(sizeof(CodePromise)))
CodePromise(false);
Segment* s = currentSegment(&c); Segment* s = currentSegment(&c);
s->event->task = new (c.zone.allocate(sizeof(CodePromiseTask))) s->event->task = new (c.zone.allocate(sizeof(CodePromiseTask)))
@ -1672,64 +1805,77 @@ class MyCompiler: public Compiler {
return p; return p;
} }
virtual Operand* poolAppend(Operand* v) { virtual Promise* machineIp(unsigned logicalIp) {
Operand* r = absolute(&c, static_cast<MyPromise*>(poolOffset())); return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(logicalIp);
}
virtual Promise* poolAppend(intptr_t v) {
return poolAppendPromise
(new (c.zone.allocate(sizeof(ResolvedPromise))) ResolvedPromise(v));
}
virtual Promise* poolAppendPromise(Promise* v) {
Promise* p = new (c.zone.allocate(sizeof(PoolPromise)))
PoolPromise(c.constantPool.length());
c.constantPool.appendAddress(v); c.constantPool.appendAddress(v);
return r; return p;
} }
virtual Operand* constant(intptr_t v) { virtual Operand* constant(intptr_t v) {
return immediate(&c, v); return immediate(&c, v);
} }
virtual void push(unsigned count) { virtual Operand* promiseConstant(Promise* p) {
::push(&c, count); return address(&c, static_cast<MyPromise*>(p));
} }
virtual void push(Operand* v) { virtual Operand* absolute(Promise* p) {
::push(&c, static_cast<MyOperand*>(v)); return ::absolute(&c, static_cast<MyPromise*>(p));
} }
virtual void push2(Operand* v) { virtual Stack* push(Stack* s, unsigned count) {
push(v); return ::push(&c, static_cast<MyStack*>(s), count);
if (BytesPerWord == 8) push(immediate(&c, 0));
} }
virtual Operand* stack(unsigned index) { virtual Stack* push(Stack* s, Operand* v) {
StackOperand* s = c.stack; return ::push(&c, static_cast<MyStack*>(s), static_cast<MyOperand*>(v));
unsigned i = 0;
if (s->footprint() / BytesPerWord == 2) ++ i;
for (; i < index; ++i) {
s = s->next;
if (s->footprint() / BytesPerWord == 2) ++ i;
} }
virtual Stack* push2(Stack* s, Operand* v) {
s = push(s, v);
if (BytesPerWord == 8) s = push(s, immediate(&c, 0));
return s; return s;
} }
virtual void pop(unsigned count) { virtual Operand* stack(Stack* s, unsigned index) {
::pop(&c, count); MyStack* stack = static_cast<MyStack*>(s);
unsigned i = 0;
if (stack->value->footprint() / BytesPerWord == 2) {
++ i;
} }
virtual Operand* pop() { for (; i < index; ++i) {
Operand* tmp = static_cast<MyOperand*>(temporary()); stack = stack->next;
pop(tmp); if (stack->value->footprint() / BytesPerWord == 2) {
return tmp; ++ i;
}
} }
virtual Operand* pop2() { return stack->value;
if (BytesPerWord == 8) pop(1);
return pop();
} }
virtual void pop(Operand* dst) { virtual Stack* pop(Stack* s, unsigned count) {
::pop(&c, static_cast<MyOperand*>(dst)); return ::pop(&c, static_cast<MyStack*>(s), count);
} }
virtual void pop2(Operand* dst) { virtual Stack* pop(Stack* s, Operand* dst) {
if (BytesPerWord == 8) pop(1); return ::pop(&c, static_cast<MyStack*>(s), static_cast<MyOperand*>(dst));
pop(dst); }
virtual Stack* pop2(Stack* s, Operand* dst) {
if (BytesPerWord == 8) s = pop(s, 1);
return pop(s, dst);
} }
virtual Operand* stack() { virtual Operand* stack() {
@ -1764,14 +1910,8 @@ class MyCompiler: public Compiler {
} }
virtual void mark(Operand* label) { virtual void mark(Operand* label) {
CodePromise* p = new (c.zone.allocate(sizeof(CodePromise))) static_cast<MyOperand*>(label)->setLabelValue
CodePromise(true); (&c, static_cast<MyPromise*>(machineIp()));
Segment* s = currentSegment(&c);
s->event->task = new (c.zone.allocate(sizeof(CodePromiseTask)))
CodePromiseTask(p, s->event->task);
static_cast<MyOperand*>(label)->setLabelValue(&c, p);
} }
virtual Operand* indirectCall virtual Operand* indirectCall
@ -1972,15 +2112,6 @@ class MyCompiler: public Compiler {
Segment(ip, new (c.zone.allocate(sizeof(Event))) Event(0))); Segment(ip, new (c.zone.allocate(sizeof(Event))) Event(0)));
} }
virtual Operand* logicalIp(unsigned ip) {
return address
(&c, new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip, true));
}
virtual Promise* logicalIpToOffset(unsigned ip) {
return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip, false);
}
virtual unsigned codeSize() { virtual unsigned codeSize() {
if (c.codeLength < 0) { if (c.codeLength < 0) {
assert(&c, c.code.length() == 0); assert(&c, c.code.length() == 0);
@ -1997,9 +2128,10 @@ class MyCompiler: public Compiler {
c.code.wrap(out, codeSize()); c.code.wrap(out, codeSize());
writeCode(&c); writeCode(&c);
memcpy(out + codeSize(), for (unsigned i = 0; i < c.constantPool.length(); i += BytesPerWord) {
c.constantPool.data, Promise* p; c.constantPool.get(i, &p, BytesPerWord);
c.constantPool.length()); *reinterpret_cast<intptr_t*>(out + codeSize() + i) = p->value(this);
}
} }
virtual void updateCall(void* returnAddress, void* newTarget) { virtual void updateCall(void* returnAddress, void* newTarget) {

View File

@ -7,6 +7,8 @@ namespace vm {
class Operand { }; class Operand { };
class Stack { };
class Compiler; class Compiler;
class Promise { class Promise {
@ -20,20 +22,29 @@ class Compiler {
public: public:
virtual ~Compiler() { } virtual ~Compiler() { }
virtual Promise* poolOffset() = 0; virtual Promise* machineIp() = 0;
virtual Promise* codeOffset() = 0; virtual Promise* machineIp(unsigned logicalIp) = 0;
virtual Promise* logicalIpToOffset(unsigned) = 0;
virtual Operand* poolAppend(Operand*) = 0; virtual Promise* poolAppend(intptr_t) = 0;
virtual Promise* poolAppendPromise(Promise*) = 0;
virtual Operand* constant(intptr_t) = 0; virtual Operand* constant(intptr_t) = 0;
virtual Operand* promiseConstant(Promise*) = 0;
virtual Operand* absolute(Promise*) = 0;
virtual Operand* memory(Operand* base, int displacement = 0,
Operand* index = 0, unsigned scale = 1) = 0;
virtual Operand* select1(Operand*) = 0;
virtual Operand* select2(Operand*) = 0;
virtual Operand* select2z(Operand*) = 0;
virtual Operand* select4(Operand*) = 0;
virtual Operand* select8(Operand*) = 0;
virtual Operand* stack() = 0; virtual Operand* stack() = 0;
virtual Operand* base() = 0; virtual Operand* base() = 0;
virtual Operand* thread() = 0; virtual Operand* thread() = 0;
virtual Operand* indirectTarget() = 0; virtual Operand* indirectTarget() = 0;
virtual Operand* temporary() = 0; virtual Operand* temporary() = 0;
virtual Operand* stack(unsigned) = 0;
virtual void release(Operand*) = 0; virtual void release(Operand*) = 0;
virtual Operand* label() = 0; virtual Operand* label() = 0;
@ -46,19 +57,19 @@ class Compiler {
virtual Operand* directCall virtual Operand* directCall
(Operand* address, unsigned argumentCount, ...) = 0; (Operand* address, unsigned argumentCount, ...) = 0;
virtual Operand* call(Operand*) = 0;
virtual Operand* alignedCall(Operand*) = 0;
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 Stack* push(Stack*, unsigned count) = 0;
virtual void push(Operand*) = 0; virtual Stack* push(Stack*, Operand*) = 0;
virtual void push2(Operand*) = 0; virtual Stack* push2(Stack*, Operand*) = 0;
virtual void pop(unsigned count) = 0; virtual Stack* pop(Stack*, unsigned count) = 0;
virtual Operand* pop() = 0; virtual Stack* pop(Stack*, Operand*) = 0;
virtual Operand* pop2() = 0; virtual Stack* pop2(Stack*, Operand*) = 0;
virtual void pop(Operand*) = 0; virtual Operand* stack(Stack*, unsigned) = 0;
virtual void pop2(Operand*) = 0;
virtual Operand* call(Operand*) = 0;
virtual Operand* alignedCall(Operand*) = 0;
virtual void mov(Operand* src, Operand* dst) = 0; virtual void mov(Operand* src, Operand* dst) = 0;
virtual void cmp(Operand* subtrahend, Operand* minuend) = 0; virtual void cmp(Operand* subtrahend, Operand* minuend) = 0;
virtual void jl(Operand*) = 0; virtual void jl(Operand*) = 0;
@ -81,21 +92,11 @@ class Compiler {
virtual void xor_(Operand* v, Operand* dst) = 0; virtual void xor_(Operand* v, Operand* dst) = 0;
virtual void neg(Operand*) = 0; virtual void neg(Operand*) = 0;
virtual Operand* memory(Operand* base, int displacement = 0,
Operand* index = 0, unsigned scale = 1) = 0;
virtual Operand* select1(Operand*) = 0;
virtual Operand* select2(Operand*) = 0;
virtual Operand* select2z(Operand*) = 0;
virtual Operand* select4(Operand*) = 0;
virtual Operand* select8(Operand*) = 0;
virtual void prologue() = 0; virtual void prologue() = 0;
virtual void reserve(unsigned size) = 0; virtual void reserve(unsigned size) = 0;
virtual void epilogue() = 0; virtual void epilogue() = 0;
virtual void startLogicalIp(unsigned) = 0; virtual void startLogicalIp(unsigned) = 0;
virtual Operand* logicalIp(unsigned) = 0;
virtual unsigned codeSize() = 0; virtual unsigned codeSize() = 0;
virtual unsigned poolSize() = 0; virtual unsigned poolSize() = 0;

View File

@ -1,6 +1,7 @@
public class Misc { public class Misc {
private static int alpha; private static int alpha;
private static int beta; private static int beta;
private int gamma;
private String foo(String s) { private String foo(String s) {
return s; return s;
@ -14,10 +15,14 @@ public class Misc {
return s; return s;
} }
private static void expect(boolean v) {
if (! v) throw new RuntimeException();
}
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();
int a = 2; int a = 2;
int b = 2; int b = 2;
@ -29,10 +34,15 @@ public class Misc {
m.bar(s); m.bar(s);
baz(s); baz(s);
// int d = alpha; int d = alpha;
// beta = 42; beta = 42;
// alpha = 43; alpha = 43;
// int e = beta; int e = beta;
// int f = alpha; int f = alpha;
m.gamma = 44;
expect(beta == 42);
expect(alpha == 43);
expect(m.gamma == 44);
} }
} }