diff --git a/src/compile.cpp b/src/compile.cpp index cebeb4f00f..bb8afc1d7d 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -552,10 +552,16 @@ class Frame { } ~Frame() { - if (level > 1 and t->exception == 0) { - c->popState(); + if (t->exception == 0) { + if (level > 0) { + c->saveStack(); + c->popState(); + c->resetStack(); + } - context->eventLog.append(PopEvent); + if (level > 1) { + context->eventLog.append(PopEvent); + } } } @@ -2913,17 +2919,25 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* b = frame->popLong(); c->cmp(8, a, b); + c->jl(less); + c->pushState(); + c->jg(greater); + c->pushState(); c->push(4, c->constant(0)); c->jmp(next); - + + c->popState(); c->mark(less); + c->push(4, c->constant(-1)); c->jmp(next); + c->popState(); c->mark(greater); + c->push(4, c->constant(1)); c->mark(next); @@ -3085,13 +3099,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } return; case lshl: { - Compiler::Operand* a = frame->popLong(); + Compiler::Operand* a = frame->popInt(); Compiler::Operand* b = frame->popLong(); frame->pushLong(c->shl(8, a, b)); } break; case lshr: { - Compiler::Operand* a = frame->popLong(); + Compiler::Operand* a = frame->popInt(); Compiler::Operand* b = frame->popLong(); frame->pushLong(c->shr(8, a, b)); } break; @@ -3128,7 +3142,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case lushr: { - Compiler::Operand* a = frame->popLong(); + Compiler::Operand* a = frame->popInt(); Compiler::Operand* b = frame->popLong(); frame->pushLong(c->ushr(8, a, b)); } break; @@ -3861,11 +3875,11 @@ finish(MyThread* t, Context* context) strcmp (reinterpret_cast (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), - "java/lang/Class") == 0 and + "java/nio/ByteBuffer") == 0 and strcmp (reinterpret_cast (&byteArrayBody(t, methodName(t, context->method), 0)), - "replace") == 0) + "checkPut") == 0) { asm("int3"); } diff --git a/src/compiler.cpp b/src/compiler.cpp index d411d3d1cb..d9afedf22b 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -556,11 +556,11 @@ increment(Context* c, int r) void decrement(Context* c, int r) { - assert(c, c->registers[r].refCount > 0); - assert(c, c->registers[r].refCount > 1 or (not c->registers[r].reserved)); if (DebugRegisters) { fprintf(stderr, "decrement %d to %d\n", r, c->registers[r].refCount - 1); } + assert(c, c->registers[r].refCount > 0); + assert(c, c->registers[r].refCount > 1 or (not c->registers[r].reserved)); -- c->registers[r].refCount; } @@ -1783,6 +1783,13 @@ count(Stack* s) void pushState(Context* c) { + if (DebugAppend) { + unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count; + fprintf(stderr, "push at level %d\n", count); + count = 0; for (Stack* s = c->state->stack; s; s = s->next) ++ count; + fprintf(stderr, "stack count: %d\n", count); + } + c->state = new (c->zone->allocate(sizeof(State))) State(c->state, c->state->stack); } @@ -1793,18 +1800,27 @@ saveStack(Context* c) if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp].stackSaved) { c->logicalCode[c->logicalIp].stackSaved = true; c->logicalCode[c->logicalIp].stack = c->state->stack; + + if (DebugAppend) { + unsigned count = 0; + for (Stack* s = c->state->stack; s; s = s->next) ++ count; + fprintf(stderr, "stack count after ip %d: %d\n", c->logicalIp, count); + } } } void popState(Context* c) { - saveStack(c); - c->state = new (c->zone->allocate(sizeof(State))) State(c->state->next->next, c->state->next->stack); - resetStack(c); + if (DebugAppend) { + unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count; + fprintf(stderr, "pop to level %d\n", count); + count = 0; for (Stack* s = c->state->stack; s; s = s->next) ++ count; + fprintf(stderr, "stack count: %d\n", count); + } } Stack* @@ -1984,6 +2000,14 @@ class MyCompiler: public Compiler { ::popState(&c); } + virtual void saveStack() { + ::saveStack(&c); + } + + virtual void resetStack() { + ::resetStack(&c); + } + virtual void init(unsigned logicalCodeLength, unsigned stackOffset) { c.logicalCodeLength = logicalCodeLength; c.stackOffset = stackOffset; @@ -2010,7 +2034,7 @@ class MyCompiler: public Compiler { visit(&c, logicalIp); - saveStack(&c); + ::saveStack(&c); c.logicalIp = logicalIp; } @@ -2110,7 +2134,7 @@ class MyCompiler: public Compiler { virtual void mark(Operand* label) { appendStackSync(&c); - resetStack(&c); + ::resetStack(&c); for (Site* s = static_cast(label)->sites; s; s = s->next) { if (s->type(&c) == ConstantOperand) { diff --git a/src/compiler.h b/src/compiler.h index 62f4387be5..d17396a484 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -28,6 +28,8 @@ class Compiler { virtual void pushState() = 0; virtual void popState() = 0; + virtual void saveStack() = 0; + virtual void resetStack() = 0; virtual void init(unsigned logicalCodeSize, unsigned localFootprint) = 0; diff --git a/src/x86.cpp b/src/x86.cpp index 3bfa697763..bcbbdea3dd 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -575,14 +575,45 @@ moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, } void -moveCM(Context* c, unsigned size UNUSED, Assembler::Constant* a, +moveCM(Context* c, unsigned size, Assembler::Constant* a, Assembler::Memory* b) { - assert(c, isInt32(a->value->value())); // todo - assert(c, BytesPerWord == 8 or size == 4); // todo + int64_t v = a->value->value(); - encode(c, 0xc7, 0, b, true); - c->code.append4(a->value->value()); + if (BytesPerWord == 4 and size == 8) { + ResolvedPromise high((v >> 32) & 0xFFFFFFFF); + Assembler::Constant ah(&high); + + ResolvedPromise low(v & 0xFFFFFFFF); + Assembler::Constant al(&low); + + Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale); + + moveCM(c, 4, &al, b); + moveCM(c, 4, &ah, &bh); + } else if (BytesPerWord == 8 and size == 4) { + encode(c, 0xc7, 0, b, false); + c->code.append4(a->value->value()); + } else { + switch (size) { + case 1: + encode(c, 0xc6, 0, b, false); + c->code.append(a->value->value()); + break; + + case 2: + encode2(c, 0x66c7, 0, b, false); + c->code.append2(a->value->value()); + break; + + case BytesPerWord: + encode(c, 0xc7, 0, b, true); + c->code.append4(a->value->value()); + break; + + default: abort(c); + } + } } void @@ -1103,7 +1134,7 @@ andCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, } else { c->code.append(0x81); c->code.append(0xe0 | b->low); - c->code.append(v); + c->code.append4(v); } } else { Assembler::Register tmp(c->client->acquireTemporary()); @@ -1131,6 +1162,17 @@ andCM(Context* c, unsigned size UNUSED, Assembler::Constant* a, } } +void +orRR(Context* c, unsigned size UNUSED, Assembler::Register* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); // todo + + rex(c); + c->code.append(0x09); + c->code.append(0xc0 | (a->low << 3) | b->low); +} + void xorRR(Context* c, unsigned size UNUSED, Assembler::Register* a, Assembler::Register* b) @@ -1171,46 +1213,89 @@ xorCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, } void -shiftLeftCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, - Assembler::Register* b) -{ - assert(c, BytesPerWord == 8 or size == 4); +shift(Context* c, int type, Assembler::Register* a, Assembler::Register* b) { + if (a->low == rcx) { + rex(c); + c->code.append(0xd3); + c->code.append(type | b->low); + } else { + Assembler::Register cx(c->client->acquireTemporary(rcx)); + moveRR(c, BytesPerWord, a, &cx); + shift(c, type, &cx, b); + c->client->releaseTemporary(cx.low); + } +} +void +shift(Context* c, int type, Assembler::Constant* a, Assembler::Register* b) +{ int64_t v = a->value->value(); rex(c); if (v == 1) { c->code.append(0xd1); - c->code.append(0xe0 | b->low); + c->code.append(type | b->low); } else if (isInt8(v)) { c->code.append(0xc1); - c->code.append(0xe0 | b->low); + c->code.append(type | b->low); c->code.append(v); } else { abort(c); - } + } } void -compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, - Assembler::Register* b) +shiftLeftRR(Context* c, unsigned size UNUSED, Assembler::Register* a, + Assembler::Register* b) { assert(c, BytesPerWord == 8 or size == 4); - int64_t v = a->value->value(); + shift(c, 0xe0, a, b); +} - if (size == 8) rex(c); - if (isInt8(v)) { - c->code.append(0x83); - c->code.append(0xf8 | b->low); - c->code.append(v); - } else if (isInt32(v)) { - c->code.append(0x81); - c->code.append(0xf8 | b->low); - c->code.append4(v); - } else { - abort(c); - } +void +shiftLeftCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + shift(c, 0xe0, a, b); +} + +void +shiftRightRR(Context* c, unsigned size UNUSED, Assembler::Register* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + shift(c, 0xf8, a, b); +} + +void +shiftRightCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + shift(c, 0xf8, a, b); +} + +void +unsignedShiftRightRR(Context* c, unsigned size UNUSED, Assembler::Register* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + shift(c, 0xe8, a, b); +} + +void +unsignedShiftRightCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + shift(c, 0xe8, a, b); } void @@ -1237,6 +1322,33 @@ compareRR(Context* c, unsigned size UNUSED, Assembler::Register* a, } } +void +compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, + Assembler::Register* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + int64_t v = a->value->value(); + + if (isInt32(v)) { + if (size == 8) rex(c); + if (isInt8(v)) { + c->code.append(0x83); + c->code.append(0xf8 | b->low); + c->code.append(v); + } else { + c->code.append(0x81); + c->code.append(0xf8 | b->low); + c->code.append4(v); + } + } else { + Assembler::Register tmp(c->client->acquireTemporary()); + moveCR(c, size, a, &tmp); + compareRR(c, size, &tmp, b); + c->client->releaseTemporary(tmp.low); + } +} + void compareCM(Context* c, unsigned size UNUSED, Assembler::Constant* a, Assembler::Memory* b) @@ -1356,11 +1468,24 @@ populateTables() BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR); BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM); + BinaryOperations[INDEX2(Or, Register, Register)] = CAST2(orRR); + BinaryOperations[INDEX2(Xor, Register, Register)] = CAST2(xorRR); BinaryOperations[INDEX2(Xor, Constant, Register)] = CAST2(xorCR); + BinaryOperations[INDEX2(ShiftLeft, Register, Register)] = CAST2(shiftLeftRR); BinaryOperations[INDEX2(ShiftLeft, Constant, Register)] = CAST2(shiftLeftCR); + BinaryOperations[INDEX2(ShiftRight, Register, Register)] + = CAST2(shiftRightRR); + BinaryOperations[INDEX2(ShiftRight, Constant, Register)] + = CAST2(shiftRightCR); + + BinaryOperations[INDEX2(UnsignedShiftRight, Register, Register)] + = CAST2(unsignedShiftRightRR); + BinaryOperations[INDEX2(UnsignedShiftRight, Constant, Register)] + = CAST2(unsignedShiftRightCR); + BinaryOperations[INDEX2(Subtract, Constant, Register)] = CAST2(subtractCR); BinaryOperations[INDEX2(Subtract, Register, Register)] = CAST2(subtractRR); diff --git a/test/Misc.java b/test/Misc.java index 81ac4b60ca..9c4aeded4a 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -10,13 +10,13 @@ public class Misc { private long time; public Misc() { -// expect(! boolean1); -// expect(! boolean2); + expect(! boolean1); + expect(! boolean2); -// time = 0xffffffffffffffffL; + time = 0xffffffffffffffffL; -// expect(! boolean1); -// expect(! boolean2); + expect(! boolean1); + expect(! boolean2); } private String foo(String s) { @@ -67,39 +67,44 @@ public class Misc { } public static void main(String[] args) { -// byte2 = 0; -// expect(byte2 == 0); + byte2 = 0; + expect(byte2 == 0); -// expect(Long.valueOf(231L) == 231L); + expect(Long.valueOf(231L) == 231L); -// long x = 231; -// expect((x >> 32) == 0); -// expect((x >>> 32) == 0); -// expect((x << 32) == 992137445376L); + long x = 231; + expect((x >> 32) == 0); + expect((x >>> 32) == 0); + expect((x << 32) == 992137445376L); -// long y = -231; -// expect((y >> 32) == 0xffffffffffffffffL); -// expect((y >>> 32) == 0xffffffffL); + int shift = 32; + expect((x >> shift) == 0); + expect((x >>> shift) == 0); + expect((x << shift) == 992137445376L); -// byte[] array = new byte[8]; -// putLong(231, array, 0); -// expect((array[0] & 0xff) == 0); -// expect((array[1] & 0xff) == 0); -// expect((array[2] & 0xff) == 0); -// expect((array[3] & 0xff) == 0); -// expect((array[4] & 0xff) == 0); -// expect((array[5] & 0xff) == 0); -// expect((array[6] & 0xff) == 0); -// expect((array[7] & 0xff) == 231); + long y = -231; + expect((y >> 32) == 0xffffffffffffffffL); + expect((y >>> 32) == 0xffffffffL); -// java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8); -// buffer.putLong(231); -// buffer.flip(); -// expect(buffer.getLong() == 231); + byte[] array = new byte[8]; + putLong(231, array, 0); + expect((array[0] & 0xff) == 0); + expect((array[1] & 0xff) == 0); + expect((array[2] & 0xff) == 0); + expect((array[3] & 0xff) == 0); + expect((array[4] & 0xff) == 0); + expect((array[5] & 0xff) == 0); + expect((array[6] & 0xff) == 0); + expect((array[7] & 0xff) == 231); -// boolean v = Boolean.valueOf("true"); + java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8); + buffer.putLong(231); + buffer.flip(); + expect(buffer.getLong() == 231); -// ClassLoader.getSystemClassLoader().toString(); + boolean v = Boolean.valueOf("true"); + + ClassLoader.getSystemClassLoader().toString(); int a = 2; int b = 2; @@ -113,23 +118,23 @@ public class Misc { m.bar(s); baz(s); -// m.sync(); -// syncStatic(false); -// try { -// syncStatic(true); -// } catch (RuntimeException e) { -// e.printStackTrace(); -// } + m.sync(); + syncStatic(false); + try { + syncStatic(true); + } catch (RuntimeException e) { + e.printStackTrace(); + } -// int d = alpha; -// beta = 42; -// alpha = 43; -// int e = beta; -// int f = alpha; -// m.gamma = 44; + int d = alpha; + beta = 42; + alpha = 43; + int e = beta; + int f = alpha; + m.gamma = 44; -// expect(beta == 42); -// expect(alpha == 43); -// expect(m.gamma == 44); + expect(beta == 42); + expect(alpha == 43); + expect(m.gamma == 44); } }