mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
fix a few bugs revealed by ProGuard optimizations, including too-early constant propagation during array loads and stores
This commit is contained in:
parent
064ba4519a
commit
fc8c5a2ea9
168
src/compile.cpp
168
src/compile.cpp
@ -1834,67 +1834,34 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(&singletonValue(t, aioobThunk(t), 0)));
|
(&singletonValue(t, aioobThunk(t), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->isConstant(index)) {
|
switch (instruction) {
|
||||||
unsigned i = c->constantValue(index);
|
case aaload:
|
||||||
switch (instruction) {
|
frame->pushObject
|
||||||
case aaload:
|
(c->load
|
||||||
frame->pushObject
|
(BytesPerWord, c->memory(array, ArrayBody, index, BytesPerWord)));
|
||||||
(c->load
|
break;
|
||||||
(BytesPerWord, c->memory(array, ArrayBody + (i * BytesPerWord))));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case faload:
|
case faload:
|
||||||
case iaload:
|
case iaload:
|
||||||
frame->pushInt(c->load(4, c->memory(array, ArrayBody + (i * 4))));
|
frame->pushInt(c->load(4, c->memory(array, ArrayBody, index, 4)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case baload:
|
case baload:
|
||||||
frame->pushInt(c->load(1, c->memory(array, ArrayBody + i)));
|
frame->pushInt(c->load(1, c->memory(array, ArrayBody, index, 1)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case caload:
|
case caload:
|
||||||
frame->pushInt(c->loadz(2, c->memory(array, ArrayBody + (i * 2))));
|
frame->pushInt(c->loadz(2, c->memory(array, ArrayBody, index, 2)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case daload:
|
case daload:
|
||||||
case laload:
|
case laload:
|
||||||
frame->pushLong(c->load(8, c->memory(array, ArrayBody + (i * 8))));
|
frame->pushLong(c->load(8, c->memory(array, ArrayBody, index, 8)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case saload:
|
case saload:
|
||||||
frame->pushInt(c->load(2, c->memory(array, ArrayBody + (i * 2))));
|
frame->pushInt(c->load(2, c->memory(array, ArrayBody, index, 2)));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (instruction) {
|
|
||||||
case aaload:
|
|
||||||
frame->pushObject
|
|
||||||
(c->load
|
|
||||||
(BytesPerWord, c->memory(array, ArrayBody, index, BytesPerWord)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case faload:
|
|
||||||
case iaload:
|
|
||||||
frame->pushInt(c->load(4, c->memory(array, ArrayBody, index, 4)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case baload:
|
|
||||||
frame->pushInt(c->load(1, c->memory(array, ArrayBody, index, 1)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case caload:
|
|
||||||
frame->pushInt(c->loadz(2, c->memory(array, ArrayBody, index, 2)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case daload:
|
|
||||||
case laload:
|
|
||||||
frame->pushLong(c->load(8, c->memory(array, ArrayBody, index, 8)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case saload:
|
|
||||||
frame->pushInt(c->load(2, c->memory(array, ArrayBody, index, 2)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1923,72 +1890,37 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(&singletonValue(t, aioobThunk(t), 0)));
|
(&singletonValue(t, aioobThunk(t), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->isConstant(index)) {
|
switch (instruction) {
|
||||||
unsigned i = c->constantValue(index);
|
case aastore: {
|
||||||
switch (instruction) {
|
c->call
|
||||||
case aastore: {
|
(c->constant(getThunk(t, setMaybeNullThunk)),
|
||||||
c->call
|
0,
|
||||||
(c->constant(getThunk(t, setMaybeNullThunk)),
|
frame->trace(0, false),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, false),
|
4, c->thread(), array,
|
||||||
0,
|
c->add(4, c->constant(ArrayBody),
|
||||||
4, c->thread(), array,
|
c->shl(4, c->constant(log(BytesPerWord)), index)),
|
||||||
c->constant(ArrayBody + (i * BytesPerWord)),
|
value);
|
||||||
value);
|
} break;
|
||||||
} break;
|
|
||||||
|
|
||||||
case fastore:
|
case fastore:
|
||||||
case iastore:
|
case iastore:
|
||||||
c->store(4, value, c->memory(array, ArrayBody + (i * 4)));
|
c->store(4, value, c->memory(array, ArrayBody, index, 4));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bastore:
|
case bastore:
|
||||||
c->store(1, value, c->memory(array, ArrayBody + i));
|
c->store(1, value, c->memory(array, ArrayBody, index, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case castore:
|
case castore:
|
||||||
case sastore:
|
case sastore:
|
||||||
c->store(2, value, c->memory(array, ArrayBody + (i * 2)));
|
c->store(2, value, c->memory(array, ArrayBody, index, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dastore:
|
case dastore:
|
||||||
case lastore:
|
case lastore:
|
||||||
c->store(8, value, c->memory(array, ArrayBody + (i * 8)));
|
c->store(8, value, c->memory(array, ArrayBody, index, 8));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (instruction) {
|
|
||||||
case aastore: {
|
|
||||||
c->call
|
|
||||||
(c->constant(getThunk(t, setMaybeNullThunk)),
|
|
||||||
0,
|
|
||||||
frame->trace(0, false),
|
|
||||||
0,
|
|
||||||
4, c->thread(), array,
|
|
||||||
c->add(4, c->constant(ArrayBody),
|
|
||||||
c->shl(4, c->constant(log(BytesPerWord)), index)),
|
|
||||||
value);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case fastore:
|
|
||||||
case iastore:
|
|
||||||
c->store(4, value, c->memory(array, ArrayBody, index, 4));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case bastore:
|
|
||||||
c->store(1, value, c->memory(array, ArrayBody, index, 1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case castore:
|
|
||||||
case sastore:
|
|
||||||
c->store(2, value, c->memory(array, ArrayBody, index, 2));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dastore:
|
|
||||||
case lastore:
|
|
||||||
c->store(8, value, c->memory(array, ArrayBody, index, 8));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1826,7 +1826,7 @@ class MemoryEvent: public Event {
|
|||||||
scale(scale), result(result)
|
scale(scale), result(result)
|
||||||
{
|
{
|
||||||
addRead(c, base, BytesPerWord, anyRegisterSite(c));
|
addRead(c, base, BytesPerWord, anyRegisterSite(c));
|
||||||
if (index) addRead(c, index, BytesPerWord, anyRegisterSite(c));
|
if (index) addRead(c, index, BytesPerWord, registerOrConstantSite(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
@ -1835,9 +1835,26 @@ class MemoryEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int indexRegister;
|
int indexRegister;
|
||||||
|
int displacement = this->displacement;
|
||||||
|
unsigned scale = this->scale;
|
||||||
if (index) {
|
if (index) {
|
||||||
assert(c, index->source->type(c) == RegisterOperand);
|
ConstantSite* constant = 0;
|
||||||
indexRegister = static_cast<RegisterSite*>(index->source)->register_.low;
|
for (Site* s = index->sites; s; s = s->next) {
|
||||||
|
if (s->type(c) == ConstantOperand) {
|
||||||
|
constant = static_cast<ConstantSite*>(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constant) {
|
||||||
|
indexRegister = NoRegister;
|
||||||
|
displacement += (constant->value.value->value() * scale);
|
||||||
|
scale = 1;
|
||||||
|
} else {
|
||||||
|
assert(c, index->source->type(c) == RegisterOperand);
|
||||||
|
indexRegister = static_cast<RegisterSite*>
|
||||||
|
(index->source)->register_.low;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
indexRegister = NoRegister;
|
indexRegister = NoRegister;
|
||||||
}
|
}
|
||||||
@ -1846,7 +1863,7 @@ class MemoryEvent: public Event {
|
|||||||
|
|
||||||
nextRead(c, base);
|
nextRead(c, base);
|
||||||
if (index) {
|
if (index) {
|
||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8 and indexRegister != NoRegister) {
|
||||||
apply(c, Move4To8, 8, index->source, index->source);
|
apply(c, Move4To8, 8, index->source, index->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2641,22 +2658,6 @@ class MyCompiler: public Compiler {
|
|||||||
return value(&c, s, s);
|
return value(&c, s, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isConstant(Operand* a) {
|
|
||||||
for (Site* s = static_cast<Value*>(a)->sites; s; s = s->next) {
|
|
||||||
if (s->type(&c) == ConstantOperand) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int64_t constantValue(Operand* a) {
|
|
||||||
for (Site* s = static_cast<Value*>(a)->sites; s; s = s->next) {
|
|
||||||
if (s->type(&c) == ConstantOperand) {
|
|
||||||
return static_cast<ConstantSite*>(s)->value.value->value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
abort(&c);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Operand* label() {
|
virtual Operand* label() {
|
||||||
return value(&c, ::constantSite(&c, static_cast<Promise*>(0)));
|
return value(&c, ::constantSite(&c, static_cast<Promise*>(0)));
|
||||||
}
|
}
|
||||||
@ -2698,7 +2699,8 @@ class MyCompiler: public Compiler {
|
|||||||
Value* v = value(&c);
|
Value* v = value(&c);
|
||||||
c.state->stack = ::stack(&c, v, 1, c.state->stack);
|
c.state->stack = ::stack(&c, v, 1, c.state->stack);
|
||||||
c.state->stack->pushed = true;
|
c.state->stack->pushed = true;
|
||||||
// v->sites = pushSite(&c, c.state->stack->index);
|
c.state->stack->pushSite
|
||||||
|
= v->sites = pushSite(&c, c.state->stack->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +62,6 @@ class Compiler {
|
|||||||
virtual Operand* base() = 0;
|
virtual Operand* base() = 0;
|
||||||
virtual Operand* thread() = 0;
|
virtual Operand* thread() = 0;
|
||||||
|
|
||||||
virtual bool isConstant(Operand* value) = 0;
|
|
||||||
virtual int64_t constantValue(Operand* value) = 0;
|
|
||||||
|
|
||||||
virtual Operand* label() = 0;
|
virtual Operand* label() = 0;
|
||||||
virtual void mark(Operand* label) = 0;
|
virtual void mark(Operand* label) = 0;
|
||||||
|
|
||||||
|
@ -95,6 +95,13 @@ public class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
{ boolean p = true;
|
||||||
|
int[] array = new int[] { 1, 2 };
|
||||||
|
expect(array[0] == array[p ? 0 : 1]);
|
||||||
|
p = false;
|
||||||
|
expect(array[1] == array[p ? 0 : 1]);
|
||||||
|
}
|
||||||
|
|
||||||
expect(roundUp(156, 2) == 156);
|
expect(roundUp(156, 2) == 156);
|
||||||
|
|
||||||
{ Foo foo = new Foo();
|
{ Foo foo = new Foo();
|
||||||
|
Loading…
Reference in New Issue
Block a user