mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
bugfixes
This commit is contained in:
parent
684b402e82
commit
a51c4cef39
@ -2187,13 +2187,17 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
||||
Compiler::Operand* table;
|
||||
|
||||
if (instruction == getstatic) {
|
||||
c->call
|
||||
(c->constant(reinterpret_cast<intptr_t>(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<intptr_t>(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<intptr_t>(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<intptr_t>(tryInitClass)),
|
||||
context->indirection,
|
||||
0,
|
||||
frame->trace(0, false),
|
||||
0,
|
||||
2, c->thread(), frame->append(fieldClass(t, field)));
|
||||
}
|
||||
|
||||
staticTable = classStaticTable(t, fieldClass(t, field));
|
||||
}
|
||||
|
208
src/compiler.cpp
208
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
21
src/x86.cpp
21
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user