various bugfixes; all but one test are passing on amd64

This commit is contained in:
Joel Dice 2008-11-09 16:56:37 -07:00
parent 000aeb25c1
commit 00d8142de9
5 changed files with 166 additions and 144 deletions

View File

@ -103,7 +103,8 @@ class TraceHandler {
public: public:
virtual ~TraceHandler() { } virtual ~TraceHandler() { }
virtual void handleTrace(Promise* address) = 0; virtual void handleTrace(Promise* address, unsigned padIndex,
unsigned padding) = 0;
}; };
class Assembler { class Assembler {
@ -190,7 +191,6 @@ class Assembler {
virtual unsigned frameReturnAddressSize() = 0; virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0; virtual unsigned frameFooterSize() = 0;
virtual void nextFrame(void** stack, void** base) = 0; virtual void nextFrame(void** stack, void** base) = 0;
virtual void* popReturnAddress(void* stack) = 0;
virtual void plan virtual void plan
(UnaryOperation op, (UnaryOperation op,

View File

@ -400,30 +400,36 @@ class TraceElement: public TraceHandler {
bool virtualCall, TraceElement* next): bool virtualCall, TraceElement* next):
context(context), context(context),
address(0), address(0),
next(next),
target(target), target(target),
virtualCall(virtualCall), padIndex(0),
next(next) padding(0),
virtualCall(virtualCall)
{ } { }
virtual void handleTrace(Promise* address) { virtual void handleTrace(Promise* address, unsigned padIndex,
unsigned padding)
{
if (this->address == 0) { if (this->address == 0) {
this->address = address; this->address = address;
this->padIndex = padIndex;
this->padding = padding;
} }
} }
Context* context; Context* context;
Promise* address; Promise* address;
object target;
bool virtualCall;
TraceElement* next; TraceElement* next;
object target;
unsigned padIndex;
unsigned padding;
bool virtualCall;
uintptr_t map[0]; uintptr_t map[0];
}; };
enum Event { enum Event {
PushContextEvent, PushContextEvent,
PopContextEvent, PopContextEvent,
PushEvent,
PopEvent,
IpEvent, IpEvent,
MarkEvent, MarkEvent,
ClearEvent, ClearEvent,
@ -843,9 +849,6 @@ class Frame {
void pushQuiet(unsigned footprint, Compiler::Operand* o) { void pushQuiet(unsigned footprint, Compiler::Operand* o) {
c->push(footprint, o); c->push(footprint, o);
context->eventLog.append(PushEvent);
context->eventLog.appendAddress(c->top());
} }
void pushLongQuiet(Compiler::Operand* o) { void pushLongQuiet(Compiler::Operand* o) {
@ -853,9 +856,6 @@ class Frame {
} }
Compiler::Operand* popQuiet(unsigned footprint) { Compiler::Operand* popQuiet(unsigned footprint) {
context->eventLog.append(PopEvent);
context->eventLog.appendAddress(c->top());
return c->pop(footprint); return c->pop(footprint);
} }
@ -883,9 +883,6 @@ class Frame {
void pushObject() { void pushObject() {
c->pushed(); c->pushed();
context->eventLog.append(PushEvent);
context->eventLog.appendAddress(c->top());
pushedObject(); pushedObject();
} }
@ -899,10 +896,6 @@ class Frame {
for (unsigned i = count; i;) { for (unsigned i = count; i;) {
Compiler::StackElement* s = c->top(); Compiler::StackElement* s = c->top();
context->eventLog.append(PopEvent);
context->eventLog.appendAddress(s);
c->popped(); c->popped();
i -= c->footprint(s); i -= c->footprint(s);
} }
@ -1178,16 +1171,18 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
unsigned parameterFootprint = methodParameterFootprint(t, method); unsigned parameterFootprint = methodParameterFootprint(t, method);
unsigned localFootprint = localSize(t, method); unsigned localFootprint = localSize(t, method);
reinterpret_cast<void**>(stack) static_cast<void**>(stack)
[alignedFrameSize(t, method) - t->arch->frameHeaderSize() [alignedFrameSize(t, method) - t->arch->frameHeaderSize()
- (localFootprint - parameterFootprint - 1)] - (localFootprint - parameterFootprint - 1)
+ t->arch->frameReturnAddressSize()]
= t->exception; = t->exception;
t->exception = 0; t->exception = 0;
*targetIp = handler; *targetIp = handler;
*targetBase = base; *targetBase = base;
*targetStack = stack; *targetStack = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize();
} else { } else {
if (methodFlags(t, method) & ACC_SYNCHRONIZED) { if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
object lock; object lock;
@ -1206,7 +1201,8 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
} else { } else {
*targetIp = ip; *targetIp = ip;
*targetBase = base; *targetBase = base;
*targetStack = t->arch->popReturnAddress(stack); *targetStack = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize();
} }
} }
} }
@ -1763,8 +1759,7 @@ handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function)
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
lock = frame->append(methodClass(t, method)); lock = frame->append(methodClass(t, method));
} else { } else {
lock = c->memory lock = c->loadLocal(1, savedTargetIndex(t, method));
(c->stack(), localOffset(t, savedTargetIndex(t, method), method));
} }
c->call(c->constant(function), c->call(c->constant(function),
@ -1787,9 +1782,7 @@ handleEntrance(MyThread* t, Frame* frame)
// save 'this' pointer in case it is overwritten. // save 'this' pointer in case it is overwritten.
unsigned index = savedTargetIndex(t, method); unsigned index = savedTargetIndex(t, method);
c->store(BytesPerWord, c->storeLocal(1, c->loadLocal(1, 0), index);
c->memory(c->stack(), localOffset(t, 0, method)),
c->memory(c->stack(), localOffset(t, index, method)));
frame->set(index, Frame::Object); 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 // stack position (i.e. it is uninitialized or contains primitive
// data). // data).
Compiler* c = context->compiler;
unsigned localSize = ::localSize(t, context->method); unsigned localSize = ::localSize(t, context->method);
unsigned mapSize = frameMapSizeInWords(t, context->method); unsigned mapSize = frameMapSizeInWords(t, context->method);
@ -3580,22 +3571,6 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
case PopContextEvent: case PopContextEvent:
return eventIndex; 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: { case IpEvent: {
ip = context->eventLog.get2(eventIndex); ip = context->eventLog.get2(eventIndex);
eventIndex += 2; eventIndex += 2;
@ -3661,6 +3636,11 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
case TraceEvent: { case TraceEvent: {
TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord); 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); memcpy(te->map, roots, mapSize * BytesPerWord);
eventIndex += BytesPerWord; eventIndex += BytesPerWord;
@ -3734,6 +3714,24 @@ finish(MyThread* t, Assembler* a, const char* name)
return result; 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<int32_t>(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<int32_t>(1) << (index % 32));
}
object object
finish(MyThread* t, Context* context) finish(MyThread* t, Context* context)
{ {
@ -3799,16 +3797,46 @@ finish(MyThread* t, Context* context)
intArrayBody(t, map, i) = static_cast<intptr_t>(p->address->value()) intArrayBody(t, map, i) = static_cast<intptr_t>(p->address->value())
- reinterpret_cast<intptr_t>(start); - reinterpret_cast<intptr_t>(start);
for (unsigned j = 0; j < size; ++j) { if (DebugFrameMaps) {
unsigned index = ((i * size) + j); fprintf(stderr, " orig roots at ip %p: ", reinterpret_cast<void*>
int32_t* v = &intArrayBody (p->address->value()));
(t, map, context->traceLogCount + (index / 32)); printSet(p->map[0]);
fprintf(stderr, "\n");
if (getBit(p->map, j)) { fprintf(stderr, "final roots at ip %p: ", reinterpret_cast<void*>
*v |= static_cast<int32_t>(1) << (index % 32); (p->address->value()));
} else { }
*v &= ~(static_cast<int32_t>(1) << (index % 32));
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 strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"GC") == 0 and "NullPointer") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&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))]; uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
Frame frame(context, stackMap); Frame frame(context, stackMap);
handleEntrance(t, &frame);
unsigned index = 0; unsigned index = 0;
if ((methodFlags(t, context->method) & ACC_STATIC) == 0) { if ((methodFlags(t, context->method) & ACC_STATIC) == 0) {
c->initLocal(1, index); c->initLocal(1, index);
@ -3903,6 +3929,8 @@ compile(MyThread* t, Context* context)
} }
} }
handleEntrance(t, &frame);
Compiler::State* state = c->saveState(); Compiler::State* state = c->saveState();
compile(t, &frame, 0); compile(t, &frame, 0);
@ -4263,7 +4291,7 @@ visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* stack, object method,
{ {
unsigned count; unsigned count;
if (calleeStack) { if (calleeStack) {
count = alignedFrameSize(t, method) - argumentFootprint; count = alignedFrameSizeWithParameters(t, method) - argumentFootprint;
} else { } else {
count = alignedFrameSizeWithParameters(t, method); count = alignedFrameSizeWithParameters(t, method);
} }
@ -4520,7 +4548,8 @@ class SegFaultHandler: public System::SignalHandler {
t->ip = *ip; t->ip = *ip;
t->base = *base; t->base = *base;
t->stack = *stack; t->stack = static_cast<void**>(*stack)
- t->arch->frameReturnAddressSize();
ensure(t, FixedSizeOfNullPointerException + traceSize(t)); ensure(t, FixedSizeOfNullPointerException + traceSize(t));

View File

@ -15,13 +15,13 @@ using namespace vm;
namespace { namespace {
const bool DebugAppend = true; const bool DebugAppend = false;
const bool DebugCompile = true; const bool DebugCompile = false;
const bool DebugStack = false; const bool DebugStack = false;
const bool DebugRegisters = false; const bool DebugRegisters = false;
const bool DebugFrameIndexes = false; const bool DebugFrameIndexes = false;
const bool DebugFrame = false; const bool DebugFrame = false;
const bool DebugControl = true; const bool DebugControl = false;
const bool DebugReads = false; const bool DebugReads = false;
const int AnyFrameIndex = -2; const int AnyFrameIndex = -2;
@ -117,13 +117,11 @@ class Site {
class Stack: public Compiler::StackElement { class Stack: public Compiler::StackElement {
public: public:
Stack(unsigned index, unsigned footprint, Value* value, Stack* next): Stack(unsigned index, unsigned footprint, Value* value, Stack* next):
index(index), footprint(footprint), paddingInWords(0), value(value), index(index), footprint(footprint), value(value), next(next)
next(next)
{ } { }
unsigned index; unsigned index;
unsigned footprint; unsigned footprint;
unsigned paddingInWords;
Value* value; Value* value;
Stack* next; Stack* next;
}; };
@ -825,10 +823,10 @@ nextRead(Context* c, Event* e, Value* v)
{ {
assert(c, e == v->reads->event); assert(c, e == v->reads->event);
if (DebugReads) { // if (DebugReads) {
fprintf(stderr, "pop read %p from %p next %p event %p (%s)\n", // 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, v->reads->next(c), e, (e ? e->name() : 0));
} // }
v->reads = v->reads->next(c); v->reads = v->reads->next(c);
if (not live(v)) { if (not live(v)) {
@ -1763,47 +1761,59 @@ find(Value* needle, Value* haystack)
bool bool
trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack, trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack,
Local* locals) Local* locals, int avoid)
{ {
if (not hasMoreThanOneSite(v)) { if (not hasMoreThanOneSite(v)) {
int index = NoFrameIndex; Read* r = live(v);
for (unsigned li = 0; li < c->localFootprint; ++li) { if (r->pickSite(c, v, true)) {
Local* local = locals + li; int index = NoFrameIndex;
if (find(v, local->value)) { for (unsigned li = 0; li < c->localFootprint; ++li) {
index = frameIndex(c, li, local->footprint); Local* local = locals + li;
break; if (find(v, local->value)) {
} int fi = frameIndex(c, li, local->footprint);
} if (fi != avoid) {
index = fi;
if (index == NoFrameIndex) { break;
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, &registerMask, &frameIndex);
if (frameIndex >= 0) {
index = frameIndex;
} else {
index = ::frameIndex
(c, s->index + c->localFootprint, s->footprint);
} }
break;
} }
} }
}
if (index != NoFrameIndex if (index == NoFrameIndex) {
and (not site->match(c, 1 << MemoryOperand, 0, index))) for (Stack* s = stack; s; s = s->next) {
{ fprintf(stderr, "%p belongs at %d\n", s->value, frameIndex
Site* saveSite = frameSite(c, index); (c, s->index + c->localFootprint, s->footprint));
move(c, stack, locals, size, v, site, saveSite);
} else { if (find(v, s->value)) {
if (DebugRegisters or DebugFrameIndexes) { uint8_t typeMask;
fprintf(stderr, "unable to steal %p from %p\n", site, v); uint64_t registerMask;
int frameIndex = AnyFrameIndex;
live(v)->intersect(&typeMask, &registerMask, &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); 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 bool
@ -2026,7 +2036,8 @@ trySteal(Context* c, FrameResource* r, Stack* stack, Local* locals)
index, frameIndexToOffset(c, index), r->value, r->site); 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 void
@ -2207,17 +2218,6 @@ codePromise(Context* c, Promise* offset)
return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, 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 void
append(Context* c, Event* e); append(Context* c, Event* e);
@ -2232,6 +2232,8 @@ class CallEvent: public Event {
traceHandler(traceHandler), traceHandler(traceHandler),
result(result), result(result),
popIndex(0), popIndex(0),
padIndex(0),
padding(0),
flags(flags), flags(flags),
resultSize(resultSize) resultSize(resultSize)
{ {
@ -2282,11 +2284,6 @@ class CallEvent: public Event {
AnyFrameIndex)); AnyFrameIndex));
int footprint = stackArgumentFootprint; int footprint = stackArgumentFootprint;
if (footprint == 0 and s) {
setPadding(c, s, frameIndex);
}
for (Stack* s = stackBefore; s; s = s->next) { for (Stack* s = stackBefore; s; s = s->next) {
if (footprint > 0) { if (footprint > 0) {
if (DebugReads) { if (DebugReads) {
@ -2299,10 +2296,6 @@ class CallEvent: public Event {
(c, footprintSizeInBytes(s->footprint), (c, footprintSizeInBytes(s->footprint),
1 << MemoryOperand, 0, frameIndex)); 1 << MemoryOperand, 0, frameIndex));
} else { } else {
if (footprint == 0) {
popIndex = frameIndex;
}
unsigned index = ::frameIndex unsigned index = ::frameIndex
(c, s->index + c->localFootprint, s->footprint); (c, s->index + c->localFootprint, s->footprint);
@ -2320,7 +2313,14 @@ class CallEvent: public Event {
footprint -= s->footprint; footprint -= s->footprint;
if (footprint == 0) { 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; frameIndex += s->footprint;
@ -2352,7 +2352,8 @@ class CallEvent: public Event {
address->source); address->source);
if (traceHandler) { 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); clean(c, this, stackBefore, localsBefore, reads, popIndex);
@ -2369,6 +2370,8 @@ class CallEvent: public Event {
TraceHandler* traceHandler; TraceHandler* traceHandler;
Value* result; Value* result;
unsigned popIndex; unsigned popIndex;
unsigned padIndex;
unsigned padding;
unsigned flags; unsigned flags;
unsigned resultSize; unsigned resultSize;
}; };
@ -3714,15 +3717,12 @@ compile(Context* c)
for (Event* e = c->firstEvent; e; e = e->next) { for (Event* e = c->firstEvent; e; e = e->next) {
if (DebugCompile) { if (DebugCompile) {
fprintf(stderr, fprintf(stderr,
" -- compile %s at %d with %d preds %d succs %d stack before " " -- compile %s at %d with %d preds %d succs %d stack\n",
"%d after\n",
e->name(), e->logicalInstruction->index, e->name(), e->logicalInstruction->index,
countPredecessors(e->predecessors), countPredecessors(e->predecessors),
countSuccessors(e->successors), countSuccessors(e->successors),
e->stackBefore ? e->stackBefore ?
e->stackBefore->index + e->stackBefore->footprint : 0, e->stackBefore->index + e->stackBefore->footprint : 0);
e->stackAfter ?
e->stackAfter->index + e->stackAfter->footprint : 0);
} }
e->block = block; e->block = block;
@ -4186,10 +4186,6 @@ class MyCompiler: public Compiler {
return static_cast<Stack*>(e)->footprint; return static_cast<Stack*>(e)->footprint;
} }
virtual unsigned padding(StackElement* e) {
return static_cast<Stack*>(e)->paddingInWords;
}
virtual Operand* peek(unsigned footprint UNUSED, unsigned index) { virtual Operand* peek(unsigned footprint UNUSED, unsigned index) {
Stack* s = c.stack; Stack* s = c.stack;
for (unsigned i = index; i > 0;) { for (unsigned i = index; i > 0;) {

View File

@ -71,7 +71,6 @@ class Compiler {
virtual void popped() = 0; virtual void popped() = 0;
virtual StackElement* top() = 0; virtual StackElement* top() = 0;
virtual unsigned footprint(StackElement*) = 0; virtual unsigned footprint(StackElement*) = 0;
virtual unsigned padding(StackElement*) = 0;
virtual Operand* peek(unsigned footprint, unsigned index) = 0; virtual Operand* peek(unsigned footprint, unsigned index) = 0;
virtual Operand* call(Operand* address, virtual Operand* call(Operand* address,

View File

@ -2023,14 +2023,12 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual void nextFrame(void** stack, void** base) { virtual void nextFrame(void** stack, void** base) {
assert(&c, *static_cast<void**>(*base) != *base);
*stack = static_cast<void**>(*base) + 1; *stack = static_cast<void**>(*base) + 1;
*base = *static_cast<void**>(*base); *base = *static_cast<void**>(*base);
} }
virtual void* popReturnAddress(void* stack) {
return static_cast<void**>(stack) + 1;
}
virtual void plan virtual void plan
(UnaryOperation, (UnaryOperation,
unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,