diff --git a/src/compile.cpp b/src/compile.cpp index f88dc2857a..9ebdc3d1fc 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2187,13 +2187,17 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) Compiler::Operand* table; if (instruction == getstatic) { - c->call - (c->constant(reinterpret_cast(tryInitClass)), - context->indirection, - 0, - frame->trace(0, false), - 0, - 2, c->thread(), frame->append(fieldClass(t, field))); + if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) + and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + { + c->call + (c->constant(reinterpret_cast(tryInitClass)), + context->indirection, + 0, + frame->trace(0, false), + 0, + 2, c->thread(), frame->append(fieldClass(t, field))); + } table = frame->append(classStaticTable(t, fieldClass(t, field))); } else { @@ -3105,13 +3109,17 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) object staticTable = 0; if (instruction == putstatic) { - c->call - (c->constant(reinterpret_cast(tryInitClass)), - context->indirection, - 0, - frame->trace(0, false), - 0, - 2, c->thread(), frame->append(fieldClass(t, field))); + if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) + and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + { + c->call + (c->constant(reinterpret_cast(tryInitClass)), + context->indirection, + 0, + frame->trace(0, false), + 0, + 2, c->thread(), frame->append(fieldClass(t, field))); + } staticTable = classStaticTable(t, fieldClass(t, field)); } diff --git a/src/compiler.cpp b/src/compiler.cpp index 1d4ca71ed4..9057734c0a 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -40,7 +40,9 @@ class Value { virtual void acquire(Context*, Stack*, MyOperand*) { } virtual void release(Context*, MyOperand*) { } - virtual int registerValue(Context* c) { abort(c); } + virtual bool ready(Context*) { return true; } + + virtual int registerValue(Context*) { return NoRegister; } virtual int64_t constantValue(Context* c) { abort(c); } virtual void asAssemblerOperand(Context*, @@ -465,12 +467,25 @@ class AbstractMemoryValue: public MemoryValue { } } + virtual bool ready(Context* c) { + return base_->value->registerValue(c) != NoRegister + and (index_ == 0 or index_->value->registerValue(c) != NoRegister); + } + virtual int base(Context* c) { - return base_->value->registerValue(c); + int r = base_->value->registerValue(c); + assert(c, r != NoRegister); + return r; } virtual int index(Context* c) { - return index_ ? index_->value->registerValue(c) : NoRegister; + if (index_) { + int r = index_->value->registerValue(c); + assert(c, r != NoRegister); + return r; + } else { + return NoRegister; + } } MyOperand* base_; @@ -675,6 +690,81 @@ appendReturn(Context* c, unsigned size, MyOperand* value) new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, size, value); } +void +syncStack(Context* c, Stack* start, unsigned count) +{ + Stack* segment[count]; + unsigned index = count; + for (Stack* s = start; s and index; s = s->next) { + segment[--index] = s; + } + + for (unsigned i = 0; i < count; ++i) { + Stack* s = segment[i]; + if (s->operand->value) { + apply(c, Push, s->size * BytesPerWord, s->operand->value); + s->operand->value->release(c, s->operand); + } else { + Assembler::Register stack(c->assembler->stack()); + Assembler::Constant offset(resolved(c, s->size * BytesPerWord)); + c->assembler->apply + (Subtract, BytesPerWord, Constant, &offset, Register, &stack); + } + s->operand->pushed = true; + s->operand->value = stackValue(c, s); + } +} + +void +syncStack(Context* c, Stack* start) +{ + unsigned count = 0; + for (Stack* s = start; s and (not s->operand->pushed); s = s->next) { + ++ count; + } + + syncStack(c, start, count); +} + +class PushEvent: public Event { + public: + PushEvent(Context* c): + Event(c), active(false) + { + assert(c, stack->operand->push == 0); + stack->operand->push = this; + } + + virtual Value* target(Context*, MyOperand*) { + return 0; + } + + virtual unsigned operandSize(Context*) { + return 0; + } + + virtual void compile(Context* c) { + fprintf(stderr, "PushEvent.compile\n"); + + if (active) { + fprintf(stderr, "PushEvent.compile: active\n"); + syncStack(c, stack); + } + } + + void markStack(Context*) { + active = true; + } + + bool active; +}; + +void +appendPush(Context* c) +{ + new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c); +} + class CallEvent: public Event { public: CallEvent(Context* c, MyOperand* address, void* indirection, unsigned flags, @@ -724,7 +814,7 @@ class CallEvent: public Event { address->value->release(c, address); - if (result->event) { + if (result->event or (result->push and result->push->active)) { result->value = register_ (c, c->assembler->returnLow(), c->assembler->returnHigh()); result->value->acquire(c, stack, result); @@ -794,83 +884,6 @@ freeRegister(Context* c, unsigned size, bool allowAcquired) } } -void -syncStack(Context* c, Stack* start, unsigned count) -{ - Stack* segment[count]; - unsigned index = count; - for (Stack* s = start; s and index; s = s->next) { - segment[--index] = s; - } - - for (unsigned i = 0; i < count; ++i) { - Stack* s = segment[i]; - if (s->operand->value) { - apply(c, Push, s->size * BytesPerWord, s->operand->value); - s->operand->value->release(c, s->operand); - s->operand->pushed = true; - s->operand->value = stackValue(c, s); - } else { - Assembler::Register stack(c->assembler->stack()); - Assembler::Constant offset(resolved(c, s->size * BytesPerWord)); - c->assembler->apply - (Subtract, BytesPerWord, Constant, &offset, Register, &stack); - s->operand->pushed = true; - s->operand->value = stackValue(c, s); - } - } -} - -void -syncStack(Context* c, Stack* start) -{ - unsigned count = 0; - for (Stack* s = start; s and (not s->operand->pushed); s = s->next) { - ++ count; - } - - syncStack(c, start, count); -} - -class PushEvent: public Event { - public: - PushEvent(Context* c): - Event(c), active(false) - { - assert(c, stack->operand->push == 0); - stack->operand->push = this; - } - - virtual Value* target(Context* c, MyOperand*) { - abort(c); - } - - virtual unsigned operandSize(Context* c) { - abort(c); - } - - virtual void compile(Context* c) { - fprintf(stderr, "PushEvent.compile\n"); - - if (active) { - fprintf(stderr, "PushEvent.compile: active\n"); - syncStack(c, stack); - } - } - - void markStack() { - active = true; - } - - bool active; -}; - -void -appendPush(Context* c) -{ - new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c); -} - class PopEvent: public Event { public: PopEvent(Context* c, unsigned count, bool ignore): @@ -901,14 +914,14 @@ class PopEvent: public Event { if (dst->event->operandSize(c) == BytesPerWord) { target = dst->event->target(c, dst); } - if (target == 0) { + if (target == 0 or (not target->ready(c))) { target = freeRegister(c, BytesPerWord * s->size, false); } - apply(c, Pop, BytesPerWord * s->size, target); - target->acquire(c, 0, dst); + apply(c, Pop, BytesPerWord * s->size, target); + dst->value = target; } else { ignored += s->size; @@ -983,22 +996,26 @@ class MoveEvent: public Event { { dst->value = src->value; return; - } else { - src->target = freeRegister(c, size, true); } } else if (type == Move - and (size == BytesPerWord or src->target->type(c) == Memory) + and (size == BytesPerWord + or src->target->type(c) == Memory) and src->target->equals(c, src->value)) { dst->value = src->value; return; } - apply(c, type, size, src->value, src->target); - src->value->release(c, src); + + if (src->target == 0 or (not src->target->ready(c))) { + src->target = freeRegister(c, size, false); + } + src->target->acquire(c, stack, dst); + apply(c, type, size, src->value, src->target); + dst->value = src->target; } @@ -1052,7 +1069,7 @@ class DupEvent: public Event { if (dst->event) { target = dst->event->target(c, dst); } - if (target == 0) { + if (target == 0 or (not target->ready(c))) { target = freeRegister(c, size, true); } @@ -1236,7 +1253,7 @@ class CombineEvent: public Event { if (a->target == 0) a->target = target(c, a); if (b->target == 0) b->target = target(c, b); - if (b->target == 0) { + if (b->target == 0 or (not b->target->ready(c))) { b->target = freeRegister(c, BytesPerWord, true); } @@ -1309,6 +1326,10 @@ class TranslateEvent: public Event { if (a->target == 0) a->target = target(c, a); + if (not a->target->ready(c)) { + a->target = a->value; + } + result->value->acquire(c, stack, result); if (a->target and not a->target->equals(c, a->value)) { @@ -1473,11 +1494,11 @@ pop(Context* c, unsigned size UNUSED) } void -markStack(Context*, Stack* stack) +markStack(Context* c, Stack* stack) { for (Stack* s = stack; s; s = s->next) { if (s->operand->push) { - s->operand->push->markStack(); + s->operand->push->markStack(c); } } } @@ -1703,7 +1724,6 @@ class MyCompiler: public Compiler { MyOperand* a = operand(&c); ::push(&c, BytesPerWord, a); a->value = stackValue(&c, c.state->stack); - a->pushed = true; } } diff --git a/src/x86.cpp b/src/x86.cpp index 2b8f496f91..308e25b6ae 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -553,11 +553,24 @@ moveRR(Context* c, unsigned size, Assembler::Register* a, moveRR(c, 4, a, b); moveRR(c, 4, &ah, &bh); } else { - assert(c, BytesPerWord == 8 or size == 4); // todo + switch (size) { + case 1: + c->code.append(0xbe); + c->code.append(0xc0 | (a->low << 3) | b->low); + break; - rex(c); - c->code.append(0x89); - c->code.append(0xc0 | (a->low << 3) | b->low); + case 2: + c->code.append(0xbf); + c->code.append(0xc0 | (a->low << 3) | b->low); + break; + + case 8: + rex(c); + case 4: + c->code.append(0x89); + c->code.append(0xc0 | (a->low << 3) | b->low); + break; + } } }