mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
various bugfixes and tweaks in new compiler, primarily related to duplicating stack operands
This commit is contained in:
parent
6271f878e8
commit
d654c943f3
@ -733,6 +733,10 @@ class Frame {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compiler::Operand* peekLong(unsigned index) {
|
||||||
|
return c->peek(8, index);
|
||||||
|
}
|
||||||
|
|
||||||
Compiler::Operand* popLong() {
|
Compiler::Operand* popLong() {
|
||||||
poppedLong();
|
poppedLong();
|
||||||
return popLongQuiet();
|
return popLongQuiet();
|
||||||
@ -803,10 +807,7 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dup() {
|
void dup() {
|
||||||
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
c->push(BytesPerWord, c->dup(BytesPerWord, c->peek(BytesPerWord, 0)));
|
||||||
|
|
||||||
c->push(BytesPerWord, s0);
|
|
||||||
c->push(BytesPerWord, s0);
|
|
||||||
|
|
||||||
dupped();
|
dupped();
|
||||||
}
|
}
|
||||||
@ -817,7 +818,7 @@ class Frame {
|
|||||||
|
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
|
|
||||||
duppedX1();
|
duppedX1();
|
||||||
}
|
}
|
||||||
@ -830,7 +831,7 @@ class Frame {
|
|||||||
|
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
pushLongQuiet(s1);
|
pushLongQuiet(s1);
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
} else {
|
} else {
|
||||||
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
||||||
Compiler::Operand* s2 = c->pop(BytesPerWord);
|
Compiler::Operand* s2 = c->pop(BytesPerWord);
|
||||||
@ -838,7 +839,7 @@ class Frame {
|
|||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
c->push(BytesPerWord, s2);
|
c->push(BytesPerWord, s2);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
}
|
}
|
||||||
|
|
||||||
duppedX2();
|
duppedX2();
|
||||||
@ -846,18 +847,15 @@ class Frame {
|
|||||||
|
|
||||||
void dup2() {
|
void dup2() {
|
||||||
if (get(sp - 1) == Long) {
|
if (get(sp - 1) == Long) {
|
||||||
Compiler::Operand* s0 = popLongQuiet();
|
pushLongQuiet(c->dup(8, peekLong(0)));
|
||||||
|
|
||||||
pushLongQuiet(s0);
|
|
||||||
pushLongQuiet(s0);
|
|
||||||
} else {
|
} else {
|
||||||
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
||||||
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
||||||
|
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
}
|
}
|
||||||
|
|
||||||
dupped2();
|
dupped2();
|
||||||
@ -870,7 +868,7 @@ class Frame {
|
|||||||
|
|
||||||
pushLongQuiet(s0);
|
pushLongQuiet(s0);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
pushLongQuiet(s0);
|
pushLongQuiet(c->dup(8, s0));
|
||||||
} else {
|
} else {
|
||||||
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
||||||
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
||||||
@ -879,8 +877,8 @@ class Frame {
|
|||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
c->push(BytesPerWord, s2);
|
c->push(BytesPerWord, s2);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
}
|
}
|
||||||
|
|
||||||
dupped2X1();
|
dupped2X1();
|
||||||
@ -895,7 +893,7 @@ class Frame {
|
|||||||
|
|
||||||
pushLongQuiet(s0);
|
pushLongQuiet(s0);
|
||||||
pushLongQuiet(s1);
|
pushLongQuiet(s1);
|
||||||
pushLongQuiet(s0);
|
pushLongQuiet(c->dup(8, s0));
|
||||||
} else {
|
} else {
|
||||||
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
Compiler::Operand* s1 = c->pop(BytesPerWord);
|
||||||
Compiler::Operand* s2 = c->pop(BytesPerWord);
|
Compiler::Operand* s2 = c->pop(BytesPerWord);
|
||||||
@ -903,7 +901,7 @@ class Frame {
|
|||||||
pushLongQuiet(s0);
|
pushLongQuiet(s0);
|
||||||
c->push(BytesPerWord, s2);
|
c->push(BytesPerWord, s2);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, s1);
|
||||||
pushLongQuiet(s0);
|
pushLongQuiet(c->dup(8, s0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
Compiler::Operand* s0 = c->pop(BytesPerWord);
|
||||||
@ -915,8 +913,8 @@ class Frame {
|
|||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, s0);
|
||||||
c->push(BytesPerWord, s3);
|
c->push(BytesPerWord, s3);
|
||||||
c->push(BytesPerWord, s2);
|
c->push(BytesPerWord, s2);
|
||||||
c->push(BytesPerWord, s1);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
|
||||||
c->push(BytesPerWord, s0);
|
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
|
||||||
}
|
}
|
||||||
|
|
||||||
dupped2X2();
|
dupped2X2();
|
||||||
@ -1788,7 +1786,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
Compiler::Operand* instance = c->peek(0);
|
Compiler::Operand* instance = c->peek(BytesPerWord, 0);
|
||||||
|
|
||||||
c->call
|
c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(checkCast)),
|
(c->constant(reinterpret_cast<intptr_t>(checkCast)),
|
||||||
@ -2396,7 +2394,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
frame->trace(0, false),
|
frame->trace(0, false),
|
||||||
BytesPerWord,
|
BytesPerWord,
|
||||||
3, c->thread(), frame->append(target),
|
3, c->thread(), frame->append(target),
|
||||||
c->peek(instance)),
|
c->peek(BytesPerWord, instance)),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
frame->trace(target, true),
|
frame->trace(target, true),
|
||||||
@ -2443,7 +2441,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
|
|
||||||
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
|
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
|
||||||
|
|
||||||
Compiler::Operand* instance = c->peek(parameterFootprint - 1);
|
Compiler::Operand* instance = c->peek
|
||||||
|
(BytesPerWord, parameterFootprint - 1);
|
||||||
|
|
||||||
unsigned rSize = resultSize(t, methodReturnCode(t, target));
|
unsigned rSize = resultSize(t, methodReturnCode(t, target));
|
||||||
|
|
||||||
@ -3463,14 +3462,13 @@ finish(MyThread* t, Context* context)
|
|||||||
Compiler* c = context->compiler;
|
Compiler* c = context->compiler;
|
||||||
|
|
||||||
unsigned codeSize = c->compile();
|
unsigned codeSize = c->compile();
|
||||||
object result = allocateCode(t, codeSize + c->poolSize());
|
object result = allocateCode(t, pad(codeSize) + c->poolSize());
|
||||||
|
PROTECT(t, result);
|
||||||
|
|
||||||
uint8_t* start = reinterpret_cast<uint8_t*>(&singletonValue(t, result, 0));
|
uint8_t* start = reinterpret_cast<uint8_t*>(&singletonValue(t, result, 0));
|
||||||
|
|
||||||
c->writeTo(start);
|
c->writeTo(start);
|
||||||
|
|
||||||
PROTECT(t, result);
|
|
||||||
|
|
||||||
unsigned mapSize = frameMapSizeInWords(t, context->method);
|
unsigned mapSize = frameMapSizeInWords(t, context->method);
|
||||||
|
|
||||||
for (TraceElement* p = context->traceLog; p; p = p->next) {
|
for (TraceElement* p = context->traceLog; p; p = p->next) {
|
||||||
|
472
src/compiler.cpp
472
src/compiler.cpp
@ -22,10 +22,11 @@ class Value {
|
|||||||
public:
|
public:
|
||||||
virtual ~Value() { }
|
virtual ~Value() { }
|
||||||
|
|
||||||
virtual bool equals(Value*) { return false; }
|
virtual OperandType type() = 0;
|
||||||
virtual bool equals(RegisterValue*) { return false; }
|
|
||||||
|
|
||||||
virtual void preserve(Context*) { }
|
virtual bool equals(Value*) { return false; }
|
||||||
|
|
||||||
|
virtual void preserve(Context*, MyOperand*) { }
|
||||||
virtual void acquire(Context*, MyOperand*) { }
|
virtual void acquire(Context*, MyOperand*) { }
|
||||||
virtual void release(Context*, MyOperand*) { }
|
virtual void release(Context*, MyOperand*) { }
|
||||||
|
|
||||||
@ -39,15 +40,24 @@ class Value {
|
|||||||
class MyOperand: public Compiler::Operand {
|
class MyOperand: public Compiler::Operand {
|
||||||
public:
|
public:
|
||||||
MyOperand(Value* value):
|
MyOperand(Value* value):
|
||||||
event(0), value(value), target(0), size(0), index(0), next(0)
|
event(0), value(value), target(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Event* event;
|
Event* event;
|
||||||
Value* value;
|
Value* value;
|
||||||
Value* target;
|
Value* target;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Stack {
|
||||||
|
public:
|
||||||
|
Stack(MyOperand* operand, unsigned size, unsigned index, Stack* next):
|
||||||
|
operand(operand), size(size), index(index), next(next)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
MyOperand* operand;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned index;
|
unsigned index;
|
||||||
MyOperand* next;
|
Stack* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
class State {
|
class State {
|
||||||
@ -57,7 +67,7 @@ class State {
|
|||||||
next(s)
|
next(s)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
MyOperand* stack;
|
Stack* stack;
|
||||||
State* next;
|
State* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -191,7 +201,7 @@ class PoolPromise: public Promise {
|
|||||||
virtual int64_t value() {
|
virtual int64_t value() {
|
||||||
if (resolved()) {
|
if (resolved()) {
|
||||||
return reinterpret_cast<intptr_t>
|
return reinterpret_cast<intptr_t>
|
||||||
(c->machineCode + c->assembler->length() + key);
|
(c->machineCode + pad(c->assembler->length()) + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(c);
|
abort(c);
|
||||||
@ -209,6 +219,8 @@ class CodePromise: public Promise {
|
|||||||
public:
|
public:
|
||||||
CodePromise(Context* c, CodePromise* next): c(c), offset(-1), next(next) { }
|
CodePromise(Context* c, CodePromise* next): c(c), offset(-1), next(next) { }
|
||||||
|
|
||||||
|
CodePromise(Context* c, int offset): c(c), offset(offset), next(0) { }
|
||||||
|
|
||||||
virtual int64_t value() {
|
virtual int64_t value() {
|
||||||
if (resolved()) {
|
if (resolved()) {
|
||||||
return reinterpret_cast<intptr_t>(c->machineCode + offset);
|
return reinterpret_cast<intptr_t>(c->machineCode + offset);
|
||||||
@ -257,6 +269,8 @@ class ConstantValue: public Value {
|
|||||||
public:
|
public:
|
||||||
ConstantValue(Promise* value): value(value) { }
|
ConstantValue(Promise* value): value(value) { }
|
||||||
|
|
||||||
|
virtual OperandType type() { return Constant; }
|
||||||
|
|
||||||
virtual RegisterValue* toRegister(Context* c);
|
virtual RegisterValue* toRegister(Context* c);
|
||||||
|
|
||||||
virtual void asAssemblerOperand(Context*,
|
virtual void asAssemblerOperand(Context*,
|
||||||
@ -287,6 +301,8 @@ class AddressValue: public Value {
|
|||||||
public:
|
public:
|
||||||
AddressValue(Promise* address): address(address) { }
|
AddressValue(Promise* address): address(address) { }
|
||||||
|
|
||||||
|
virtual OperandType type() { return Address; }
|
||||||
|
|
||||||
virtual RegisterValue* toRegister(Context* c);
|
virtual RegisterValue* toRegister(Context* c);
|
||||||
|
|
||||||
virtual void asAssemblerOperand(Context*,
|
virtual void asAssemblerOperand(Context*,
|
||||||
@ -306,35 +322,43 @@ address(Context* c, Promise* address)
|
|||||||
return new (c->zone->allocate(sizeof(AddressValue))) AddressValue(address);
|
return new (c->zone->allocate(sizeof(AddressValue))) AddressValue(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void preserve(Context* c, int reg);
|
void preserve(Context* c, int reg, MyOperand* a);
|
||||||
|
|
||||||
class RegisterValue: public Value {
|
class RegisterValue: public Value {
|
||||||
public:
|
public:
|
||||||
RegisterValue(int low, int high): register_(low, high) { }
|
RegisterValue(int low, int high): register_(low, high) { }
|
||||||
|
|
||||||
virtual bool equals(Value* o) { return o->equals(this); }
|
virtual OperandType type() { return Register; }
|
||||||
|
|
||||||
virtual bool equals(RegisterValue* o) {
|
virtual bool equals(Value* o) {
|
||||||
return o->register_.low == register_.low
|
return this == o or
|
||||||
and o->register_.high == register_.high;
|
(o->type() == Register
|
||||||
|
and static_cast<RegisterValue*>(o)->register_.low == register_.low
|
||||||
|
and static_cast<RegisterValue*>(o)->register_.high == register_.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void preserve(Context* c) {
|
virtual void preserve(Context* c, MyOperand* a) {
|
||||||
::preserve(c, register_.low);
|
::preserve(c, register_.low, a);
|
||||||
if (register_.high >= 0) ::preserve(c, register_.high);
|
if (register_.high >= 0) ::preserve(c, register_.high, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void acquire(Context* c, MyOperand* a) {
|
virtual void acquire(Context* c, MyOperand* a) {
|
||||||
preserve(c);
|
if (a != c->registers[register_.low].operand) {
|
||||||
c->registers[register_.low].operand = a;
|
fprintf(stderr, "%p acquire %d\n", a, register_.low);
|
||||||
if (register_.high >= 0) c->registers[register_.high].operand = a;
|
|
||||||
|
preserve(c, a);
|
||||||
|
c->registers[register_.low].operand = a;
|
||||||
|
if (register_.high >= 0) c->registers[register_.high].operand = a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void release(Context* c, MyOperand* a UNUSED) {
|
virtual void release(Context* c, MyOperand* a UNUSED) {
|
||||||
assert(c, a == c->registers[register_.low].operand);
|
if (a == c->registers[register_.low].operand) {
|
||||||
|
fprintf(stderr, "%p release %d\n", a, register_.low);
|
||||||
|
|
||||||
c->registers[register_.low].operand = 0;
|
c->registers[register_.low].operand = 0;
|
||||||
if (register_.high >= 0) c->registers[register_.high].operand = 0;
|
if (register_.high >= 0) c->registers[register_.high].operand = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual RegisterValue* toRegister(Context*) {
|
virtual RegisterValue* toRegister(Context*) {
|
||||||
@ -366,6 +390,17 @@ class MemoryValue: public Value {
|
|||||||
value(base, offset, index, scale, traceHandler)
|
value(base, offset, index, scale, traceHandler)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual OperandType type() { return Memory; }
|
||||||
|
|
||||||
|
virtual bool equals(Value* o) {
|
||||||
|
return this == o or
|
||||||
|
(o->type() == Memory
|
||||||
|
and static_cast<MemoryValue*>(o)->value.base == value.base
|
||||||
|
and static_cast<MemoryValue*>(o)->value.offset == value.offset
|
||||||
|
and static_cast<MemoryValue*>(o)->value.index == value.index
|
||||||
|
and static_cast<MemoryValue*>(o)->value.scale == value.scale);
|
||||||
|
}
|
||||||
|
|
||||||
virtual RegisterValue* toRegister(Context* c) {
|
virtual RegisterValue* toRegister(Context* c) {
|
||||||
RegisterValue* v = freeRegister(c, BytesPerWord);
|
RegisterValue* v = freeRegister(c, BytesPerWord);
|
||||||
apply(c, Move, BytesPerWord, this, v);
|
apply(c, Move, BytesPerWord, this, v);
|
||||||
@ -458,7 +493,7 @@ class Event {
|
|||||||
virtual void compile(Context* c) = 0;
|
virtual void compile(Context* c) = 0;
|
||||||
|
|
||||||
Event* next;
|
Event* next;
|
||||||
MyOperand* stack;
|
Stack* stack;
|
||||||
CodePromise* promises;
|
CodePromise* promises;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -466,7 +501,10 @@ class ArgumentEvent: public Event {
|
|||||||
public:
|
public:
|
||||||
ArgumentEvent(Context* c, unsigned size, MyOperand* a, unsigned index):
|
ArgumentEvent(Context* c, unsigned size, MyOperand* a, unsigned index):
|
||||||
Event(c), size(size), a(a), index(index)
|
Event(c), size(size), a(a), index(index)
|
||||||
{ }
|
{
|
||||||
|
assert(c, a->event == 0);
|
||||||
|
a->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == a);
|
assert(c, v == a);
|
||||||
@ -475,7 +513,7 @@ class ArgumentEvent: public Event {
|
|||||||
return register_(c, c->assembler->argumentRegister(index));
|
return register_(c, c->assembler->argumentRegister(index));
|
||||||
} else {
|
} else {
|
||||||
return memory(c, c->assembler->base(),
|
return memory(c, c->assembler->base(),
|
||||||
(v->index + c->stackOffset) * BytesPerWord,
|
index + (c->stackOffset * BytesPerWord),
|
||||||
NoRegister, 0, 0);
|
NoRegister, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,8 +525,12 @@ class ArgumentEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "ArgumentEvent.compile\n");
|
||||||
|
|
||||||
|
if (a->target == 0) a->target = target(c, a);
|
||||||
|
|
||||||
a->value->release(c, a);
|
a->value->release(c, a);
|
||||||
a->target->preserve(c);
|
a->target->preserve(c, a);
|
||||||
|
|
||||||
if (not a->target->equals(a->value)) {
|
if (not a->target->equals(a->value)) {
|
||||||
apply(c, Move, size, a->value, a->target);
|
apply(c, Move, size, a->value, a->target);
|
||||||
@ -511,7 +553,12 @@ class ReturnEvent: public Event {
|
|||||||
public:
|
public:
|
||||||
ReturnEvent(Context* c, unsigned size, MyOperand* a):
|
ReturnEvent(Context* c, unsigned size, MyOperand* a):
|
||||||
Event(c), size(size), a(a)
|
Event(c), size(size), a(a)
|
||||||
{ }
|
{
|
||||||
|
if (a) {
|
||||||
|
assert(c, a->event == 0);
|
||||||
|
a->event = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == a);
|
assert(c, v == a);
|
||||||
@ -526,7 +573,11 @@ class ReturnEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "ReturnEvent.compile\n");
|
||||||
|
|
||||||
if (a) {
|
if (a) {
|
||||||
|
if (a->target == 0) a->target = target(c, a);
|
||||||
|
|
||||||
a->value->release(c, a);
|
a->value->release(c, a);
|
||||||
|
|
||||||
if (not a->target->equals(a->value)) {
|
if (not a->target->equals(a->value)) {
|
||||||
@ -536,6 +587,7 @@ class ReturnEvent: public Event {
|
|||||||
|
|
||||||
Assembler::Register base(c->assembler->base());
|
Assembler::Register base(c->assembler->base());
|
||||||
Assembler::Register stack(c->assembler->stack());
|
Assembler::Register stack(c->assembler->stack());
|
||||||
|
|
||||||
c->assembler->apply(Move, BytesPerWord, Register, &base, Register, &stack);
|
c->assembler->apply(Move, BytesPerWord, Register, &base, Register, &stack);
|
||||||
c->assembler->apply(Pop, BytesPerWord, Register, &base);
|
c->assembler->apply(Pop, BytesPerWord, Register, &base);
|
||||||
c->assembler->apply(Return);
|
c->assembler->apply(Return);
|
||||||
@ -553,15 +605,19 @@ appendReturn(Context* c, unsigned size, MyOperand* value)
|
|||||||
|
|
||||||
class SyncForCallEvent: public Event {
|
class SyncForCallEvent: public Event {
|
||||||
public:
|
public:
|
||||||
SyncForCallEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
|
SyncForCallEvent(Context* c, unsigned size, unsigned index, MyOperand* src,
|
||||||
Event(c), size(size), src(src), dst(dst)
|
MyOperand* dst):
|
||||||
{ }
|
Event(c), size(size), index(index), src(src), dst(dst)
|
||||||
|
{
|
||||||
|
assert(c, src->event == 0);
|
||||||
|
src->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == src);
|
assert(c, v == src);
|
||||||
|
|
||||||
return memory(c, c->assembler->base(),
|
return memory(c, c->assembler->base(),
|
||||||
(v->index + c->stackOffset) * BytesPerWord,
|
index + (c->stackOffset * BytesPerWord),
|
||||||
NoRegister, 0, 0);
|
NoRegister, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,43 +628,68 @@ class SyncForCallEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "SyncForCallEvent.compile\n");
|
||||||
|
|
||||||
|
if (src->target == 0) src->target = target(c, src);
|
||||||
|
|
||||||
src->value->release(c, src);
|
src->value->release(c, src);
|
||||||
|
|
||||||
if (not src->target->equals(src->value)) {
|
if (not src->target->equals(src->value)) {
|
||||||
|
if (src->value->type() == Memory and src->target->type() == Memory) {
|
||||||
|
RegisterValue* tmp = freeRegister(c, size);
|
||||||
|
tmp->preserve(c, 0);
|
||||||
|
apply(c, Move, size, src->value, tmp);
|
||||||
|
src->value = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
apply(c, Move, size, src->value, src->target);
|
apply(c, Move, size, src->value, src->target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dst->value = src->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned index;
|
||||||
MyOperand* src;
|
MyOperand* src;
|
||||||
MyOperand* dst;
|
MyOperand* dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendSyncForCall(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
|
appendSyncForCall(Context* c, unsigned size, unsigned index, MyOperand* src,
|
||||||
|
MyOperand* dst)
|
||||||
{
|
{
|
||||||
new (c->zone->allocate(sizeof(SyncForCallEvent)))
|
new (c->zone->allocate(sizeof(SyncForCallEvent)))
|
||||||
SyncForCallEvent(c, size, src, dst);
|
SyncForCallEvent(c, size, index, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SyncForJumpEvent: public Event {
|
class SyncForJumpEvent: public Event {
|
||||||
public:
|
public:
|
||||||
SyncForJumpEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
|
SyncForJumpEvent(Context* c, unsigned size, unsigned index, MyOperand* src,
|
||||||
Event(c), size(size), src(src), dst(dst)
|
MyOperand* dst):
|
||||||
{ }
|
Event(c), size(size), index(index), src(src), dst(dst)
|
||||||
|
{
|
||||||
|
assert(c, src->event == 0);
|
||||||
|
src->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
SyncForJumpEvent(Event* next, unsigned size, MyOperand* src, MyOperand* dst):
|
SyncForJumpEvent(Context* c, Event* next, unsigned size, unsigned index,
|
||||||
Event(next), size(size), src(src), dst(dst)
|
MyOperand* src, MyOperand* dst):
|
||||||
{ }
|
Event(next), size(size), index(index), src(src), dst(dst)
|
||||||
|
{
|
||||||
|
assert(c, src->event == 0);
|
||||||
|
src->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == src);
|
assert(c, v == src);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and v->size == 8) {
|
if (BytesPerWord == 4 and size == 8) {
|
||||||
return register_(c, c->assembler->stackSyncRegister(v->index),
|
return register_
|
||||||
c->assembler->stackSyncRegister(v->index + 4));
|
(c, c->assembler->stackSyncRegister(index / BytesPerWord),
|
||||||
|
c->assembler->stackSyncRegister((index / BytesPerWord) + 1));
|
||||||
} else {
|
} else {
|
||||||
return register_(c, c->assembler->stackSyncRegister(v->index));
|
return register_
|
||||||
|
(c, c->assembler->stackSyncRegister(index / BytesPerWord));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,6 +700,10 @@ class SyncForJumpEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "SyncForJumpEvent.compile\n");
|
||||||
|
|
||||||
|
if (src->target == 0) src->target = target(c, src);
|
||||||
|
|
||||||
src->value->release(c, src);
|
src->value->release(c, src);
|
||||||
src->target->acquire(c, dst);
|
src->target->acquire(c, dst);
|
||||||
|
|
||||||
@ -630,15 +715,17 @@ class SyncForJumpEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned index;
|
||||||
MyOperand* src;
|
MyOperand* src;
|
||||||
MyOperand* dst;
|
MyOperand* dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendSyncForJump(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
|
appendSyncForJump(Context* c, unsigned size, unsigned index, MyOperand* src,
|
||||||
|
MyOperand* dst)
|
||||||
{
|
{
|
||||||
new (c->zone->allocate(sizeof(SyncForJumpEvent)))
|
new (c->zone->allocate(sizeof(SyncForJumpEvent)))
|
||||||
SyncForJumpEvent(c, size, src, dst);
|
SyncForJumpEvent(c, size, index, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CallEvent: public Event {
|
class CallEvent: public Event {
|
||||||
@ -653,7 +740,10 @@ class CallEvent: public Event {
|
|||||||
traceHandler(traceHandler),
|
traceHandler(traceHandler),
|
||||||
result(result),
|
result(result),
|
||||||
stackOffset(stackOffset)
|
stackOffset(stackOffset)
|
||||||
{ }
|
{
|
||||||
|
assert(c, address->event == 0);
|
||||||
|
address->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == address);
|
assert(c, v == address);
|
||||||
@ -672,6 +762,12 @@ class CallEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "CallEvent.compile\n");
|
||||||
|
|
||||||
|
if (indirection and address->target == 0) {
|
||||||
|
address->target = target(c, address);
|
||||||
|
}
|
||||||
|
|
||||||
address->value->release(c, address);
|
address->value->release(c, address);
|
||||||
|
|
||||||
if (result->event) {
|
if (result->event) {
|
||||||
@ -680,12 +776,14 @@ class CallEvent: public Event {
|
|||||||
result->value->acquire(c, result);
|
result->value->acquire(c, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(c, LoadAddress, BytesPerWord, register_(c, c->assembler->stack()),
|
if (stackOffset != c->stackOffset) {
|
||||||
memory(c, c->assembler->base(), stackOffset * BytesPerWord,
|
apply(c, LoadAddress, BytesPerWord, register_(c, c->assembler->stack()),
|
||||||
NoRegister, 0, 0));
|
memory(c, c->assembler->base(), stackOffset * BytesPerWord,
|
||||||
|
NoRegister, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
if (indirection) {
|
if (indirection) {
|
||||||
if (not address->target->equals(address->value)) {
|
if (address->target->equals(address->value)) {
|
||||||
apply(c, Move, BytesPerWord, address->value, address->target);
|
apply(c, Move, BytesPerWord, address->value, address->target);
|
||||||
}
|
}
|
||||||
apply(c, Call, BytesPerWord,
|
apply(c, Call, BytesPerWord,
|
||||||
@ -693,6 +791,12 @@ class CallEvent: public Event {
|
|||||||
} else {
|
} else {
|
||||||
apply(c, Call, BytesPerWord, address->value);
|
apply(c, Call, BytesPerWord, address->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (traceHandler) {
|
||||||
|
traceHandler->handleTrace
|
||||||
|
(new (c->zone->allocate(sizeof(CodePromise)))
|
||||||
|
CodePromise(c, c->assembler->length()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyOperand* address;
|
MyOperand* address;
|
||||||
@ -716,7 +820,7 @@ appendCall(Context* c, MyOperand* address, void* indirection, unsigned flags,
|
|||||||
int
|
int
|
||||||
freeRegister(Context* c)
|
freeRegister(Context* c)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < c->assembler->registerCount(); ++i) {
|
for (int i = c->assembler->registerCount(); i >= 0; --i) {
|
||||||
if ((not c->registers[i].reserved)
|
if ((not c->registers[i].reserved)
|
||||||
and c->registers[i].operand == 0)
|
and c->registers[i].operand == 0)
|
||||||
{
|
{
|
||||||
@ -724,7 +828,7 @@ freeRegister(Context* c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < c->assembler->registerCount(); ++i) {
|
for (int i = c->assembler->registerCount(); i >= 0; --i) {
|
||||||
if (not c->registers[i].reserved) {
|
if (not c->registers[i].reserved) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -748,15 +852,20 @@ class MoveEvent: public Event {
|
|||||||
MoveEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
|
MoveEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
|
||||||
MyOperand* dst):
|
MyOperand* dst):
|
||||||
Event(c), type(type), size(size), src(src), dst(dst)
|
Event(c), type(type), size(size), src(src), dst(dst)
|
||||||
{ }
|
{
|
||||||
|
assert(c, src->event == 0);
|
||||||
|
src->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == src);
|
assert(c, v == src);
|
||||||
|
|
||||||
if (dst->value) {
|
if (dst->value) {
|
||||||
return dst->value;
|
return dst->value;
|
||||||
|
} else if (dst->event) {
|
||||||
|
return dst->event->target(c, dst);
|
||||||
} else {
|
} else {
|
||||||
return v->event->target(c, dst);
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,12 +876,18 @@ class MoveEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "MoveEvent.compile\n");
|
||||||
|
|
||||||
|
if (src->target == 0) src->target = target(c, src);
|
||||||
|
|
||||||
if (src->target == 0) {
|
if (src->target == 0) {
|
||||||
if (dst->value) {
|
src->target = freeRegister(c, size);
|
||||||
src->target = dst->value;
|
} else if (src->value->type() == Memory and src->target->type() == Memory)
|
||||||
} else {
|
{
|
||||||
src->target = freeRegister(c, size);
|
RegisterValue* tmp = freeRegister(c, size);
|
||||||
}
|
tmp->preserve(c, 0);
|
||||||
|
apply(c, Move, size, src->value, tmp);
|
||||||
|
src->value = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
src->value->release(c, src);
|
src->value->release(c, src);
|
||||||
@ -797,11 +912,67 @@ appendMove(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
|
|||||||
MoveEvent(c, type, size, src, dst);
|
MoveEvent(c, type, size, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DupEvent: public Event {
|
||||||
|
public:
|
||||||
|
DupEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
|
||||||
|
Event(c), size(size), src(src), dst(dst)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual Value* target(Context* c, MyOperand*) {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void replace(Context* c, MyOperand*, MyOperand*) {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "DupEvent.compile\n");
|
||||||
|
|
||||||
|
Value* value = src->value;
|
||||||
|
Value* target = dst->value;
|
||||||
|
|
||||||
|
if (target == 0) {
|
||||||
|
if (dst->event) {
|
||||||
|
target = dst->event->target(c, dst);
|
||||||
|
} else {
|
||||||
|
target = freeRegister(c, size);
|
||||||
|
}
|
||||||
|
} else if (value->type() == Memory and target->type() == Memory) {
|
||||||
|
RegisterValue* tmp = freeRegister(c, size);
|
||||||
|
tmp->preserve(c, 0);
|
||||||
|
apply(c, Move, size, value, tmp);
|
||||||
|
value = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
target->acquire(c, dst);
|
||||||
|
|
||||||
|
apply(c, Move, size, value, target);
|
||||||
|
|
||||||
|
dst->value = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
MyOperand* src;
|
||||||
|
MyOperand* dst;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendDup(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
|
||||||
|
{
|
||||||
|
new (c->zone->allocate(sizeof(DupEvent))) DupEvent(c, size, src, dst);
|
||||||
|
}
|
||||||
|
|
||||||
class CompareEvent: public Event {
|
class CompareEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CompareEvent(Context* c, unsigned size, MyOperand* a, MyOperand* b):
|
CompareEvent(Context* c, unsigned size, MyOperand* a, MyOperand* b):
|
||||||
Event(c), size(size), a(a), b(b)
|
Event(c), size(size), a(a), b(b)
|
||||||
{ }
|
{
|
||||||
|
assert(c, a->event == 0);
|
||||||
|
a->event = this;
|
||||||
|
assert(c, b->event == 0);
|
||||||
|
b->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == a or v == b);
|
assert(c, v == a or v == b);
|
||||||
@ -821,6 +992,8 @@ class CompareEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "CompareEvent.compile\n");
|
||||||
|
|
||||||
a->value->release(c, a);
|
a->value->release(c, a);
|
||||||
b->value->release(c, b);
|
b->value->release(c, b);
|
||||||
|
|
||||||
@ -842,7 +1015,10 @@ class BranchEvent: public Event {
|
|||||||
public:
|
public:
|
||||||
BranchEvent(Context* c, UnaryOperation type, MyOperand* address):
|
BranchEvent(Context* c, UnaryOperation type, MyOperand* address):
|
||||||
Event(c), type(type), address(address)
|
Event(c), type(type), address(address)
|
||||||
{ }
|
{
|
||||||
|
assert(c, address->event == 0);
|
||||||
|
address->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == address);
|
assert(c, v == address);
|
||||||
@ -857,6 +1033,8 @@ class BranchEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "BranchEvent.compile\n");
|
||||||
|
|
||||||
address->value->release(c, address);
|
address->value->release(c, address);
|
||||||
|
|
||||||
apply(c, type, BytesPerWord, address->value);
|
apply(c, type, BytesPerWord, address->value);
|
||||||
@ -877,7 +1055,10 @@ class JumpEvent: public Event {
|
|||||||
JumpEvent(Context* c, MyOperand* address):
|
JumpEvent(Context* c, MyOperand* address):
|
||||||
Event(c),
|
Event(c),
|
||||||
address(address)
|
address(address)
|
||||||
{ }
|
{
|
||||||
|
assert(c, address->event == 0);
|
||||||
|
address->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == address);
|
assert(c, v == address);
|
||||||
@ -891,6 +1072,8 @@ class JumpEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "JumpEvent.compile\n");
|
||||||
|
|
||||||
address->value->release(c, address);
|
address->value->release(c, address);
|
||||||
|
|
||||||
apply(c, Jump, BytesPerWord, address->value);
|
apply(c, Jump, BytesPerWord, address->value);
|
||||||
@ -913,12 +1096,17 @@ class CombineEvent: public Event {
|
|||||||
CombineEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* a,
|
CombineEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* a,
|
||||||
MyOperand* b, MyOperand* result):
|
MyOperand* b, MyOperand* result):
|
||||||
Event(c), type(type), size(size), a(a), b(b), result(result)
|
Event(c), type(type), size(size), a(a), b(b), result(result)
|
||||||
{ }
|
{
|
||||||
|
assert(c, a->event == 0);
|
||||||
|
a->event = this;
|
||||||
|
assert(c, b->event == 0);
|
||||||
|
b->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
Assembler::Register ar(NoRegister);
|
Assembler::Register ar(NoRegister);
|
||||||
Assembler::Register br(NoRegister);
|
Assembler::Register br(NoRegister);
|
||||||
c->assembler->getTargets(type, v->size, &ar, &br);
|
c->assembler->getTargets(type, size, &ar, &br);
|
||||||
|
|
||||||
if (v == a) {
|
if (v == a) {
|
||||||
if (ar.low == NoRegister) {
|
if (ar.low == NoRegister) {
|
||||||
@ -930,7 +1118,16 @@ class CombineEvent: public Event {
|
|||||||
assert(c, v == b);
|
assert(c, v == b);
|
||||||
|
|
||||||
if (br.low == NoRegister) {
|
if (br.low == NoRegister) {
|
||||||
return result->event->target(c, result);
|
if (result->event) {
|
||||||
|
Value* v = result->event->target(c, result);
|
||||||
|
if (v->type() == Register) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return register_(c, br.low, br.high);
|
return register_(c, br.low, br.high);
|
||||||
}
|
}
|
||||||
@ -949,6 +1146,11 @@ class CombineEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "CombineEvent.compile\n");
|
||||||
|
|
||||||
|
if (a->target == 0) a->target = target(c, a);
|
||||||
|
if (b->target == 0) b->target = target(c, b);
|
||||||
|
|
||||||
a->value->release(c, a);
|
a->value->release(c, a);
|
||||||
b->value->release(c, b);
|
b->value->release(c, b);
|
||||||
b->value->acquire(c, result);
|
b->value->acquire(c, result);
|
||||||
@ -985,13 +1187,16 @@ class TranslateEvent: public Event {
|
|||||||
TranslateEvent(Context* c, UnaryOperation type, unsigned size, MyOperand* a,
|
TranslateEvent(Context* c, UnaryOperation type, unsigned size, MyOperand* a,
|
||||||
MyOperand* result):
|
MyOperand* result):
|
||||||
Event(c), type(type), size(size), a(a), result(result)
|
Event(c), type(type), size(size), a(a), result(result)
|
||||||
{ }
|
{
|
||||||
|
assert(c, a->event == 0);
|
||||||
|
a->event = this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Value* target(Context* c, MyOperand* v) {
|
virtual Value* target(Context* c, MyOperand* v) {
|
||||||
assert(c, v == a);
|
assert(c, v == a);
|
||||||
|
|
||||||
Assembler::Register r(NoRegister);
|
Assembler::Register r(NoRegister);
|
||||||
c->assembler->getTargets(type, v->size, &r);
|
c->assembler->getTargets(type, size, &r);
|
||||||
|
|
||||||
if (r.low == NoRegister) {
|
if (r.low == NoRegister) {
|
||||||
return result->event->target(c, result);
|
return result->event->target(c, result);
|
||||||
@ -1007,9 +1212,16 @@ class TranslateEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "TranslateEvent.compile\n");
|
||||||
|
|
||||||
|
if (a->target == 0) a->target = target(c, a);
|
||||||
|
|
||||||
result->value->acquire(c, result);
|
result->value->acquire(c, result);
|
||||||
|
|
||||||
apply(c, type, a->size, a->value);
|
if (a->target and not a->target->equals(a->value)) {
|
||||||
|
apply(c, Move, size, a->value, a->target);
|
||||||
|
}
|
||||||
|
apply(c, type, size, a->value);
|
||||||
|
|
||||||
result->value = a->value;
|
result->value = a->value;
|
||||||
}
|
}
|
||||||
@ -1045,18 +1257,21 @@ AddressValue::toRegister(Context* c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
preserve(Context* c, int reg)
|
preserve(Context* c, int reg, MyOperand* a)
|
||||||
{
|
{
|
||||||
MyOperand* a = c->registers[reg].operand;
|
MyOperand* b = c->registers[reg].operand;
|
||||||
if (a) {
|
if (b and a != b) {
|
||||||
MemoryValue* dst = memory
|
fprintf(stderr, "%p preserve %d for %p\n", a, reg, b);
|
||||||
(c, c->assembler->base(), (a->index + c->stackOffset) * BytesPerWord,
|
|
||||||
-1, 0, 0);
|
|
||||||
|
|
||||||
apply(c, Move, a->size, a->value, dst);
|
abort(c);
|
||||||
|
// MemoryValue* dst = memory
|
||||||
|
// (c, c->assembler->base(), (b->index + c->stackOffset) * BytesPerWord,
|
||||||
|
// -1, 0, 0);
|
||||||
|
|
||||||
a->value = dst;
|
// apply(c, Move, b->size, b->value, dst);
|
||||||
c->registers[reg].operand = 0;
|
|
||||||
|
// b->value = dst;
|
||||||
|
// c->registers[reg].operand = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1080,52 +1295,59 @@ popState(Context* c)
|
|||||||
State(c->state->next);
|
State(c->state->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stack*
|
||||||
|
stack(Context* c, MyOperand* operand, unsigned size, unsigned index,
|
||||||
|
Stack* next)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(Stack)))
|
||||||
|
Stack(operand, size, index, next);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
push(Context* c, unsigned size, MyOperand* o)
|
push(Context* c, unsigned size, MyOperand* o)
|
||||||
{
|
{
|
||||||
assert(c, o->size == 0 and o->index == 0);
|
assert(c, ceiling(size, BytesPerWord));
|
||||||
|
assert(c, o->event == 0);
|
||||||
|
|
||||||
o->next = c->state->stack;
|
c->state->stack = stack
|
||||||
o->size = ceiling(size, BytesPerWord);
|
(c, o, ceiling(size, BytesPerWord),
|
||||||
o->index = ceiling(size, BytesPerWord)
|
ceiling(size, BytesPerWord)
|
||||||
+ (c->state->stack ? c->state->stack->index : 0);
|
+ (c->state->stack ? c->state->stack->index : 0),
|
||||||
c->state->stack = o;
|
c->state->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyOperand*
|
MyOperand*
|
||||||
pop(Context* c, unsigned size UNUSED)
|
pop(Context* c, unsigned size UNUSED)
|
||||||
{
|
{
|
||||||
MyOperand* o = c->state->stack;
|
Stack* s = c->state->stack;
|
||||||
assert(c, ceiling(size, BytesPerWord) == o->size);
|
assert(c, ceiling(size, BytesPerWord) == s->size);
|
||||||
|
|
||||||
c->state->stack = o->next;
|
c->state->stack = s->next;
|
||||||
return o;
|
return s->operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
syncStack(Context* c, SyncType type)
|
syncStack(Context* c, SyncType type)
|
||||||
{
|
{
|
||||||
MyOperand* top = 0;
|
Stack* newStack = 0;
|
||||||
MyOperand* new_ = 0;
|
for (Stack* s = c->state->stack; s; s = s->next) {
|
||||||
for (MyOperand* old = c->state->stack; old; old = old->next) {
|
MyOperand* old = s->operand;
|
||||||
MyOperand* n = operand(c);
|
MyOperand* new_ = operand(c);
|
||||||
if (new_) {
|
Stack* ns = stack(c, new_, s->size, s->index, 0);
|
||||||
new_->next = n;
|
if (newStack) {
|
||||||
|
newStack->next = ns;
|
||||||
} else {
|
} else {
|
||||||
top = n;
|
newStack = c->state->stack = ns;
|
||||||
}
|
}
|
||||||
new_ = n;
|
|
||||||
new_->size = old->size;
|
|
||||||
new_->index = old->index;
|
|
||||||
|
|
||||||
if (type == SyncForCall) {
|
if (type == SyncForCall) {
|
||||||
appendSyncForCall(c, old->size * BytesPerWord, old, new_);
|
appendSyncForCall
|
||||||
|
(c, s->size * BytesPerWord, s->index * BytesPerWord, old, new_);
|
||||||
} else {
|
} else {
|
||||||
appendSyncForJump(c, old->size * BytesPerWord, old, new_);
|
appendSyncForJump
|
||||||
|
(c, s->size * BytesPerWord, s->index * BytesPerWord, old, new_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c->state->stack = top;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1137,13 +1359,9 @@ updateJunctions(Context* c)
|
|||||||
if (i->predecessor >= 0) {
|
if (i->predecessor >= 0) {
|
||||||
LogicalInstruction* p = c->logicalCode + i->predecessor;
|
LogicalInstruction* p = c->logicalCode + i->predecessor;
|
||||||
|
|
||||||
MyOperand* new_ = 0;
|
for (Stack* s = c->state->stack; s; s = s->next) {
|
||||||
for (MyOperand* old = i->firstEvent->stack; old; old = old->next) {
|
MyOperand* old = s->operand;
|
||||||
MyOperand* n = operand(c);
|
MyOperand* new_ = operand(c);
|
||||||
if (new_) new_->next = n;
|
|
||||||
new_ = n;
|
|
||||||
new_->size = old->size;
|
|
||||||
new_->index = old->index;
|
|
||||||
|
|
||||||
if (old->event) {
|
if (old->event) {
|
||||||
old->event->replace(c, old, new_);
|
old->event->replace(c, old, new_);
|
||||||
@ -1151,7 +1369,9 @@ updateJunctions(Context* c)
|
|||||||
|
|
||||||
p->lastEvent = p->lastEvent->next = new
|
p->lastEvent = p->lastEvent->next = new
|
||||||
(c->zone->allocate(sizeof(SyncForJumpEvent)))
|
(c->zone->allocate(sizeof(SyncForJumpEvent)))
|
||||||
SyncForJumpEvent(p->lastEvent->next, old->size, old, new_);
|
SyncForJumpEvent
|
||||||
|
(c, p->lastEvent->next, s->size * BytesPerWord,
|
||||||
|
s->index * BytesPerWord, old, new_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1170,7 +1390,6 @@ compile(Context* c)
|
|||||||
for (unsigned i = 0; i < c->logicalCodeLength; ++ i) {
|
for (unsigned i = 0; i < c->logicalCodeLength; ++ i) {
|
||||||
fprintf(stderr, "compile ip %d\n", i);
|
fprintf(stderr, "compile ip %d\n", i);
|
||||||
for (Event* e = c->logicalCode[i].firstEvent; e; e = e->next) {
|
for (Event* e = c->logicalCode[i].firstEvent; e; e = e->next) {
|
||||||
fprintf(stderr, "compile ip %d event\n", i);
|
|
||||||
e->compile(c);
|
e->compile(c);
|
||||||
|
|
||||||
if (e == c->logicalCode[i].lastEvent) break;
|
if (e == c->logicalCode[i].lastEvent) break;
|
||||||
@ -1307,17 +1526,21 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void popped(unsigned count) {
|
virtual void popped(unsigned count) {
|
||||||
for (int i = count; i >= 0;) {
|
for (unsigned i = count; i > 0;) {
|
||||||
MyOperand* o = c.state->stack;
|
Stack* s = c.state->stack;
|
||||||
c.state->stack = o->next;
|
c.state->stack = s->next;
|
||||||
count -= o->size;
|
i -= s->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* peek(unsigned index) {
|
virtual Operand* peek(unsigned size, unsigned index) {
|
||||||
MyOperand* a = c.state->stack;
|
Stack* s = c.state->stack;
|
||||||
for (; index; --index) a = a->next;
|
for (unsigned i = index; i > 0;) {
|
||||||
return a;
|
s = s->next;
|
||||||
|
i -= s->size;
|
||||||
|
}
|
||||||
|
assert(&c, s->size == ceiling(size, BytesPerWord));
|
||||||
|
return s->operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* call(Operand* address,
|
virtual Operand* call(Operand* address,
|
||||||
@ -1347,9 +1570,10 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
syncStack(&c, SyncForCall);
|
syncStack(&c, SyncForCall);
|
||||||
|
|
||||||
unsigned stackOffset = c.stackOffset + c.state->stack->index
|
unsigned stackOffset = c.stackOffset
|
||||||
+ (footprint > c.assembler->argumentRegisterCount() ?
|
+ (c.state->stack ? c.state->stack->index
|
||||||
footprint - c.assembler->argumentRegisterCount() : 0);
|
+ (footprint > c.assembler->argumentRegisterCount() ?
|
||||||
|
footprint - c.assembler->argumentRegisterCount() : 0) : 0);
|
||||||
|
|
||||||
MyOperand* result = operand(&c);
|
MyOperand* result = operand(&c);
|
||||||
appendCall(&c, static_cast<MyOperand*>(address), indirection, flags,
|
appendCall(&c, static_cast<MyOperand*>(address), indirection, flags,
|
||||||
@ -1384,6 +1608,12 @@ class MyCompiler: public Compiler {
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Operand* dup(unsigned size, Operand* src) {
|
||||||
|
MyOperand* dst = operand(&c);
|
||||||
|
appendDup(&c, size, static_cast<MyOperand*>(src), dst);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void cmp(unsigned size, Operand* a, Operand* b) {
|
virtual void cmp(unsigned size, Operand* a, Operand* b) {
|
||||||
appendCompare(&c, size, static_cast<MyOperand*>(a),
|
appendCompare(&c, size, static_cast<MyOperand*>(a),
|
||||||
static_cast<MyOperand*>(b));
|
static_cast<MyOperand*>(b));
|
||||||
@ -1530,7 +1760,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
|
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
|
||||||
*reinterpret_cast<intptr_t*>(dst + c.assembler->length() + (i++))
|
*reinterpret_cast<intptr_t*>(dst + pad(c.assembler->length()) + (i++))
|
||||||
= n->promise->value();
|
= n->promise->value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class Compiler {
|
|||||||
virtual Operand* pop(unsigned size) = 0;
|
virtual Operand* pop(unsigned size) = 0;
|
||||||
virtual void pushed(unsigned count) = 0;
|
virtual void pushed(unsigned count) = 0;
|
||||||
virtual void popped(unsigned count) = 0;
|
virtual void popped(unsigned count) = 0;
|
||||||
virtual Operand* peek(unsigned index) = 0;
|
virtual Operand* peek(unsigned size, unsigned index) = 0;
|
||||||
|
|
||||||
virtual Operand* call(Operand* address,
|
virtual Operand* call(Operand* address,
|
||||||
void* indirection,
|
void* indirection,
|
||||||
@ -64,6 +64,7 @@ class Compiler {
|
|||||||
virtual Operand* load(unsigned size, Operand* src) = 0;
|
virtual Operand* load(unsigned size, Operand* src) = 0;
|
||||||
virtual Operand* loadz(unsigned size, Operand* src) = 0;
|
virtual Operand* loadz(unsigned size, Operand* src) = 0;
|
||||||
virtual Operand* load4To8(Operand* src) = 0;
|
virtual Operand* load4To8(Operand* src) = 0;
|
||||||
|
virtual Operand* dup(unsigned size, Operand* src) = 0;
|
||||||
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual void jl(Operand* address) = 0;
|
virtual void jl(Operand* address) = 0;
|
||||||
virtual void jg(Operand* address) = 0;
|
virtual void jg(Operand* address) = 0;
|
||||||
|
74
src/x86.cpp
74
src/x86.cpp
@ -121,7 +121,7 @@ class Task {
|
|||||||
|
|
||||||
class OffsetTask: public Task {
|
class OffsetTask: public Task {
|
||||||
public:
|
public:
|
||||||
OffsetTask(Task* next, Promise* promise, int instructionOffset,
|
OffsetTask(Task* next, Promise* promise, unsigned instructionOffset,
|
||||||
unsigned instructionSize):
|
unsigned instructionSize):
|
||||||
Task(next),
|
Task(next),
|
||||||
promise(promise),
|
promise(promise),
|
||||||
@ -141,7 +141,7 @@ class OffsetTask: public Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Promise* promise;
|
Promise* promise;
|
||||||
int instructionOffset;
|
unsigned instructionOffset;
|
||||||
unsigned instructionSize;
|
unsigned instructionSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,6 +153,30 @@ appendOffsetTask(Context* c, Promise* promise, int instructionOffset,
|
|||||||
(c->tasks, promise, instructionOffset, instructionSize);
|
(c->tasks, promise, instructionOffset, instructionSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ImmediateTask: public Task {
|
||||||
|
public:
|
||||||
|
ImmediateTask(Task* next, Promise* promise, unsigned offset):
|
||||||
|
Task(next),
|
||||||
|
promise(promise),
|
||||||
|
offset(offset)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void run(Context* c) {
|
||||||
|
intptr_t v = promise->value();
|
||||||
|
memcpy(c->result + offset, &v, BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise* promise;
|
||||||
|
unsigned offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendImmediateTask(Context* c, Promise* promise, unsigned offset)
|
||||||
|
{
|
||||||
|
c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask
|
||||||
|
(c->tasks, promise, offset);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
encode(Context* c, uint8_t* instruction, unsigned length, int a, int b,
|
encode(Context* c, uint8_t* instruction, unsigned length, int a, int b,
|
||||||
int32_t displacement, int index, unsigned scale)
|
int32_t displacement, int index, unsigned scale)
|
||||||
@ -307,6 +331,18 @@ popR(Context* c, unsigned size, Assembler::Register* a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
leaRM(Context* c, unsigned size, Assembler::Register* a, Assembler::Memory* b)
|
||||||
|
{
|
||||||
|
if (BytesPerWord == 8 and size == 4) {
|
||||||
|
encode(c, 0x8d, a->low, b, false);
|
||||||
|
} else {
|
||||||
|
assert(c, BytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
|
encode(c, 0x8d, a->low, b, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
@ -315,7 +351,12 @@ moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
|||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0xb8 | b->low);
|
c->code.append(0xb8 | b->low);
|
||||||
c->code.appendAddress(a->value->value());
|
if (a->value->resolved()) {
|
||||||
|
c->code.appendAddress(a->value->value());
|
||||||
|
} else {
|
||||||
|
appendImmediateTask(c, a->value, c->code.length());
|
||||||
|
c->code.appendAddress(static_cast<uintptr_t>(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -393,6 +434,19 @@ moveMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moveAR(Context* c, unsigned size, Assembler::Address* a,
|
||||||
|
Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, BytesPerWord == 8 or size == 4); // todo
|
||||||
|
|
||||||
|
Assembler::Constant constant(a->address);
|
||||||
|
Assembler::Memory memory(b->low, 0, -1, 0);
|
||||||
|
|
||||||
|
moveCR(c, size, &constant, b);
|
||||||
|
moveMR(c, size, &memory, b);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
|
move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
@ -412,6 +466,15 @@ addRR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addRM(Context* c, unsigned size, Assembler::Register* a,
|
||||||
|
Assembler::Memory* b)
|
||||||
|
{
|
||||||
|
assert(c, BytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
|
encode(c, 0x01, a->low, b, true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
populateTables()
|
populateTables()
|
||||||
{
|
{
|
||||||
@ -422,13 +485,16 @@ populateTables()
|
|||||||
UnaryOperations[INDEX1(Push, Register)] = CAST1(pushR);
|
UnaryOperations[INDEX1(Push, Register)] = CAST1(pushR);
|
||||||
UnaryOperations[INDEX1(Pop, Register)] = CAST1(popR);
|
UnaryOperations[INDEX1(Pop, Register)] = CAST1(popR);
|
||||||
|
|
||||||
|
BinaryOperations[INDEX2(LoadAddress, Register, Memory)] = CAST2(leaRM);
|
||||||
BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
|
BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
|
||||||
BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
|
BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
|
||||||
BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
|
BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
|
||||||
BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
|
BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
|
||||||
BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
|
BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
|
||||||
|
BinaryOperations[INDEX2(Move, Address, Register)] = CAST2(moveAR);
|
||||||
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
|
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
|
||||||
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
|
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
|
||||||
|
BinaryOperations[INDEX2(Add, Register, Memory)] = CAST2(addRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyAssembler: public Assembler {
|
class MyAssembler: public Assembler {
|
||||||
@ -442,7 +508,7 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned registerCount() {
|
virtual unsigned registerCount() {
|
||||||
return BytesPerWord == 4 ? 8 : 16;
|
return 8;//BytesPerWord == 4 ? 8 : 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int base() {
|
virtual int base() {
|
||||||
|
@ -1,67 +1,60 @@
|
|||||||
public class Misc {
|
public class Misc {
|
||||||
// private static int alpha;
|
private static int alpha;
|
||||||
// private static int beta;
|
private static int beta;
|
||||||
// private static byte byte1, byte2, byte3;
|
private static byte byte1, byte2, byte3;
|
||||||
// private int gamma;
|
private int gamma;
|
||||||
|
|
||||||
// private String foo(String s) {
|
private String foo(String s) {
|
||||||
// return s;
|
return s;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public String bar(String s) {
|
public String bar(String s) {
|
||||||
// return s;
|
return s;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// private static String baz(String s) {
|
private static String baz(String s) {
|
||||||
// return s;
|
return s;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// private static void expect(boolean v) {
|
private static void expect(boolean v) {
|
||||||
// if (! v) throw new RuntimeException();
|
if (! v) throw new RuntimeException();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// private synchronized byte sync() {
|
private synchronized byte sync() {
|
||||||
// byte[] array = new byte[123];
|
byte[] array = new byte[123];
|
||||||
// return array[42];
|
return array[42];
|
||||||
// }
|
}
|
||||||
|
|
||||||
// private static synchronized byte syncStatic(boolean throw_) {
|
private static synchronized byte syncStatic(boolean throw_) {
|
||||||
// byte[] array = new byte[123];
|
byte[] array = new byte[123];
|
||||||
// if (throw_) {
|
if (throw_) {
|
||||||
// throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
// } else {
|
} else {
|
||||||
// return array[42];
|
return array[42];
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public static void putInt(int val, byte[] dst, int offset) {
|
public static void putInt(int val, byte[] dst, int offset) {
|
||||||
// System.out.println("put " + val);
|
System.out.println("put " + val);
|
||||||
// dst[offset] = (byte)((val >> 24) & 0xff);
|
dst[offset] = (byte)((val >> 24) & 0xff);
|
||||||
// dst[offset+1] = (byte)((val >> 16) & 0xff);
|
dst[offset+1] = (byte)((val >> 16) & 0xff);
|
||||||
// dst[offset+2] = (byte)((val >> 8) & 0xff);
|
dst[offset+2] = (byte)((val >> 8) & 0xff);
|
||||||
// dst[offset+3] = (byte)((val ) & 0xff);
|
dst[offset+3] = (byte)((val ) & 0xff);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public static void putLong(long val, byte[] dst, int offset) {
|
public static void putLong(long val, byte[] dst, int offset) {
|
||||||
// putInt((int)(val >> 32), dst, offset);
|
putInt((int)(val >> 32), dst, offset);
|
||||||
// putInt((int)val, dst, offset + 4);
|
putInt((int)val, dst, offset + 4);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public String toString() {
|
public String toString() {
|
||||||
// return super.toString();
|
return super.toString();
|
||||||
// }
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int a = 2;
|
|
||||||
int b = 2;
|
|
||||||
int c = a + b;
|
|
||||||
|
|
||||||
// byte2 = 0;
|
// byte2 = 0;
|
||||||
// expect(byte2 == 0);
|
// expect(byte2 == 0);
|
||||||
|
|
||||||
// Misc m = new Misc();
|
|
||||||
// m.toString();
|
|
||||||
|
|
||||||
// expect(Long.valueOf(231L) == 231L);
|
// expect(Long.valueOf(231L) == 231L);
|
||||||
|
|
||||||
// long x = 231;
|
// long x = 231;
|
||||||
@ -97,6 +90,9 @@ public class Misc {
|
|||||||
// int b = 2;
|
// int b = 2;
|
||||||
// int c = a + b;
|
// int c = a + b;
|
||||||
|
|
||||||
|
Misc m = new Misc();
|
||||||
|
// m.toString();
|
||||||
|
|
||||||
// String s = "hello";
|
// String s = "hello";
|
||||||
// m.foo(s);
|
// m.foo(s);
|
||||||
// m.bar(s);
|
// m.bar(s);
|
||||||
|
Loading…
Reference in New Issue
Block a user