mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +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 {
|
||||
public:
|
||||
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 index;
|
||||
bool reuse;
|
||||
Value* value;
|
||||
Site* site;
|
||||
Local* next;
|
||||
@ -1304,11 +1305,7 @@ void
|
||||
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
||||
{
|
||||
for (Local* l = locals; l; l = l->next) {
|
||||
clearSites(c, l->value);
|
||||
}
|
||||
|
||||
for (Local* l = locals; l; l = l->next) {
|
||||
addSite(c, 0, l->size * BytesPerWord, l->value, l->site);
|
||||
l->reuse = false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
public:
|
||||
LocalEvent(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
||||
Site* site):
|
||||
Event(c), size(size), newValue(newValue), oldValue(oldValue), site(site)
|
||||
{ }
|
||||
LocalEvent(Context* c, unsigned size, Local* oldLocal, Local* newLocal):
|
||||
Event(c), size(size), oldLocal(oldLocal), newLocal(newLocal)
|
||||
{
|
||||
if (oldLocal) {
|
||||
addRead(c, oldLocal->value, size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
if (DebugCompile) {
|
||||
fprintf(stderr, "LocalEvent.compile\n");
|
||||
}
|
||||
|
||||
if (oldValue) {
|
||||
if (oldValue->reads
|
||||
and oldValue->sites->next == 0
|
||||
and oldValue->sites == site)
|
||||
{
|
||||
preserve(c, stack, size, oldValue, site, oldValue->reads);
|
||||
Site* sites = 0;
|
||||
if (oldLocal) {
|
||||
Value* v = oldLocal->value;
|
||||
if (oldLocal->reuse and v->reads->next == 0) {
|
||||
sites = v->sites;
|
||||
}
|
||||
removeSite(c, oldValue, site);
|
||||
|
||||
nextRead(c, v);
|
||||
}
|
||||
|
||||
if (newValue->reads) {
|
||||
addSite(c, 0, size, newValue, site);
|
||||
Value* v = newLocal->value;
|
||||
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;
|
||||
Value* newValue;
|
||||
Value* oldValue;
|
||||
Site* site;
|
||||
Local* oldLocal;
|
||||
Local* newLocal;
|
||||
};
|
||||
|
||||
void
|
||||
appendLocal(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
||||
Site* site)
|
||||
appendLocal(Context* c, unsigned size, Local* oldLocal, Local* newLocal)
|
||||
{
|
||||
if (DebugAppend) {
|
||||
fprintf(stderr, "appendLocal\n");
|
||||
}
|
||||
|
||||
new (c->zone->allocate(sizeof(LocalEvent)))
|
||||
LocalEvent(c, size, newValue, oldValue, site);
|
||||
LocalEvent(c, size, oldLocal, newLocal);
|
||||
}
|
||||
|
||||
Site*
|
||||
@ -2291,23 +2335,19 @@ push(Context* c, unsigned size, Value* v)
|
||||
void
|
||||
addLocal(Context* c, unsigned size, unsigned index, Value* newValue)
|
||||
{
|
||||
Value* oldValue;
|
||||
unsigned s = ceiling(size, BytesPerWord);
|
||||
Local* local = c->localTable[index];
|
||||
if (local) {
|
||||
oldValue = local->value;
|
||||
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||
Local(s, index, newValue, local->site, c->locals);
|
||||
} else {
|
||||
oldValue = 0;
|
||||
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||
Local(s, index, newValue, memorySite
|
||||
(c, c->assembler->base(), localOffset(c, index)),
|
||||
c->locals);
|
||||
}
|
||||
|
||||
appendLocal(c, s * BytesPerWord, newValue, oldValue,
|
||||
c->localTable[index]->site);
|
||||
appendLocal(c, s * BytesPerWord, local, c->locals);
|
||||
}
|
||||
|
||||
Value*
|
||||
@ -2654,16 +2694,24 @@ class MyCompiler: public Compiler {
|
||||
|
||||
virtual void storeLocal(unsigned size, Operand* src, unsigned index) {
|
||||
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)));
|
||||
|
||||
// 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) {
|
||||
assert(&c, index < c.localFootprint);
|
||||
if (c.localTable[index] == 0) {
|
||||
addLocal(&c, size, index, value(&c));
|
||||
}
|
||||
return c.localTable[index]->value;
|
||||
|
||||
Value* v = value(&c);
|
||||
addLocal(&c, size, index, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
virtual void store(unsigned size, Operand* src, Operand* dst) {
|
||||
|
@ -78,7 +78,22 @@ public class Misc {
|
||||
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) {
|
||||
{ Foo foo = new Foo();
|
||||
int x = foo.a + foo.b + foo.c;
|
||||
bar(foo.a, foo.b, foo.c);
|
||||
}
|
||||
|
||||
{ int get_buffer = 2144642881;
|
||||
int bits_left = 30;
|
||||
int l = 9;
|
||||
@ -254,9 +269,35 @@ public class Misc {
|
||||
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];
|
||||
expect(array.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