This commit is contained in:
Joel Dice 2007-12-21 17:26:55 -07:00
parent ef97a5d8da
commit a867e4d587
5 changed files with 131 additions and 73 deletions

View File

@ -476,3 +476,16 @@ Java_java_lang_Double_fillBufferWithDouble(JNIEnv* e, jclass, jdouble val,
e->ReleaseByteArrayElements(buffer, buf, 0); e->ReleaseByteArrayElements(buffer, buf, 0);
return count; return count;
} }
extern "C" JNIEXPORT void JNICALL
Java_java_lang_Long_printLong(JNIEnv*, jclass, jlong v)
{
fprintf(stderr, "DEBUG: %lld\n", v);
}
extern "C" JNIEXPORT void JNICALL
Java_java_lang_Long_printInt(JNIEnv*, jclass, jint v)
{
fprintf(stderr, "DEBUG: %d\n", v);
}

View File

@ -38,11 +38,16 @@ public final class Long extends Number implements Comparable<Long> {
return String.valueOf(value); return String.valueOf(value);
} }
private static native void printLong(long v);
private static native void printInt(long v);
public static String toString(long v, int radix) { public static String toString(long v, int radix) {
if (radix < 1 || radix > 36) { if (radix < 1 || radix > 36) {
throw new IllegalArgumentException("radix " + radix + " not in [1,36]"); throw new IllegalArgumentException("radix " + radix + " not in [1,36]");
} }
printLong(v);
if (v == 0) { if (v == 0) {
return "0"; return "0";
} }
@ -53,10 +58,13 @@ public final class Long extends Number implements Comparable<Long> {
int size = (negative ? 1 : 0); int size = (negative ? 1 : 0);
for (long n = v; n > 0; n /= radix) ++size; for (long n = v; n > 0; n /= radix) ++size;
printInt(size);
char[] array = new char[size]; char[] array = new char[size];
int i = array.length - 1; int i = array.length - 1;
for (long n = v; n > 0; n /= radix) { for (long n = v; n > 0; n /= radix) {
printLong(n);
long digit = n % radix; long digit = n % radix;
if (digit >= 0 && digit <= 9) { if (digit >= 0 && digit <= 9) {
array[i] = (char) ('0' + digit); array[i] = (char) ('0' + digit);

View File

@ -18,7 +18,7 @@ vmJump(void* address, void* base, void* stack, void* thread);
namespace { namespace {
const bool Verbose = false; const bool Verbose = true;
const bool DebugTraces = false; const bool DebugTraces = false;
class MyThread: public Thread { class MyThread: public Thread {
@ -617,7 +617,7 @@ class Frame {
} }
void pushLong(Operand* o) { void pushLong(Operand* o) {
stack = c->push(stack, c->select8(o)); stack = c->push(stack, o);
if (BytesPerWord == 8) { if (BytesPerWord == 8) {
stack = c->push(stack, 1); stack = c->push(stack, 1);
} }
@ -654,7 +654,7 @@ class Frame {
} }
Operand* popInt() { Operand* popInt() {
Operand* tmp = c->temporary(); Operand* tmp = c->select4(c->temporary());
popInt(tmp); popInt(tmp);
return tmp; return tmp;
} }
@ -695,7 +695,8 @@ class Frame {
assert(t, index < codeMaxLocals(t, methodCode(t, method))); assert(t, index < codeMaxLocals(t, methodCode(t, method)));
assert(t, index < parameterFootprint(t, method) assert(t, index < parameterFootprint(t, method)
or getBit(map, index - parameterFootprint(t, method)) == 0); or getBit(map, index - parameterFootprint(t, method)) == 0);
pushInt(c->memory(c->base(), localOffset(t, index, method))); pushInt
(c->signExtend4(c->memory(c->base(), localOffset(t, index, method))));
} }
void loadLong(unsigned index) { void loadLong(unsigned index) {
@ -1180,8 +1181,10 @@ compileThrowNew(MyThread* t, Frame* frame, Machine::Type type)
} }
void void
pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result) pushReturnValue(MyThread* t, Frame* frame, unsigned code)
{ {
Object* result = c->result();
switch (code) { switch (code) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
@ -1189,7 +1192,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result)
case ShortField: case ShortField:
case FloatField: case FloatField:
case IntField: case IntField:
frame->pushInt(result); frame->pushInt(c->signExtend4(result));
break; break;
case ObjectField: case ObjectField:
@ -1198,7 +1201,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result)
case LongField: case LongField:
case DoubleField: case DoubleField:
frame->pushLong(result); frame->pushLong(c->select8(result));
break; break;
case VoidField: case VoidField:
@ -1207,6 +1210,8 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result)
default: default:
abort(t); abort(t);
} }
c->release(c);
} }
void void
@ -1275,15 +1280,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case faload: case faload:
case iaload: case iaload:
frame->pushInt(c->select4(c->memory(array, ArrayBody, index, 4))); frame->pushInt(c->signExtend4(c->memory(array, ArrayBody, index, 4)));
break; break;
case baload: case baload:
frame->pushInt(c->select1(c->memory(array, ArrayBody, index, 1))); frame->pushInt(c->signExtend1(c->memory(array, ArrayBody, index, 1)));
break; break;
case caload: case caload:
frame->pushInt(c->select2z(c->memory(array, ArrayBody, index, 2))); frame->pushInt(c->zeroExtend2(c->memory(array, ArrayBody, index, 2)));
break; break;
case daload: case daload:
@ -1292,7 +1297,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
break; break;
case saload: case saload:
frame->pushInt(c->select2(c->memory(array, ArrayBody, index, 2))); frame->pushInt(c->signExtend2(c->memory(array, ArrayBody, index, 2)));
break; break;
} }
@ -1350,21 +1355,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case fastore: case fastore:
case iastore: case iastore:
c->mov(value, c->select4(c->memory(array, ArrayBody, index, 4))); c->mov(c->select4(value), c->memory(array, ArrayBody, index, 4));
break; break;
case bastore: case bastore:
c->mov(value, c->select1(c->memory(array, ArrayBody, index, 1))); c->mov(c->select1(value), c->memory(array, ArrayBody, index, 1));
break; break;
case castore: case castore:
case sastore: case sastore:
c->mov(value, c->select2(c->memory(array, ArrayBody, index, 2))); c->mov(c->select2(value), c->memory(array, ArrayBody, index, 2));
break; break;
case dastore: case dastore:
case lastore: case lastore:
c->mov(value, c->select8(c->memory(array, ArrayBody, index, 8))); c->mov(c->select8(value), c->memory(array, ArrayBody, index, 8));
break; break;
} }
@ -1787,25 +1792,30 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (fieldCode(t, field)) { switch (fieldCode(t, field)) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
frame->pushInt(c->select1(c->memory(table, fieldOffset(t, field)))); frame->pushInt
(c->signExtend1(c->memory(table, fieldOffset(t, field))));
break; break;
case CharField: case CharField:
frame->pushInt(c->select2z(c->memory(table, fieldOffset(t, field)))); frame->pushInt
(c->zeroExtend2(c->memory(table, fieldOffset(t, field))));
break; break;
case ShortField: case ShortField:
frame->pushInt(c->select2(c->memory(table, fieldOffset(t, field)))); frame->pushInt
(c->signExtend2(c->memory(table, fieldOffset(t, field))));
break; break;
case FloatField: case FloatField:
case IntField: case IntField:
frame->pushInt(c->select4(c->memory(table, fieldOffset(t, field)))); frame->pushInt
(c->signExtend4(c->memory(table, fieldOffset(t, field))));
break; break;
case DoubleField: case DoubleField:
case LongField: case LongField:
frame->pushLong(c->select8(c->memory(table, fieldOffset(t, field)))); frame->pushLong
(c->select8(c->memory(table, fieldOffset(t, field))));
break; break;
case ObjectField: case ObjectField:
@ -1839,12 +1849,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case i2b: { case i2b: {
Operand* top = frame->topInt(); Operand* top = frame->topInt();
c->mov(c->select1(top), top); c->mov(c->signExtend1(top), top);
} break; } break;
case i2c: { case i2c: {
Operand* top = frame->topInt(); Operand* top = frame->topInt();
c->mov(c->select2z(top), top); c->mov(c->zeroExtend2(top), top);
} break; } break;
case i2d: { case i2d: {
@ -1865,13 +1875,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case i2l: { case i2l: {
Operand* a = frame->popInt(); Operand* a = frame->popInt();
frame->pushLong(a); frame->pushLong(c->signExtend4(a));
c->release(a); c->release(a);
} break; } break;
case i2s: { case i2s: {
Operand* top = frame->topInt(); Operand* top = frame->topInt();
c->mov(c->select2(top), top); c->mov(c->signExtend2(top), top);
} break; } break;
case iadd: { case iadd: {
@ -2739,22 +2749,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (fieldCode(t, field)) { switch (fieldCode(t, field)) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
c->mov(value, c->select1(c->memory(table, fieldOffset(t, field)))); c->mov(c->select1(value), c->memory(table, fieldOffset(t, field)));
break; break;
case CharField: case CharField:
case ShortField: case ShortField:
c->mov(value, c->select2(c->memory(table, fieldOffset(t, field)))); c->mov(c->select2(value), c->memory(table, fieldOffset(t, field)));
break; break;
case FloatField: case FloatField:
case IntField: case IntField:
c->mov(value, c->select4(c->memory(table, fieldOffset(t, field)))); c->mov(c->select4(value), c->memory(table, fieldOffset(t, field)));
break; break;
case DoubleField: case DoubleField:
case LongField: case LongField:
c->mov(value, c->select8(c->memory(table, fieldOffset(t, field)))); c->mov(c->select8(value), c->memory(table, fieldOffset(t, field)));
break; break;
case ObjectField: case ObjectField:
@ -2997,13 +3007,13 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
} }
// for debugging: // for debugging:
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/Throwable") == 0 and "java/lang/Long") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"init") == 0) "toString") == 0)
{ {
asm("int3"); asm("int3");
} }

View File

@ -27,11 +27,14 @@ enum Register {
}; };
enum SelectionType { enum SelectionType {
S1Selection, Select1,
S2Selection, Select2,
Z2Selection, Select4,
S4Selection, Select8,
S8Selection SignExtend1,
SignExtend2,
ZeroExtend2,
SignExtend4
}; };
const bool Verbose = false; const bool Verbose = false;
@ -1112,8 +1115,8 @@ RegisterOperand::apply(Context* c, Operation operation)
case S8Selection: case S8Selection:
assert(c, selection == S8Selection); assert(c, selection == S8Selection);
register_(c, high(c))->apply(c, pop);
register_(c, value(c))->apply(c, pop); register_(c, value(c))->apply(c, pop);
register_(c, high(c))->apply(c, pop);
break; break;
default: abort(c); default: abort(c);
@ -1125,16 +1128,10 @@ RegisterOperand::apply(Context* c, Operation operation)
if (selection == DefaultSelection) { if (selection == DefaultSelection) {
c->code.append(0x50 | value(c)); c->code.append(0x50 | value(c));
} else { } else {
switch (selection) { assert(c, selection == S8Selection);
case S8Selection:
assert(c, selection == S8Selection);
register_(c, value(c))->apply(c, push); register_(c, high(c))->apply(c, push);
register_(c, high(c))->apply(c, push); register_(c, value(c))->apply(c, push);
break;
default: abort(c);
}
} }
break; break;
@ -1579,6 +1576,8 @@ ImmediateOperand::apply(Context* c, Operation operation)
tmp->release(c); tmp->release(c);
} }
} else { } else {
assert(c, selection == S8Selection);
immediate(c, (value >> 32) & 0xFFFFFFFF)->apply(c, push); immediate(c, (value >> 32) & 0xFFFFFFFF)->apply(c, push);
immediate(c, (value ) & 0xFFFFFFFF)->apply(c, push); immediate(c, (value ) & 0xFFFFFFFF)->apply(c, push);
} }
@ -1678,11 +1677,24 @@ MemoryOperand::apply(Context* c, Operation operation)
if (selection == DefaultSelection) { if (selection == DefaultSelection) {
encode(c, 0xff, 6, this, false); encode(c, 0xff, 6, this, false);
} else { } else {
RegisterOperand* tmp = temporary switch (selection) {
(c, selection == S8Selection ? S8Selection : DefaultSelection); case S8Selection: {
tmp->accept(c, mov, this); MemoryOperand* low = memory(c, base, displacement, index, scale);
tmp->apply(c, operation); MemoryOperand* high = memory
tmp->release(c); (c, base, displacement + BytesPerWord, index, scale);
high->apply(c, push);
low->apply(c, push);
} break;
default: {
RegisterOperand* tmp = temporary
(c, selection == S8Selection ? S8Selection : DefaultSelection);
tmp->accept(c, mov, this);
tmp->apply(c, operation);
tmp->release(c);
} break;
}
} }
break; break;
@ -2169,7 +2181,7 @@ class MyCompiler: public Compiler {
(&c, static_cast<MyPromise*>(machineIp())); (&c, static_cast<MyPromise*>(machineIp()));
} }
virtual Operand* indirectCall virtual void indirectCall
(Operand* address, unsigned argumentCount, ...) (Operand* address, unsigned argumentCount, ...)
{ {
va_list a; va_start(a, argumentCount); va_list a; va_start(a, argumentCount);
@ -2180,8 +2192,6 @@ class MyCompiler: public Compiler {
call(immediate(&c, c.indirectCaller)); call(immediate(&c, c.indirectCaller));
add(immediate(&c, footprint), register_(&c, rsp)); add(immediate(&c, footprint), register_(&c, rsp));
return register_(&c, rax);
} }
virtual void indirectCallNoReturn virtual void indirectCallNoReturn
@ -2196,7 +2206,7 @@ class MyCompiler: public Compiler {
call(immediate(&c, c.indirectCaller)); call(immediate(&c, c.indirectCaller));
} }
virtual Operand* directCall virtual void directCall
(Operand* address, unsigned argumentCount, ...) (Operand* address, unsigned argumentCount, ...)
{ {
va_list a; va_start(a, argumentCount); va_list a; va_start(a, argumentCount);
@ -2206,8 +2216,10 @@ class MyCompiler: public Compiler {
call(address); call(address);
add(immediate(&c, footprint), register_(&c, rsp)); add(immediate(&c, footprint), register_(&c, rsp));
}
return register_(&c, rax); virtual Operand* result() {
return ::temporary(&c, rax, rdx);
} }
virtual void return_(Operand* v) { virtual void return_(Operand* v) {
@ -2216,14 +2228,12 @@ class MyCompiler: public Compiler {
ret(); ret();
} }
virtual Operand* call(Operand* v) { virtual void call(Operand* v) {
appendOperation(&c, MyOperand::call, v); appendOperation(&c, MyOperand::call, v);
return register_(&c, rax);
} }
virtual Operand* alignedCall(Operand* v) { virtual void alignedCall(Operand* v) {
appendOperation(&c, MyOperand::alignedCall, v); appendOperation(&c, MyOperand::alignedCall, v);
return register_(&c, rax);
} }
virtual void ret() { virtual void ret() {
@ -2322,23 +2332,35 @@ class MyCompiler: public Compiler {
} }
virtual Operand* select1(Operand* v) { virtual Operand* select1(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, S1Selection); return static_cast<MyOperand*>(v)->select(&c, Select1);
} }
virtual Operand* select2(Operand* v) { virtual Operand* select2(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, S2Selection); return static_cast<MyOperand*>(v)->select(&c, Select2);
}
virtual Operand* select2z(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, Z2Selection);
} }
virtual Operand* select4(Operand* v) { virtual Operand* select4(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, S4Selection); return static_cast<MyOperand*>(v)->select(&c, Select4);
} }
virtual Operand* select8(Operand* v) { virtual Operand* select8(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, S8Selection); return static_cast<MyOperand*>(v)->select(&c, Select8);
}
virtual Operand* signExtend1(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, SignExtend1);
}
virtual Operand* signExtend2(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, SignExtend2);
}
virtual Operand* zeroExtend2(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, ZeroExtend2);
}
virtual Operand* signExtend4(Operand* v) {
return static_cast<MyOperand*>(v)->select(&c, SignExtend4);
} }
virtual void prologue() { virtual void prologue() {

View File

@ -36,29 +36,34 @@ class Compiler {
virtual Operand* select1(Operand*) = 0; virtual Operand* select1(Operand*) = 0;
virtual Operand* select2(Operand*) = 0; virtual Operand* select2(Operand*) = 0;
virtual Operand* select2z(Operand*) = 0;
virtual Operand* select4(Operand*) = 0; virtual Operand* select4(Operand*) = 0;
virtual Operand* select8(Operand*) = 0; virtual Operand* select8(Operand*) = 0;
virtual Operand* signExtend1(Operand*) = 0;
virtual Operand* signExtend2(Operand*) = 0;
virtual Operand* zeroExtend2(Operand*) = 0;
virtual Operand* signExtend4(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* result() = 0;
virtual void release(Operand*) = 0; virtual void release(Operand*) = 0;
virtual Operand* label() = 0; virtual Operand* label() = 0;
virtual void mark(Operand*) = 0; virtual void mark(Operand*) = 0;
virtual Operand* indirectCall virtual void indirectCall
(Operand* address, unsigned argumentCount, ...) = 0; (Operand* address, unsigned argumentCount, ...) = 0;
virtual void indirectCallNoReturn virtual void indirectCallNoReturn
(Operand* address, unsigned argumentCount, ...) = 0; (Operand* address, unsigned argumentCount, ...) = 0;
virtual Operand* directCall virtual void directCall
(Operand* address, unsigned argumentCount, ...) = 0; (Operand* address, unsigned argumentCount, ...) = 0;
virtual Operand* call(Operand*) = 0; virtual void call(Operand*) = 0;
virtual Operand* alignedCall(Operand*) = 0; virtual void alignedCall(Operand*) = 0;
virtual void return_(Operand*) = 0; virtual void return_(Operand*) = 0;
virtual void ret() = 0; virtual void ret() = 0;