mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
fix local variable caching bug
This commit is contained in:
parent
651c4559db
commit
d604efd8f5
118
src/compiler.cpp
118
src/compiler.cpp
@ -94,11 +94,12 @@ class State {
|
|||||||
class Local {
|
class Local {
|
||||||
public:
|
public:
|
||||||
Local(unsigned size, unsigned index, Value* value, Site* site, Local* next):
|
Local(unsigned size, unsigned index, Value* value, Site* site, Local* next):
|
||||||
size(size), index(index), value(value), site(site), next(next)
|
size(size), index(index), reuse(true), value(value), site(site), next(next)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned index;
|
unsigned index;
|
||||||
|
bool reuse;
|
||||||
Value* value;
|
Value* value;
|
||||||
Site* site;
|
Site* site;
|
||||||
Local* next;
|
Local* next;
|
||||||
@ -1304,11 +1305,7 @@ void
|
|||||||
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
||||||
{
|
{
|
||||||
for (Local* l = locals; l; l = l->next) {
|
for (Local* l = locals; l; l = l->next) {
|
||||||
clearSites(c, l->value);
|
l->reuse = false;
|
||||||
}
|
|
||||||
|
|
||||||
for (Local* l = locals; l; l = l->next) {
|
|
||||||
addSite(c, 0, l->size * BytesPerWord, l->value, l->site);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
@ -2087,49 +2084,96 @@ appendPop(Context* c, unsigned count, bool ignore)
|
|||||||
new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore);
|
new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClobberLocalEvent: public Event {
|
||||||
|
public:
|
||||||
|
ClobberLocalEvent(Context* c, unsigned size, Local* local):
|
||||||
|
Event(c), size(size), local(local)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
if (DebugCompile) {
|
||||||
|
fprintf(stderr, "ClobberLocalEvent.compile\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* v = local->value;
|
||||||
|
Site* s = local->site;
|
||||||
|
if (v->reads
|
||||||
|
and v->sites->next == 0
|
||||||
|
and v->sites == s)
|
||||||
|
{
|
||||||
|
preserve(c, stack, size, v, s, v->reads);
|
||||||
|
}
|
||||||
|
removeSite(c, v, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
Local* local;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendClobberLocal(Context* c, unsigned size, Local* local)
|
||||||
|
{
|
||||||
|
if (DebugAppend) {
|
||||||
|
fprintf(stderr, "appendClobberLocal\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
new (c->zone->allocate(sizeof(ClobberLocalEvent)))
|
||||||
|
ClobberLocalEvent(c, size, local);
|
||||||
|
}
|
||||||
|
|
||||||
class LocalEvent: public Event {
|
class LocalEvent: public Event {
|
||||||
public:
|
public:
|
||||||
LocalEvent(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
LocalEvent(Context* c, unsigned size, Local* oldLocal, Local* newLocal):
|
||||||
Site* site):
|
Event(c), size(size), oldLocal(oldLocal), newLocal(newLocal)
|
||||||
Event(c), size(size), newValue(newValue), oldValue(oldValue), site(site)
|
{
|
||||||
{ }
|
if (oldLocal) {
|
||||||
|
addRead(c, oldLocal->value, size, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
if (DebugCompile) {
|
if (DebugCompile) {
|
||||||
fprintf(stderr, "LocalEvent.compile\n");
|
fprintf(stderr, "LocalEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldValue) {
|
Site* sites = 0;
|
||||||
if (oldValue->reads
|
if (oldLocal) {
|
||||||
and oldValue->sites->next == 0
|
Value* v = oldLocal->value;
|
||||||
and oldValue->sites == site)
|
if (oldLocal->reuse and v->reads->next == 0) {
|
||||||
{
|
sites = v->sites;
|
||||||
preserve(c, stack, size, oldValue, site, oldValue->reads);
|
|
||||||
}
|
}
|
||||||
removeSite(c, oldValue, site);
|
|
||||||
|
nextRead(c, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue->reads) {
|
Value* v = newLocal->value;
|
||||||
addSite(c, 0, size, newValue, site);
|
if (v->reads) {
|
||||||
|
for (Site* s = sites; s;) {
|
||||||
|
Site* t = s->next;
|
||||||
|
if (s->type(c) != MemoryOperand) {
|
||||||
|
addSite(c, stack, size, v, s);
|
||||||
|
}
|
||||||
|
s = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
addSite(c, 0, size, v, newLocal->site);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
Value* newValue;
|
Local* oldLocal;
|
||||||
Value* oldValue;
|
Local* newLocal;
|
||||||
Site* site;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendLocal(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
appendLocal(Context* c, unsigned size, Local* oldLocal, Local* newLocal)
|
||||||
Site* site)
|
|
||||||
{
|
{
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
fprintf(stderr, "appendLocal\n");
|
fprintf(stderr, "appendLocal\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(LocalEvent)))
|
new (c->zone->allocate(sizeof(LocalEvent)))
|
||||||
LocalEvent(c, size, newValue, oldValue, site);
|
LocalEvent(c, size, oldLocal, newLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
@ -2291,23 +2335,19 @@ push(Context* c, unsigned size, Value* v)
|
|||||||
void
|
void
|
||||||
addLocal(Context* c, unsigned size, unsigned index, Value* newValue)
|
addLocal(Context* c, unsigned size, unsigned index, Value* newValue)
|
||||||
{
|
{
|
||||||
Value* oldValue;
|
|
||||||
unsigned s = ceiling(size, BytesPerWord);
|
unsigned s = ceiling(size, BytesPerWord);
|
||||||
Local* local = c->localTable[index];
|
Local* local = c->localTable[index];
|
||||||
if (local) {
|
if (local) {
|
||||||
oldValue = local->value;
|
|
||||||
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||||
Local(s, index, newValue, local->site, c->locals);
|
Local(s, index, newValue, local->site, c->locals);
|
||||||
} else {
|
} else {
|
||||||
oldValue = 0;
|
|
||||||
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||||
Local(s, index, newValue, memorySite
|
Local(s, index, newValue, memorySite
|
||||||
(c, c->assembler->base(), localOffset(c, index)),
|
(c, c->assembler->base(), localOffset(c, index)),
|
||||||
c->locals);
|
c->locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendLocal(c, s * BytesPerWord, newValue, oldValue,
|
appendLocal(c, s * BytesPerWord, local, c->locals);
|
||||||
c->localTable[index]->site);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
@ -2654,16 +2694,24 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
virtual void storeLocal(unsigned size, Operand* src, unsigned index) {
|
virtual void storeLocal(unsigned size, Operand* src, unsigned index) {
|
||||||
assert(&c, index < c.localFootprint);
|
assert(&c, index < c.localFootprint);
|
||||||
addLocal(&c, size, index, value(&c));
|
|
||||||
|
if (c.localTable[index]) {
|
||||||
|
appendClobberLocal(&c, size, c.localTable[index]);
|
||||||
|
c.localTable[index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
store(size, src, memory(base(), localOffset(&c, index)));
|
store(size, src, memory(base(), localOffset(&c, index)));
|
||||||
|
|
||||||
|
// todo: find out why this doesn't work and fix it:
|
||||||
|
// addLocal(&c, size, index, static_cast<Value*>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* loadLocal(unsigned size, unsigned index) {
|
virtual Operand* loadLocal(unsigned size, unsigned index) {
|
||||||
assert(&c, index < c.localFootprint);
|
assert(&c, index < c.localFootprint);
|
||||||
if (c.localTable[index] == 0) {
|
|
||||||
addLocal(&c, size, index, value(&c));
|
Value* v = value(&c);
|
||||||
}
|
addLocal(&c, size, index, v);
|
||||||
return c.localTable[index]->value;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void store(unsigned size, Operand* src, Operand* dst) {
|
virtual void store(unsigned size, Operand* src, Operand* dst) {
|
||||||
|
@ -78,7 +78,22 @@ public class Misc {
|
|||||||
return zap() + 5;
|
return zap() + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Foo {
|
||||||
|
public int a;
|
||||||
|
public int b;
|
||||||
|
public int c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int bar(int a, int b, int c) {
|
||||||
|
return a + b + c;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
{ Foo foo = new Foo();
|
||||||
|
int x = foo.a + foo.b + foo.c;
|
||||||
|
bar(foo.a, foo.b, foo.c);
|
||||||
|
}
|
||||||
|
|
||||||
{ int get_buffer = 2144642881;
|
{ int get_buffer = 2144642881;
|
||||||
int bits_left = 30;
|
int bits_left = 30;
|
||||||
int l = 9;
|
int l = 9;
|
||||||
@ -254,9 +269,35 @@ public class Misc {
|
|||||||
expect(exception != null);
|
expect(exception != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ int[] array = new int[3];
|
||||||
|
int i = 0;
|
||||||
|
array[i++] = 1;
|
||||||
|
array[i++] = 2;
|
||||||
|
array[i++] = 3;
|
||||||
|
|
||||||
|
expect(array[--i] == 3);
|
||||||
|
expect(array[--i] == 2);
|
||||||
|
expect(array[--i] == 1);
|
||||||
|
}
|
||||||
|
|
||||||
{ Object[][] array = new Object[1][1];
|
{ Object[][] array = new Object[1][1];
|
||||||
expect(array.length == 1);
|
expect(array.length == 1);
|
||||||
expect(array[0].length == 1);
|
expect(array[0].length == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Object a = new Object();
|
||||||
|
Object b = new Object();
|
||||||
|
expect(a != b);
|
||||||
|
|
||||||
|
Object c = a;
|
||||||
|
Object d = b;
|
||||||
|
expect(c != d);
|
||||||
|
|
||||||
|
c = (c == a) ? b : a;
|
||||||
|
d = (d == a) ? b : a;
|
||||||
|
|
||||||
|
expect(c != d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user