mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
JIT progress: new, invokespecial, etc.
This commit is contained in:
parent
396c979de8
commit
d70e3aaefb
@ -18,6 +18,8 @@ vmJump(void* address, void* base, void* stack);
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const bool Verbose = true;
|
||||||
|
|
||||||
class MyThread: public Thread {
|
class MyThread: public Thread {
|
||||||
public:
|
public:
|
||||||
class CallTrace {
|
class CallTrace {
|
||||||
@ -351,7 +353,7 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned traceSizeInBytes(Thread* t, object method) {
|
static unsigned traceSizeInBytes(Thread* t, object method) {
|
||||||
return BytesPerWord + BytesPerWord + 1 + mapSizeInWords(t, method);
|
return sizeof(TraceElement) + mapSizeInWords(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushedInt() {
|
void pushedInt() {
|
||||||
@ -655,21 +657,26 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadInt(unsigned index) {
|
void loadInt(unsigned index) {
|
||||||
assert(t, index < localSize(t, method));
|
assert(t, index < codeMaxLocals(t, methodCode(t, method)));
|
||||||
assert(t, getBit(map, index) == 0);
|
assert(t, index < parameterFootprint(t, method)
|
||||||
|
or getBit(map, index - parameterFootprint(t, method)) == 0);
|
||||||
pushInt(c->memory(c->base(), localOffset(t, index, method)));
|
pushInt(c->memory(c->base(), localOffset(t, index, method)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadLong(unsigned index) {
|
void loadLong(unsigned index) {
|
||||||
assert(t, index < localSize(t, method) - 1);
|
assert(t, index < static_cast<unsigned>
|
||||||
assert(t, getBit(map, index) == 0);
|
(codeMaxLocals(t, methodCode(t, method)) - 1));
|
||||||
assert(t, getBit(map, index + 1) == 0);
|
assert(t, index < parameterFootprint(t, method)
|
||||||
|
or getBit(map, index - parameterFootprint(t, method)) == 0);
|
||||||
|
assert(t, index < parameterFootprint(t, method)
|
||||||
|
or getBit(map, index + 1 - parameterFootprint(t, method)) == 0);
|
||||||
pushLong(c->memory(c->base(), localOffset(t, index, method)));
|
pushLong(c->memory(c->base(), localOffset(t, index, method)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadObject(unsigned index) {
|
void loadObject(unsigned index) {
|
||||||
assert(t, index < localSize(t, method));
|
assert(t, index < codeMaxLocals(t, methodCode(t, method)));
|
||||||
assert(t, getBit(map, index) != 0);
|
assert(t, index < parameterFootprint(t, method)
|
||||||
|
or getBit(map, index - parameterFootprint(t, method)) != 0);
|
||||||
pushObject(c->memory(c->base(), localOffset(t, index, method)));
|
pushObject(c->memory(c->base(), localOffset(t, index, method)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2733,7 +2740,7 @@ object
|
|||||||
finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||||
Vector* traceLog)
|
Vector* traceLog)
|
||||||
{
|
{
|
||||||
unsigned count = ceiling(c->size(), BytesPerWord);
|
unsigned count = ceiling(c->codeSize() + c->poolSize(), BytesPerWord);
|
||||||
unsigned size = count + singletonMaskSize(count);
|
unsigned size = count + singletonMaskSize(count);
|
||||||
object result = allocate2
|
object result = allocate2
|
||||||
(t, SingletonBody + size * BytesPerWord, true, true);
|
(t, SingletonBody + size * BytesPerWord, true, true);
|
||||||
@ -2828,6 +2835,14 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
|||||||
set(t, code, CodeLineNumberTable, newTable);
|
set(t, code, CodeLineNumberTable, newTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Verbose) {
|
||||||
|
fprintf(stderr, "%s.%s from %p to %p\n",
|
||||||
|
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||||
|
&byteArrayBody(t, methodName(t, method), 0),
|
||||||
|
start,
|
||||||
|
start + c->codeSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -3638,7 +3653,7 @@ processor(MyThread* t)
|
|||||||
c->jmp(c->indirectTarget());
|
c->jmp(c->indirectTarget());
|
||||||
|
|
||||||
p->indirectCaller = static_cast<uint8_t*>
|
p->indirectCaller = static_cast<uint8_t*>
|
||||||
(t->m->system->allocate(c->size()));
|
(t->m->system->allocate(c->codeSize()));
|
||||||
c->writeTo(p->indirectCaller);
|
c->writeTo(p->indirectCaller);
|
||||||
|
|
||||||
c->dispose();
|
c->dispose();
|
||||||
@ -3665,6 +3680,11 @@ compile(MyThread* t, object method)
|
|||||||
object compiled = compile(t, c, method);
|
object compiled = compile(t, c, method);
|
||||||
set(t, method, MethodCompiled, compiled);
|
set(t, method, MethodCompiled, compiled);
|
||||||
|
|
||||||
|
if (methodVirtual(t, method)) {
|
||||||
|
classVtable(t, methodClass(t, method), methodOffset(t, method))
|
||||||
|
= &singletonValue(t, compiled, 0);
|
||||||
|
}
|
||||||
|
|
||||||
c->dispose();
|
c->dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
250
src/compiler.cpp
250
src/compiler.cpp
@ -29,6 +29,7 @@ const unsigned RegisterCount = BytesPerWord * 2;
|
|||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
class ImmediateOperand;
|
class ImmediateOperand;
|
||||||
|
class AbsoluteOperand;
|
||||||
class RegisterOperand;
|
class RegisterOperand;
|
||||||
class MemoryOperand;
|
class MemoryOperand;
|
||||||
class StackOperand;
|
class StackOperand;
|
||||||
@ -53,12 +54,21 @@ isInt32(intptr_t v)
|
|||||||
|
|
||||||
class IpTask {
|
class IpTask {
|
||||||
public:
|
public:
|
||||||
|
enum Priority {
|
||||||
|
LowPriority,
|
||||||
|
HighPriority
|
||||||
|
};
|
||||||
|
|
||||||
IpTask(IpTask* next): next(next) { }
|
IpTask(IpTask* next): next(next) { }
|
||||||
|
|
||||||
virtual ~IpTask() { }
|
virtual ~IpTask() { }
|
||||||
|
|
||||||
virtual void run(Context* c, unsigned ip, unsigned start, unsigned end,
|
virtual void run(Context* c, unsigned ip, unsigned start, unsigned end,
|
||||||
uint8_t* code, unsigned offset) = 0;
|
uint8_t* code, unsigned offset) = 0;
|
||||||
|
|
||||||
|
virtual Priority priority() {
|
||||||
|
return LowPriority;
|
||||||
|
}
|
||||||
|
|
||||||
IpTask* next;
|
IpTask* next;
|
||||||
};
|
};
|
||||||
@ -86,6 +96,10 @@ class MyPromise: public Promise {
|
|||||||
public:
|
public:
|
||||||
MyPromise(intptr_t key): key(key) { }
|
MyPromise(intptr_t key): key(key) { }
|
||||||
|
|
||||||
|
virtual unsigned value(Compiler*);
|
||||||
|
|
||||||
|
virtual unsigned value(Context*) = 0;
|
||||||
|
|
||||||
intptr_t key;
|
intptr_t key;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,14 +107,14 @@ class PoolPromise: public MyPromise {
|
|||||||
public:
|
public:
|
||||||
PoolPromise(intptr_t key): MyPromise(key) { }
|
PoolPromise(intptr_t key): MyPromise(key) { }
|
||||||
|
|
||||||
virtual unsigned value(Compiler*);
|
virtual unsigned value(Context*);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodePromise: public MyPromise {
|
class CodePromise: public MyPromise {
|
||||||
public:
|
public:
|
||||||
CodePromise(intptr_t key): MyPromise(key) { }
|
CodePromise(intptr_t key): MyPromise(key) { }
|
||||||
|
|
||||||
virtual unsigned value(Compiler*);
|
virtual unsigned value(Context*);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodePromiseTask: public IpTask {
|
class CodePromiseTask: public IpTask {
|
||||||
@ -113,6 +127,10 @@ class CodePromiseTask: public IpTask {
|
|||||||
p->key = offset + (p->key - start);
|
p->key = offset + (p->key - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Priority priority() {
|
||||||
|
return HighPriority;
|
||||||
|
}
|
||||||
|
|
||||||
CodePromise* p;
|
CodePromise* p;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +138,7 @@ class IpPromise: public MyPromise {
|
|||||||
public:
|
public:
|
||||||
IpPromise(intptr_t key): MyPromise(key) { }
|
IpPromise(intptr_t key): MyPromise(key) { }
|
||||||
|
|
||||||
virtual unsigned value(Compiler*);
|
virtual unsigned value(Context*);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyOperand: public Operand {
|
class MyOperand: public Operand {
|
||||||
@ -178,6 +196,8 @@ class MyOperand: public Operand {
|
|||||||
|
|
||||||
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); }
|
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); }
|
||||||
|
|
||||||
|
virtual void accept(Context* c, Operation, AbsoluteOperand*) { abort(c); }
|
||||||
|
|
||||||
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
|
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,6 +207,8 @@ class RegisterOperand: public MyOperand {
|
|||||||
value(value), reserved(false), stack(0)
|
value(value), reserved(false), stack(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual StackOperand* logicalPush(Context* c);
|
||||||
|
|
||||||
virtual void logicalFlush(Context* c UNUSED, StackOperand* s UNUSED) {
|
virtual void logicalFlush(Context* c UNUSED, StackOperand* s UNUSED) {
|
||||||
assert(c, stack == s);
|
assert(c, stack == s);
|
||||||
stack = 0;
|
stack = 0;
|
||||||
@ -209,6 +231,7 @@ class RegisterOperand: public MyOperand {
|
|||||||
|
|
||||||
virtual void accept(Context*, Operation, RegisterOperand*);
|
virtual void accept(Context*, Operation, RegisterOperand*);
|
||||||
virtual void accept(Context*, Operation, ImmediateOperand*);
|
virtual void accept(Context*, Operation, ImmediateOperand*);
|
||||||
|
virtual void accept(Context*, Operation, AbsoluteOperand*);
|
||||||
virtual void accept(Context*, Operation, MemoryOperand*);
|
virtual void accept(Context*, Operation, MemoryOperand*);
|
||||||
|
|
||||||
Register value;
|
Register value;
|
||||||
@ -241,6 +264,10 @@ class AbsoluteOperand: public MyOperand {
|
|||||||
|
|
||||||
virtual void apply(Context* c, Operation operation);
|
virtual void apply(Context* c, Operation operation);
|
||||||
|
|
||||||
|
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||||
|
operand->accept(c, operation, this);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setAbsolute(Context*, intptr_t v) {
|
virtual void setAbsolute(Context*, intptr_t v) {
|
||||||
value->key = v;
|
value->key = v;
|
||||||
}
|
}
|
||||||
@ -313,6 +340,10 @@ class StackOperand: public MyOperand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual StackOperand* logicalPush(Context* c) {
|
||||||
|
return base->logicalPush(c);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void accept(Context* c, Operation operation,
|
virtual void accept(Context* c, Operation operation,
|
||||||
RegisterOperand* operand)
|
RegisterOperand* operand)
|
||||||
{
|
{
|
||||||
@ -626,6 +657,24 @@ encode(Context* c, uint8_t instruction, uint8_t zeroPrefix,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackOperand*
|
||||||
|
RegisterOperand::logicalPush(Context* c)
|
||||||
|
{
|
||||||
|
if (reserved or stack) {
|
||||||
|
RegisterOperand* tmp = temporary(c, false);
|
||||||
|
tmp->accept(c, mov, this);
|
||||||
|
c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
||||||
|
StackOperand(tmp, c->stack);
|
||||||
|
tmp->stack = c->stack;
|
||||||
|
} else {
|
||||||
|
c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
||||||
|
StackOperand(this, c->stack);
|
||||||
|
stack = c->stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c->stack;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RegisterOperand::apply(Context* c, Operation operation)
|
RegisterOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
@ -680,13 +729,21 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
ImmediateOperand* operand)
|
ImmediateOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case sub:
|
case mov:
|
||||||
assert(c, isInt8(operand->value)); // todo
|
|
||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0x83);
|
c->code.append(0xb8 | value);
|
||||||
c->code.append(0xe8 | value);
|
c->code.appendAddress(operand->value);
|
||||||
c->code.append(operand->value);
|
break;
|
||||||
|
|
||||||
|
case sub:
|
||||||
|
if (operand->value) {
|
||||||
|
assert(c, isInt8(operand->value)); // todo
|
||||||
|
|
||||||
|
rex(c);
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xe8 | value);
|
||||||
|
c->code.append(operand->value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -708,6 +765,42 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AbsoluteMovTask: public IpTask {
|
||||||
|
public:
|
||||||
|
AbsoluteMovTask(unsigned start, MyPromise* promise, IpTask* next):
|
||||||
|
IpTask(next), start(start), promise(promise)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void run(Context* c UNUSED, unsigned, unsigned start, unsigned,
|
||||||
|
uint8_t* code, unsigned offset)
|
||||||
|
{
|
||||||
|
uint8_t* instruction = code + offset + (this->start - start);
|
||||||
|
intptr_t v = reinterpret_cast<intptr_t>(code + promise->value(c));
|
||||||
|
memcpy(instruction + (BytesPerWord / 8) + 1, &v, BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned start;
|
||||||
|
MyPromise* promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
RegisterOperand::accept(Context* c, Operation operation,
|
||||||
|
AbsoluteOperand* operand)
|
||||||
|
{
|
||||||
|
switch (operation) {
|
||||||
|
case mov: {
|
||||||
|
IpMapping* mapping = currentMapping(c);
|
||||||
|
mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask)))
|
||||||
|
AbsoluteMovTask(c->code.length(), operand->value, mapping->task);
|
||||||
|
|
||||||
|
accept(c, mov, immediate(c, 0));
|
||||||
|
accept(c, mov, memory(c, this, 0, 0, 1));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DirectCallTask: public IpTask {
|
class DirectCallTask: public IpTask {
|
||||||
public:
|
public:
|
||||||
DirectCallTask(unsigned start, uint8_t* address, IpTask* next):
|
DirectCallTask(unsigned start, uint8_t* address, IpTask* next):
|
||||||
@ -718,8 +811,11 @@ class DirectCallTask: public IpTask {
|
|||||||
uint8_t* code, unsigned offset)
|
uint8_t* code, unsigned offset)
|
||||||
{
|
{
|
||||||
uint8_t* instruction = code + offset + (this->start - start);
|
uint8_t* instruction = code + offset + (this->start - start);
|
||||||
|
assert(c, *instruction == 0xe8);
|
||||||
|
|
||||||
intptr_t v = address - instruction;
|
intptr_t v = address - instruction;
|
||||||
assert(c, isInt32(v));
|
assert(c, isInt32(v));
|
||||||
|
|
||||||
int32_t v32 = v;
|
int32_t v32 = v;
|
||||||
memcpy(instruction + 1, &v32, 4);
|
memcpy(instruction + 1, &v32, 4);
|
||||||
}
|
}
|
||||||
@ -748,6 +844,13 @@ ImmediateOperand::apply(Context* c, Operation operation)
|
|||||||
c->code.append(0xE8);
|
c->code.append(0xE8);
|
||||||
c->code.append4(0);
|
c->code.append4(0);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case alignedCall: {
|
||||||
|
while ((c->code.length() + 1) % 4) {
|
||||||
|
c->code.append(0x90);
|
||||||
|
}
|
||||||
|
apply(c, call);
|
||||||
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
@ -776,6 +879,10 @@ void
|
|||||||
MemoryOperand::apply(Context* c, Operation operation)
|
MemoryOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
|
case pop:
|
||||||
|
encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
||||||
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -812,6 +919,67 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
PoolPromise::value(Context* c)
|
||||||
|
{
|
||||||
|
if (c->ipTable) {
|
||||||
|
return c->code.length() + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
CodePromise::value(Context* c)
|
||||||
|
{
|
||||||
|
if (c->ipTable) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
IpPromise::value(Context* c)
|
||||||
|
{
|
||||||
|
if (c->ipTable) {
|
||||||
|
unsigned bottom = 0;
|
||||||
|
unsigned top = c->ipMappings.length() / BytesPerWord;
|
||||||
|
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||||
|
unsigned middle = bottom + (span / 2);
|
||||||
|
IpMapping* mapping = c->ipTable[middle];
|
||||||
|
|
||||||
|
if (key == mapping->ip) {
|
||||||
|
return mapping->start;
|
||||||
|
} else if (key < mapping->ip) {
|
||||||
|
top = middle;
|
||||||
|
} else if (key > mapping->ip) {
|
||||||
|
bottom = middle + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
runTasks(Context* c, uint8_t* out, IpTask::Priority priority)
|
||||||
|
{
|
||||||
|
uint8_t* p = out;
|
||||||
|
for (unsigned i = 0; i < c->ipMappings.length() / BytesPerWord; ++i) {
|
||||||
|
IpMapping* mapping = c->ipTable[i];
|
||||||
|
int length = mapping->end - mapping->start;
|
||||||
|
|
||||||
|
for (IpTask* t = mapping->task; t; t = t->next) {
|
||||||
|
if (t->priority() == priority) {
|
||||||
|
t->run(c, mapping->ip, mapping->start, mapping->end, out, p - out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MyCompiler: public Compiler {
|
class MyCompiler: public Compiler {
|
||||||
public:
|
public:
|
||||||
MyCompiler(System* s, void* indirectCaller):
|
MyCompiler(System* s, void* indirectCaller):
|
||||||
@ -1140,8 +1308,12 @@ class MyCompiler: public Compiler {
|
|||||||
return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip);
|
return new (c.zone.allocate(sizeof(IpPromise))) IpPromise(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned size() {
|
virtual unsigned codeSize() {
|
||||||
return c.code.length() + c.constantPool.length();
|
return c.code.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual unsigned poolSize() {
|
||||||
|
return c.constantPool.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void writeTo(uint8_t* out) {
|
virtual void writeTo(uint8_t* out) {
|
||||||
@ -1172,21 +1344,22 @@ class MyCompiler: public Compiler {
|
|||||||
for (unsigned i = 0; i < tableSize; ++i) {
|
for (unsigned i = 0; i < tableSize; ++i) {
|
||||||
IpMapping* mapping = c.ipTable[i];
|
IpMapping* mapping = c.ipTable[i];
|
||||||
int length = mapping->end - mapping->start;
|
int length = mapping->end - mapping->start;
|
||||||
memcpy(p, c.code.data + mapping->start, length);
|
|
||||||
|
|
||||||
for (IpTask* t = mapping->task; t; t = t->next) {
|
memcpy(p, c.code.data + mapping->start, length);
|
||||||
t->run(&c, mapping->ip, mapping->start, mapping->end, out, p - out);
|
|
||||||
}
|
|
||||||
|
|
||||||
p += length;
|
p += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(p, c.constantPool.data, c.constantPool.length());
|
memcpy(p, c.constantPool.data, c.constantPool.length());
|
||||||
|
|
||||||
|
runTasks(&c, out, IpTask::HighPriority);
|
||||||
|
runTasks(&c, out, IpTask::LowPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updateCall(void* returnAddress, void* newTarget) {
|
virtual void updateCall(void* returnAddress, void* newTarget) {
|
||||||
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||||
assert(&c, *instruction == 0xE8);
|
assert(&c, *instruction == 0xE8);
|
||||||
|
assert(&c, reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||||
|
|
||||||
int32_t v = static_cast<uint8_t*>(newTarget)
|
int32_t v = static_cast<uint8_t*>(newTarget)
|
||||||
- static_cast<uint8_t*>(returnAddress);
|
- static_cast<uint8_t*>(returnAddress);
|
||||||
@ -1203,52 +1376,9 @@ class MyCompiler: public Compiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
PoolPromise::value(Compiler* compiler)
|
MyPromise::value(Compiler* compiler)
|
||||||
{
|
{
|
||||||
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
|
return value(&(static_cast<MyCompiler*>(compiler)->c));
|
||||||
|
|
||||||
if (c->ipTable) {
|
|
||||||
return c->code.length() + key;
|
|
||||||
}
|
|
||||||
|
|
||||||
abort(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
CodePromise::value(Compiler* compiler)
|
|
||||||
{
|
|
||||||
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
|
|
||||||
|
|
||||||
if (c->ipTable) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
abort(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
IpPromise::value(Compiler* compiler)
|
|
||||||
{
|
|
||||||
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
|
|
||||||
|
|
||||||
if (c->ipTable) {
|
|
||||||
unsigned bottom = 0;
|
|
||||||
unsigned top = c->ipMappings.length() / BytesPerWord;
|
|
||||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
|
||||||
unsigned middle = bottom + (span / 2);
|
|
||||||
IpMapping* mapping = c->ipTable[middle];
|
|
||||||
|
|
||||||
if (key == mapping->ip) {
|
|
||||||
return mapping->start;
|
|
||||||
} else if (key < mapping->ip) {
|
|
||||||
top = middle;
|
|
||||||
} else if (key > mapping->ip) {
|
|
||||||
bottom = middle + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abort(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -94,7 +94,8 @@ class Compiler {
|
|||||||
virtual void startLogicalIp(unsigned) = 0;
|
virtual void startLogicalIp(unsigned) = 0;
|
||||||
virtual Operand* logicalIp(unsigned) = 0;
|
virtual Operand* logicalIp(unsigned) = 0;
|
||||||
|
|
||||||
virtual unsigned size() = 0;
|
virtual unsigned codeSize() = 0;
|
||||||
|
virtual unsigned poolSize() = 0;
|
||||||
virtual void writeTo(uint8_t*) = 0;
|
virtual void writeTo(uint8_t*) = 0;
|
||||||
|
|
||||||
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
||||||
|
@ -23,7 +23,7 @@ public class Misc {
|
|||||||
int b = 2;
|
int b = 2;
|
||||||
int c = a + b;
|
int c = a + b;
|
||||||
|
|
||||||
// Misc m = new Misc();
|
Misc m = new Misc();
|
||||||
// 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