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:
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,

View File

@ -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<void**>(stack)
static_cast<void**>(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<void**>(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<void**>(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<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
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())
- reinterpret_cast<intptr_t>(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<void*>
(p->address->value()));
printSet(p->map[0]);
fprintf(stderr, "\n");
if (getBit(p->map, j)) {
*v |= static_cast<int32_t>(1) << (index % 32);
} else {
*v &= ~(static_cast<int32_t>(1) << (index % 32));
fprintf(stderr, "final roots at ip %p: ", reinterpret_cast<void*>
(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<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"GC") == 0 and
"NullPointer") == 0 and
strcmp
(reinterpret_cast<const char*>
(&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<void**>(*stack)
- t->arch->frameReturnAddressSize();
ensure(t, FixedSizeOfNullPointerException + traceSize(t));

View File

@ -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, &registerMask, &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, &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);
}
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<Stack*>(e)->footprint;
}
virtual unsigned padding(StackElement* e) {
return static_cast<Stack*>(e)->paddingInWords;
}
virtual Operand* peek(unsigned footprint UNUSED, unsigned index) {
Stack* s = c.stack;
for (unsigned i = index; i > 0;) {

View File

@ -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,

View File

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