From 00d8142de91f4f9b541f1eeda724909de0353505 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 9 Nov 2008 16:56:37 -0700 Subject: [PATCH] various bugfixes; all but one test are passing on amd64 --- src/assembler.h | 4 +- src/compile.cpp | 149 +++++++++++++++++++++++++++------------------- src/compiler.cpp | 150 +++++++++++++++++++++++------------------------ src/compiler.h | 1 - src/x86.cpp | 6 +- 5 files changed, 166 insertions(+), 144 deletions(-) diff --git a/src/assembler.h b/src/assembler.h index 779c71bfd7..df63d4fd99 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -103,7 +103,8 @@ class TraceHandler { public: virtual ~TraceHandler() { } - virtual void handleTrace(Promise* address) = 0; + virtual void handleTrace(Promise* address, unsigned padIndex, + unsigned padding) = 0; }; class Assembler { @@ -190,7 +191,6 @@ class Assembler { virtual unsigned frameReturnAddressSize() = 0; virtual unsigned frameFooterSize() = 0; virtual void nextFrame(void** stack, void** base) = 0; - virtual void* popReturnAddress(void* stack) = 0; virtual void plan (UnaryOperation op, diff --git a/src/compile.cpp b/src/compile.cpp index 91ac141cb9..d62d1db71c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -400,30 +400,36 @@ class TraceElement: public TraceHandler { bool virtualCall, TraceElement* next): context(context), address(0), + next(next), target(target), - virtualCall(virtualCall), - next(next) + padIndex(0), + padding(0), + virtualCall(virtualCall) { } - virtual void handleTrace(Promise* address) { + virtual void handleTrace(Promise* address, unsigned padIndex, + unsigned padding) + { if (this->address == 0) { this->address = address; + this->padIndex = padIndex; + this->padding = padding; } } Context* context; Promise* address; - object target; - bool virtualCall; TraceElement* next; + object target; + unsigned padIndex; + unsigned padding; + bool virtualCall; uintptr_t map[0]; }; enum Event { PushContextEvent, PopContextEvent, - PushEvent, - PopEvent, IpEvent, MarkEvent, ClearEvent, @@ -843,9 +849,6 @@ class Frame { void pushQuiet(unsigned footprint, Compiler::Operand* o) { c->push(footprint, o); - - context->eventLog.append(PushEvent); - context->eventLog.appendAddress(c->top()); } void pushLongQuiet(Compiler::Operand* o) { @@ -853,9 +856,6 @@ class Frame { } Compiler::Operand* popQuiet(unsigned footprint) { - context->eventLog.append(PopEvent); - context->eventLog.appendAddress(c->top()); - return c->pop(footprint); } @@ -883,9 +883,6 @@ class Frame { void pushObject() { c->pushed(); - context->eventLog.append(PushEvent); - context->eventLog.appendAddress(c->top()); - pushedObject(); } @@ -899,10 +896,6 @@ class Frame { for (unsigned i = count; i;) { Compiler::StackElement* s = c->top(); - - context->eventLog.append(PopEvent); - context->eventLog.appendAddress(s); - c->popped(); i -= c->footprint(s); } @@ -1178,16 +1171,18 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, unsigned parameterFootprint = methodParameterFootprint(t, method); unsigned localFootprint = localSize(t, method); - reinterpret_cast(stack) + static_cast(stack) [alignedFrameSize(t, method) - t->arch->frameHeaderSize() - - (localFootprint - parameterFootprint - 1)] + - (localFootprint - parameterFootprint - 1) + + t->arch->frameReturnAddressSize()] = t->exception; t->exception = 0; *targetIp = handler; *targetBase = base; - *targetStack = stack; + *targetStack = static_cast(stack) + + t->arch->frameReturnAddressSize(); } else { if (methodFlags(t, method) & ACC_SYNCHRONIZED) { object lock; @@ -1206,7 +1201,8 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, } else { *targetIp = ip; *targetBase = base; - *targetStack = t->arch->popReturnAddress(stack); + *targetStack = static_cast(stack) + + t->arch->frameReturnAddressSize(); } } } @@ -1763,8 +1759,7 @@ handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function) if (methodFlags(t, method) & ACC_STATIC) { lock = frame->append(methodClass(t, method)); } else { - lock = c->memory - (c->stack(), localOffset(t, savedTargetIndex(t, method), method)); + lock = c->loadLocal(1, savedTargetIndex(t, method)); } c->call(c->constant(function), @@ -1787,9 +1782,7 @@ handleEntrance(MyThread* t, Frame* frame) // save 'this' pointer in case it is overwritten. unsigned index = savedTargetIndex(t, method); - c->store(BytesPerWord, - c->memory(c->stack(), localOffset(t, 0, method)), - c->memory(c->stack(), localOffset(t, index, method))); + c->storeLocal(1, c->loadLocal(1, 0), index); frame->set(index, Frame::Object); } @@ -3546,8 +3539,6 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, // stack position (i.e. it is uninitialized or contains primitive // data). - Compiler* c = context->compiler; - unsigned localSize = ::localSize(t, context->method); unsigned mapSize = frameMapSizeInWords(t, context->method); @@ -3580,22 +3571,6 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, case PopContextEvent: return eventIndex; - case PushEvent: { - Compiler::StackElement* s; - context->eventLog.get(eventIndex, &s, BytesPerWord); - stackPadding += c->padding(s); - - eventIndex += BytesPerWord; - } break; - - case PopEvent: { - Compiler::StackElement* s; - context->eventLog.get(eventIndex, &s, BytesPerWord); - stackPadding -= c->padding(s); - - eventIndex += BytesPerWord; - } break; - case IpEvent: { ip = context->eventLog.get2(eventIndex); eventIndex += 2; @@ -3661,6 +3636,11 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, case TraceEvent: { TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord); + if (DebugFrameMaps) { + fprintf(stderr, "trace roots at ip %3d: ", ip); + printSet(*roots); + fprintf(stderr, "\n"); + } memcpy(te->map, roots, mapSize * BytesPerWord); eventIndex += BytesPerWord; @@ -3734,6 +3714,24 @@ finish(MyThread* t, Assembler* a, const char* name) return result; } +void +setBit(MyThread* t, object map, unsigned count, unsigned size, unsigned i, + unsigned j) +{ + unsigned index = ((i * size) + j); + intArrayBody(t, map, count + (index / 32)) + |= static_cast(1) << (index % 32); +} + +void +clearBit(MyThread* t, object map, unsigned count, unsigned size, unsigned i, + unsigned j) +{ + unsigned index = ((i * size) + j); + intArrayBody(t, map, count + (index / 32)) + &= ~(static_cast(1) << (index % 32)); +} + object finish(MyThread* t, Context* context) { @@ -3799,16 +3797,46 @@ finish(MyThread* t, Context* context) intArrayBody(t, map, i) = static_cast(p->address->value()) - reinterpret_cast(start); - for (unsigned j = 0; j < size; ++j) { - unsigned index = ((i * size) + j); - int32_t* v = &intArrayBody - (t, map, context->traceLogCount + (index / 32)); + if (DebugFrameMaps) { + fprintf(stderr, " orig roots at ip %p: ", reinterpret_cast + (p->address->value())); + printSet(p->map[0]); + fprintf(stderr, "\n"); - if (getBit(p->map, j)) { - *v |= static_cast(1) << (index % 32); - } else { - *v &= ~(static_cast(1) << (index % 32)); + fprintf(stderr, "final roots at ip %p: ", reinterpret_cast + (p->address->value())); + } + + for (unsigned j = 0, k = 0; j < size; ++j, ++k) { + if (j == p->padIndex) { + unsigned limit = j + p->padding; + assert(t, limit <= size); + + for (; j < limit; ++j) { + if (DebugFrameMaps) { + fprintf(stderr, "_"); + } + clearBit(t, map, context->traceLogCount, size, i, j); + } + + if (j == size) break; } + + if (getBit(p->map, k)) { + if (DebugFrameMaps) { + fprintf(stderr, "1"); + } + setBit(t, map, context->traceLogCount, size, i, j); + } else { + if (DebugFrameMaps) { + fprintf(stderr, "_"); + } + clearBit(t, map, context->traceLogCount, size, i, j); + } + } + + if (DebugFrameMaps) { + fprintf(stderr, "\n"); } } @@ -3839,7 +3867,7 @@ finish(MyThread* t, Context* context) strcmp (reinterpret_cast (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), - "GC") == 0 and + "NullPointer") == 0 and strcmp (reinterpret_cast (&byteArrayBody(t, methodName(t, context->method), 0)), @@ -3869,8 +3897,6 @@ compile(MyThread* t, Context* context) uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))]; Frame frame(context, stackMap); - handleEntrance(t, &frame); - unsigned index = 0; if ((methodFlags(t, context->method) & ACC_STATIC) == 0) { c->initLocal(1, index); @@ -3903,6 +3929,8 @@ compile(MyThread* t, Context* context) } } + handleEntrance(t, &frame); + Compiler::State* state = c->saveState(); compile(t, &frame, 0); @@ -4263,7 +4291,7 @@ visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* stack, object method, { unsigned count; if (calleeStack) { - count = alignedFrameSize(t, method) - argumentFootprint; + count = alignedFrameSizeWithParameters(t, method) - argumentFootprint; } else { count = alignedFrameSizeWithParameters(t, method); } @@ -4520,7 +4548,8 @@ class SegFaultHandler: public System::SignalHandler { t->ip = *ip; t->base = *base; - t->stack = *stack; + t->stack = static_cast(*stack) + - t->arch->frameReturnAddressSize(); ensure(t, FixedSizeOfNullPointerException + traceSize(t)); diff --git a/src/compiler.cpp b/src/compiler.cpp index 99a8036d30..f5755c640f 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -15,13 +15,13 @@ using namespace vm; namespace { -const bool DebugAppend = true; -const bool DebugCompile = true; +const bool DebugAppend = false; +const bool DebugCompile = false; const bool DebugStack = false; const bool DebugRegisters = false; const bool DebugFrameIndexes = false; const bool DebugFrame = false; -const bool DebugControl = true; +const bool DebugControl = false; const bool DebugReads = false; const int AnyFrameIndex = -2; @@ -117,13 +117,11 @@ class Site { class Stack: public Compiler::StackElement { public: Stack(unsigned index, unsigned footprint, Value* value, Stack* next): - index(index), footprint(footprint), paddingInWords(0), value(value), - next(next) + index(index), footprint(footprint), value(value), next(next) { } unsigned index; unsigned footprint; - unsigned paddingInWords; Value* value; Stack* next; }; @@ -825,10 +823,10 @@ nextRead(Context* c, Event* e, Value* v) { assert(c, e == v->reads->event); - if (DebugReads) { - fprintf(stderr, "pop read %p from %p next %p event %p (%s)\n", - v->reads, v, v->reads->next(c), e, (e ? e->name() : 0)); - } +// if (DebugReads) { +// fprintf(stderr, "pop read %p from %p next %p event %p (%s)\n", +// v->reads, v, v->reads->next(c), e, (e ? e->name() : 0)); +// } v->reads = v->reads->next(c); if (not live(v)) { @@ -1763,47 +1761,59 @@ find(Value* needle, Value* haystack) bool trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack, - Local* locals) + Local* locals, int avoid) { if (not hasMoreThanOneSite(v)) { - int index = NoFrameIndex; - for (unsigned li = 0; li < c->localFootprint; ++li) { - Local* local = locals + li; - if (find(v, local->value)) { - index = frameIndex(c, li, local->footprint); - break; - } - } - - if (index == NoFrameIndex) { - for (Stack* s = stack; s; s = s->next) { - if (find(v, s->value)) { - uint8_t typeMask; - uint64_t registerMask; - int frameIndex = AnyFrameIndex; - live(v)->intersect(&typeMask, ®isterMask, &frameIndex); - - if (frameIndex >= 0) { - index = frameIndex; - } else { - index = ::frameIndex - (c, s->index + c->localFootprint, s->footprint); + Read* r = live(v); + if (r->pickSite(c, v, true)) { + int index = NoFrameIndex; + for (unsigned li = 0; li < c->localFootprint; ++li) { + Local* local = locals + li; + if (find(v, local->value)) { + int fi = frameIndex(c, li, local->footprint); + if (fi != avoid) { + index = fi; + break; } - break; } } - } - if (index != NoFrameIndex - and (not site->match(c, 1 << MemoryOperand, 0, index))) - { - Site* saveSite = frameSite(c, index); - move(c, stack, locals, size, v, site, saveSite); - } else { - if (DebugRegisters or DebugFrameIndexes) { - fprintf(stderr, "unable to steal %p from %p\n", site, v); + if (index == NoFrameIndex) { + for (Stack* s = stack; s; s = s->next) { + fprintf(stderr, "%p belongs at %d\n", s->value, frameIndex + (c, s->index + c->localFootprint, s->footprint)); + + if (find(v, s->value)) { + uint8_t typeMask; + uint64_t registerMask; + int frameIndex = AnyFrameIndex; + live(v)->intersect(&typeMask, ®isterMask, &frameIndex); + + if (frameIndex >= 0 and frameIndex != avoid) { + index = frameIndex; + break; + } else { + int fi = ::frameIndex + (c, s->index + c->localFootprint, s->footprint); + if (fi != avoid) { + index = fi; + break; + } + } + } + } } - return false; + + if (index != NoFrameIndex) { + move(c, stack, locals, size, v, site, frameSite(c, index)); + } else { + if (DebugRegisters or DebugFrameIndexes) { + fprintf(stderr, "unable to steal %p from %p\n", site, v); + } + return false; + } + } else { + move(c, stack, locals, size, v, site, r->allocateSite(c)); } } @@ -1824,7 +1834,7 @@ trySteal(Context* c, Register* r, Stack* stack, Local* locals) fprintf(stderr, "try steal %d from %p\n", r->number, v); } - return trySteal(c, r->site, r->value, r->size, stack, locals); + return trySteal(c, r->site, r->value, r->size, stack, locals, NoFrameIndex); } bool @@ -2026,7 +2036,8 @@ trySteal(Context* c, FrameResource* r, Stack* stack, Local* locals) index, frameIndexToOffset(c, index), r->value, r->site); } - return trySteal(c, r->site, r->value, r->size, stack, locals); + return trySteal(c, r->site, r->value, r->size, stack, locals, + r - c->frameResources); } void @@ -2207,17 +2218,6 @@ codePromise(Context* c, Promise* offset) return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset); } -void -setPadding(Context* c, Stack* s, unsigned realIndex) -{ - unsigned logicalIndex = frameIndex - (c, s->index + c->localFootprint, s->footprint); - - assert(c, logicalIndex >= realIndex); - - s->paddingInWords = logicalIndex - realIndex; -} - void append(Context* c, Event* e); @@ -2232,6 +2232,8 @@ class CallEvent: public Event { traceHandler(traceHandler), result(result), popIndex(0), + padIndex(0), + padding(0), flags(flags), resultSize(resultSize) { @@ -2282,11 +2284,6 @@ class CallEvent: public Event { AnyFrameIndex)); int footprint = stackArgumentFootprint; - - if (footprint == 0 and s) { - setPadding(c, s, frameIndex); - } - for (Stack* s = stackBefore; s; s = s->next) { if (footprint > 0) { if (DebugReads) { @@ -2299,10 +2296,6 @@ class CallEvent: public Event { (c, footprintSizeInBytes(s->footprint), 1 << MemoryOperand, 0, frameIndex)); } else { - if (footprint == 0) { - popIndex = frameIndex; - } - unsigned index = ::frameIndex (c, s->index + c->localFootprint, s->footprint); @@ -2320,7 +2313,14 @@ class CallEvent: public Event { footprint -= s->footprint; if (footprint == 0) { - setPadding(c, s, frameIndex); + unsigned logicalIndex = ::frameIndex + (c, s->index + c->localFootprint, s->footprint); + + assert(c, logicalIndex >= frameIndex); + + padding = logicalIndex - frameIndex; + padIndex = s->index + c->localFootprint; + popIndex = frameIndex + s->footprint; } frameIndex += s->footprint; @@ -2352,7 +2352,8 @@ class CallEvent: public Event { address->source); if (traceHandler) { - traceHandler->handleTrace(codePromise(c, c->assembler->offset())); + traceHandler->handleTrace(codePromise(c, c->assembler->offset()), + padIndex, padding); } clean(c, this, stackBefore, localsBefore, reads, popIndex); @@ -2369,6 +2370,8 @@ class CallEvent: public Event { TraceHandler* traceHandler; Value* result; unsigned popIndex; + unsigned padIndex; + unsigned padding; unsigned flags; unsigned resultSize; }; @@ -3714,15 +3717,12 @@ compile(Context* c) for (Event* e = c->firstEvent; e; e = e->next) { if (DebugCompile) { fprintf(stderr, - " -- compile %s at %d with %d preds %d succs %d stack before " - "%d after\n", + " -- compile %s at %d with %d preds %d succs %d stack\n", e->name(), e->logicalInstruction->index, countPredecessors(e->predecessors), countSuccessors(e->successors), e->stackBefore ? - e->stackBefore->index + e->stackBefore->footprint : 0, - e->stackAfter ? - e->stackAfter->index + e->stackAfter->footprint : 0); + e->stackBefore->index + e->stackBefore->footprint : 0); } e->block = block; @@ -4186,10 +4186,6 @@ class MyCompiler: public Compiler { return static_cast(e)->footprint; } - virtual unsigned padding(StackElement* e) { - return static_cast(e)->paddingInWords; - } - virtual Operand* peek(unsigned footprint UNUSED, unsigned index) { Stack* s = c.stack; for (unsigned i = index; i > 0;) { diff --git a/src/compiler.h b/src/compiler.h index 80757ff8f2..b72ba4bff6 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -71,7 +71,6 @@ class Compiler { virtual void popped() = 0; virtual StackElement* top() = 0; virtual unsigned footprint(StackElement*) = 0; - virtual unsigned padding(StackElement*) = 0; virtual Operand* peek(unsigned footprint, unsigned index) = 0; virtual Operand* call(Operand* address, diff --git a/src/x86.cpp b/src/x86.cpp index 1468c5fa54..97abda39a9 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -2023,14 +2023,12 @@ class MyArchitecture: public Assembler::Architecture { } virtual void nextFrame(void** stack, void** base) { + assert(&c, *static_cast(*base) != *base); + *stack = static_cast(*base) + 1; *base = *static_cast(*base); } - virtual void* popReturnAddress(void* stack) { - return static_cast(stack) + 1; - } - virtual void plan (UnaryOperation, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,