mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
insert stack sync events before each instruction with more than one predecessor
This commit is contained in:
parent
50eb1cbb71
commit
8baa2bbd87
@ -714,6 +714,8 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void visitLogicalIp(unsigned ip) {
|
void visitLogicalIp(unsigned ip) {
|
||||||
|
c->visitLogicalIp(ip);
|
||||||
|
|
||||||
context->eventLog.append(IpEvent);
|
context->eventLog.append(IpEvent);
|
||||||
context->eventLog.append2(ip);
|
context->eventLog.append2(ip);
|
||||||
}
|
}
|
||||||
@ -3849,11 +3851,11 @@ 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)),
|
||||||
"java/lang/String") == 0 and
|
"Enums") == 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)),
|
||||||
"getBytes") == 0)
|
"main") == 0)
|
||||||
{
|
{
|
||||||
asm("int3");
|
asm("int3");
|
||||||
}
|
}
|
||||||
|
120
src/compiler.cpp
120
src/compiler.cpp
@ -15,9 +15,10 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool DebugStack = false;
|
|
||||||
const bool DebugAppend = false;
|
const bool DebugAppend = false;
|
||||||
const bool DebugCompile = false;
|
const bool DebugCompile = false;
|
||||||
|
const bool DebugStack = false;
|
||||||
|
const bool DebugRegisters = false;
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
class Value;
|
class Value;
|
||||||
@ -60,7 +61,7 @@ class Stack {
|
|||||||
public:
|
public:
|
||||||
Stack(Value* value, unsigned size, unsigned index, Stack* next):
|
Stack(Value* value, unsigned size, unsigned index, Stack* next):
|
||||||
value(value), size(size), index(index), next(next), pushEvent(0),
|
value(value), size(size), index(index), next(next), pushEvent(0),
|
||||||
pushSite(0), pushed(false)
|
pushSite(0), syncSite(0), pushed(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -69,6 +70,7 @@ class Stack {
|
|||||||
Stack* next;
|
Stack* next;
|
||||||
PushEvent* pushEvent;
|
PushEvent* pushEvent;
|
||||||
Site* pushSite;
|
Site* pushSite;
|
||||||
|
Site* syncSite;
|
||||||
bool pushed;
|
bool pushed;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,6 +98,7 @@ class Register {
|
|||||||
Value* value;
|
Value* value;
|
||||||
Site* site;
|
Site* site;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned refCount;
|
||||||
bool reserved;
|
bool reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -172,8 +175,11 @@ class Context {
|
|||||||
{
|
{
|
||||||
memset(registers, 0, sizeof(Register) * assembler->registerCount());
|
memset(registers, 0, sizeof(Register) * assembler->registerCount());
|
||||||
|
|
||||||
|
registers[assembler->base()].refCount = 1;
|
||||||
registers[assembler->base()].reserved = true;
|
registers[assembler->base()].reserved = true;
|
||||||
|
registers[assembler->stack()].refCount = 1;
|
||||||
registers[assembler->stack()].reserved = true;
|
registers[assembler->stack()].reserved = true;
|
||||||
|
registers[assembler->thread()].refCount = 1;
|
||||||
registers[assembler->thread()].reserved = true;
|
registers[assembler->thread()].reserved = true;
|
||||||
|
|
||||||
unsigned fri = 0;
|
unsigned fri = 0;
|
||||||
@ -308,9 +314,9 @@ class Event {
|
|||||||
i->lastEvent = this;
|
i->lastEvent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(Context*, Event* next):
|
Event(Context*, Event* previous):
|
||||||
next(next), stack(next->stack), promises(0), reads(0),
|
next(0), stack(previous->stack), promises(0), reads(0),
|
||||||
sequence(next->sequence)
|
sequence(previous->sequence)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~Event() { }
|
virtual ~Event() { }
|
||||||
@ -512,6 +518,26 @@ registerSite(Context* c, int low, int high = NoRegister)
|
|||||||
RegisterSite*
|
RegisterSite*
|
||||||
freeRegister(Context* c, unsigned size, bool allowAcquired);
|
freeRegister(Context* c, unsigned size, bool allowAcquired);
|
||||||
|
|
||||||
|
void
|
||||||
|
increment(Context* c, int r)
|
||||||
|
{
|
||||||
|
if (DebugRegisters) {
|
||||||
|
fprintf(stderr, "increment %d\n", r);
|
||||||
|
}
|
||||||
|
++ c->registers[r].refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
decrement(Context* c, int r)
|
||||||
|
{
|
||||||
|
assert(c, c->registers[r].refCount > 0);
|
||||||
|
assert(c, c->registers[r].refCount > 1 or (not c->registers[r].reserved));
|
||||||
|
if (DebugRegisters) {
|
||||||
|
fprintf(stderr, "decrement %d\n", r);
|
||||||
|
}
|
||||||
|
-- c->registers[r].refCount;
|
||||||
|
}
|
||||||
|
|
||||||
class MemorySite: public Site {
|
class MemorySite: public Site {
|
||||||
public:
|
public:
|
||||||
MemorySite(int base, int offset, int index, unsigned scale):
|
MemorySite(int base, int offset, int index, unsigned scale):
|
||||||
@ -533,19 +559,17 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void acquire(Context* c, Stack* stack, unsigned size, Value* v,
|
virtual void acquire(Context* c, Stack*, unsigned, Value*, Site*) {
|
||||||
Site* s)
|
increment(c, value.base);
|
||||||
{
|
|
||||||
::acquire(c, value.base, stack, size, v, s);
|
|
||||||
if (value.index != NoRegister) {
|
if (value.index != NoRegister) {
|
||||||
::acquire(c, value.index, stack, size, v, s);
|
increment(c, value.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void release(Context* c) {
|
virtual void release(Context* c) {
|
||||||
::release(c, value.base);
|
decrement(c, value.base);
|
||||||
if (value.index != NoRegister) {
|
if (value.index != NoRegister) {
|
||||||
::release(c, value.index);
|
decrement(c, value.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -779,16 +803,22 @@ acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
{
|
{
|
||||||
if (c->registers[r].reserved) return;
|
if (c->registers[r].reserved) return;
|
||||||
|
|
||||||
// fprintf(stderr, "acquire %d, value %p, site %p\n",
|
if (DebugRegisters) {
|
||||||
// r, newValue, newSite);
|
fprintf(stderr, "acquire %d, value %p, site %p\n",
|
||||||
|
r, newValue, newSite);
|
||||||
|
}
|
||||||
|
|
||||||
Value* oldValue = c->registers[r].value;
|
Value* oldValue = c->registers[r].value;
|
||||||
if (oldValue
|
if (oldValue
|
||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, c->registers[r].site))
|
and findSite(c, oldValue, c->registers[r].site))
|
||||||
{
|
{
|
||||||
// fprintf(stderr, "steal %d from %p: next: %p\n",
|
assert(c, c->registers[r].refCount == 0);
|
||||||
// r, oldValue, oldValue->sites->next);
|
|
||||||
|
if (DebugRegisters) {
|
||||||
|
fprintf(stderr, "steal %d from %p: next: %p\n",
|
||||||
|
r, oldValue, oldValue->sites->next);
|
||||||
|
}
|
||||||
|
|
||||||
if (oldValue->sites->next == 0) {
|
if (oldValue->sites->next == 0) {
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
@ -818,6 +848,10 @@ acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
void
|
void
|
||||||
release(Context* c, int r)
|
release(Context* c, int r)
|
||||||
{
|
{
|
||||||
|
if (DebugRegisters) {
|
||||||
|
fprintf(stderr, "release %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
c->registers[r].size = 0;
|
c->registers[r].size = 0;
|
||||||
c->registers[r].value = 0;
|
c->registers[r].value = 0;
|
||||||
c->registers[r].site = 0;
|
c->registers[r].site = 0;
|
||||||
@ -845,7 +879,7 @@ apply(Context* c, BinaryOperation op, unsigned size, Site* a, Site* b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
insertRead(Context* c, Event* thisEvent, Event* before, Value* v,
|
insertRead(Context* c, Event* thisEvent, Event* previousEvent, Value* v,
|
||||||
unsigned size, Site* target)
|
unsigned size, Site* target)
|
||||||
{
|
{
|
||||||
Read* r = new (c->zone->allocate(sizeof(Read)))
|
Read* r = new (c->zone->allocate(sizeof(Read)))
|
||||||
@ -854,9 +888,9 @@ insertRead(Context* c, Event* thisEvent, Event* before, Value* v,
|
|||||||
|
|
||||||
// fprintf(stderr, "add read %p to %p\n", r, v);
|
// fprintf(stderr, "add read %p to %p\n", r, v);
|
||||||
|
|
||||||
if (before) {
|
if (previousEvent) {
|
||||||
for (Read** p = &(v->reads); *p;) {
|
for (Read** p = &(v->reads); *p;) {
|
||||||
if ((*p)->event->sequence >= before->sequence) {
|
if ((*p)->event->sequence > previousEvent->sequence) {
|
||||||
r->next = *p;
|
r->next = *p;
|
||||||
*p = r;
|
*p = r;
|
||||||
break;
|
break;
|
||||||
@ -955,6 +989,10 @@ class CallEvent: public Event {
|
|||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
addRead(c, s->value, s->size * BytesPerWord, 0);
|
||||||
|
}
|
||||||
|
|
||||||
addRead(c, address, BytesPerWord,
|
addRead(c, address, BytesPerWord,
|
||||||
(indirection ? registerSite(c, c->assembler->returnLow()) : 0));
|
(indirection ? registerSite(c, c->assembler->returnLow()) : 0));
|
||||||
}
|
}
|
||||||
@ -963,6 +1001,8 @@ class CallEvent: public Event {
|
|||||||
if (DebugCompile) {
|
if (DebugCompile) {
|
||||||
fprintf(stderr, "CallEvent.compile\n");
|
fprintf(stderr, "CallEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pushNow(c, stack);
|
||||||
|
|
||||||
UnaryOperation type = ((flags & Compiler::Aligned) ? AlignedCall : Call);
|
UnaryOperation type = ((flags & Compiler::Aligned) ? AlignedCall : Call);
|
||||||
if (indirection) {
|
if (indirection) {
|
||||||
@ -1432,21 +1472,23 @@ class StackSyncEvent: public Event {
|
|||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
addRead(c, s->value, s->size * BytesPerWord,
|
s->syncSite = stackSyncSite(c, i, s->size);
|
||||||
stackSyncSite(c, i, s->size));
|
addRead(c, s->value, s->size * BytesPerWord, s->syncSite);
|
||||||
i += s->size;
|
i += s->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetStack(c);
|
resetStack(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
StackSyncEvent(Context* c, Event* next):
|
StackSyncEvent(Context* c, Event* previous):
|
||||||
Event(c, next)
|
Event(c, previous)
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
insertRead(c, this, next, s->value, s->size * BytesPerWord,
|
s->syncSite = stackSyncSite(c, i, s->size);
|
||||||
stackSyncSite(c, i, s->size));
|
insertRead(c, this, previous, s->value, s->size * BytesPerWord,
|
||||||
|
s->syncSite);
|
||||||
|
s->pushEvent->active = false;
|
||||||
i += s->size;
|
i += s->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1460,6 +1502,14 @@ class StackSyncEvent: public Event {
|
|||||||
fprintf(stderr, "StackSyncEvent.compile\n");
|
fprintf(stderr, "StackSyncEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
clearSites(c, s->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
addSite(c, 0, 0, s->value, s->syncSite);
|
||||||
|
}
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
nextRead(c, r->value);
|
nextRead(c, r->value);
|
||||||
}
|
}
|
||||||
@ -1664,14 +1714,14 @@ void
|
|||||||
updateJunctions(Context* c)
|
updateJunctions(Context* c)
|
||||||
{
|
{
|
||||||
for (Junction* j = c->junctions; j; j = j->next) {
|
for (Junction* j = c->junctions; j; j = j->next) {
|
||||||
LogicalInstruction* i = c->logicalCode + j->logicalIp;
|
|
||||||
|
|
||||||
for (int ip = j->logicalIp - 1; ip >= 0; --ip) {
|
for (int ip = j->logicalIp - 1; ip >= 0; --ip) {
|
||||||
LogicalInstruction* p = c->logicalCode + ip;
|
LogicalInstruction* p = c->logicalCode + ip;
|
||||||
if (p->lastEvent) {
|
if (p->lastEvent) {
|
||||||
i->lastEvent = i->lastEvent->next
|
// fprintf(stderr, "update junction at %d, predecessor %d\n", j->logicalIp, ip);
|
||||||
|
p->lastEvent = p->lastEvent->next
|
||||||
= new (c->zone->allocate(sizeof(StackSyncEvent)))
|
= new (c->zone->allocate(sizeof(StackSyncEvent)))
|
||||||
StackSyncEvent(c, 0);
|
StackSyncEvent(c, p->lastEvent);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1700,7 +1750,7 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
{
|
{
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and (not c->registers[i].reserved)
|
and c->registers[i].refCount == 0
|
||||||
and (not used(c, i)))
|
and (not used(c, i)))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
@ -1719,7 +1769,7 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
if (allowAcquired) {
|
if (allowAcquired) {
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and (not c->registers[i].reserved))
|
and c->registers[i].refCount == 0)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -1756,15 +1806,15 @@ class Client: public Assembler::Client {
|
|||||||
if (r == NoRegister) {
|
if (r == NoRegister) {
|
||||||
r = freeRegisterExcept(c, NoRegister, false);
|
r = freeRegisterExcept(c, NoRegister, false);
|
||||||
} else {
|
} else {
|
||||||
expect(c, not c->registers[r].reserved);
|
expect(c, c->registers[r].refCount == 0);
|
||||||
expect(c, c->registers[r].value == 0);
|
expect(c, c->registers[r].value == 0);
|
||||||
}
|
}
|
||||||
c->registers[r].reserved = true;
|
increment(c, r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void releaseTemporary(int r) {
|
virtual void releaseTemporary(int r) {
|
||||||
c->registers[r].reserved = false;
|
decrement(c, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context* c;
|
Context* c;
|
||||||
@ -1795,6 +1845,8 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||||
|
// fprintf(stderr, " ++ visit ip: %d visits: %d\n", logicalIp, c.logicalCode[logicalIp].visits + 1);
|
||||||
|
|
||||||
if ((++ c.logicalCode[logicalIp].visits) == 2) {
|
if ((++ c.logicalCode[logicalIp].visits) == 2) {
|
||||||
c.junctions = new (c.zone->allocate(sizeof(Junction)))
|
c.junctions = new (c.zone->allocate(sizeof(Junction)))
|
||||||
Junction(logicalIp, c.junctions);
|
Junction(logicalIp, c.junctions);
|
||||||
|
25
src/x86.cpp
25
src/x86.cpp
@ -837,7 +837,7 @@ andCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
|||||||
if (isInt8(v)) {
|
if (isInt8(v)) {
|
||||||
c->code.append(0x83);
|
c->code.append(0x83);
|
||||||
c->code.append(0xe0 | b->low);
|
c->code.append(0xe0 | b->low);
|
||||||
c->code.append(a->value->value());
|
c->code.append(v);
|
||||||
} else if (isInt32(v)) {
|
} else if (isInt32(v)) {
|
||||||
c->code.append(0x81);
|
c->code.append(0x81);
|
||||||
c->code.append(0xe0 | b->low);
|
c->code.append(0xe0 | b->low);
|
||||||
@ -865,6 +865,27 @@ andCM(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shiftLeftCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||||
|
Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, BytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
|
rex(c);
|
||||||
|
if (v == 1) {
|
||||||
|
c->code.append(0xd1);
|
||||||
|
c->code.append(0xe0 | b->low);
|
||||||
|
} else if (isInt8(v)) {
|
||||||
|
c->code.append(0xc1);
|
||||||
|
c->code.append(0xe0 | b->low);
|
||||||
|
c->code.append(v);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
@ -1018,6 +1039,8 @@ populateTables()
|
|||||||
BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR);
|
BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR);
|
||||||
BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM);
|
BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM);
|
||||||
|
|
||||||
|
BinaryOperations[INDEX2(ShiftLeft, Constant, Register)] = CAST2(shiftLeftCR);
|
||||||
|
|
||||||
BinaryOperations[INDEX2(Subtract, Constant, Register)] = CAST2(subtractCR);
|
BinaryOperations[INDEX2(Subtract, Constant, Register)] = CAST2(subtractCR);
|
||||||
BinaryOperations[INDEX2(Subtract, Register, Register)] = CAST2(subtractRR);
|
BinaryOperations[INDEX2(Subtract, Register, Register)] = CAST2(subtractRR);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user