2+2 test now works with new JIT code

This commit is contained in:
Joel Dice 2007-12-11 14:26:59 -07:00
parent 286f290665
commit fdeafe46fd
9 changed files with 451 additions and 155 deletions

View File

@ -28,7 +28,7 @@ src = src
classpath = classpath
test = test
input = $(test-build)/Exceptions.class
input = $(test-build)/Misc.class
build-cxx = g++
build-cc = gcc
@ -40,6 +40,7 @@ ranlib = ranlib
objcopy = objcopy
vg = nice valgrind --suppressions=valgrind.supp --undef-value-errors=no \
--num-callers=32 --db-attach=yes --freelist-vol=100000000
vg += --leak-check=full
db = gdb --args
javac = javac
jar = jar
@ -105,7 +106,7 @@ ifeq ($(platform),windows)
endif
ifeq ($(mode),debug)
cflags += -O0 -g3 -DNDEBUG
cflags += -O0 -g3
endif
ifeq ($(mode),stress)
cflags += -O0 -g3 -DNDEBUG -DVM_STRESS

View File

@ -11,35 +11,38 @@ vmInvoke:
// rbx is a callee-saved register (so are r12-r15, but we don't use those)
pushq %rbx
// %rdi: function
// %rsi: stack
// %rdx: stackSize
// %rcx: returnType
// %rdi: thread
// %rsi: function
// %rdx: stack
// %rcx: stackSize
// %r8 : returnType
mov %rdi,%rbx
// reserve space for arguments
pushq %rdx
subq %rdx,%rsp
pushq %rcx
subq %rcx,%rsp
// copy memory arguments into place
movq $0,%r8
movq $0,%r9
jmp test
loop:
movq %r8,%rax
movq %r8,%r9
addq %rsp,%r9
addq %rsi,%rax
movq %r9,%rax
movq %r9,%r10
addq %rsp,%r10
addq %rdx,%rax
movq (%rax),%rax
movq %rax,(%r9)
addq $8,%r8
movq %rax,(%r10)
addq $8,%r9
test:
cmpq %rdx,%r8
cmpq %rcx,%r9
jb loop
// call function
call *%rdi
call *%rsi
// pop arguments
addq -16(%rbp),%rsp
@ -68,13 +71,16 @@ vmInvoke:
pushl %esi
pushl %edi
// 8(%ebp): function
// 12(%ebp): stack
// 16(%ebp): stackSize
// 20(%ebp): returnType
// 8(%ebp): thread
// 12(%ebp): function
// 16(%ebp): stack
// 20(%ebp): stackSize
// 24(%ebp): returnType
mov 8(%ebp),%rbx
// reserve space for arguments
subl 16(%ebp),%esp
subl 20(%ebp),%esp
// copy arguments into place
movl $0,%ecx
@ -84,23 +90,23 @@ loop:
movl %ecx,%eax
movl %ecx,%edx
addl %esp,%edx
addl 12(%ebp),%eax
addl 16(%ebp),%eax
movl (%eax),%eax
movl %eax,(%edx)
addl $4,%ecx
test:
cmpl 16(%ebp),%ecx
cmpl 20(%ebp),%ecx
jb loop
// call function
call *8(%ebp)
call *12(%ebp)
// pop arguments
addl 16(%ebp),%esp
addl 20(%ebp),%esp
// handle return value based on expected type
movl 20(%ebp),%ecx
movl 24(%ebp),%ecx
void:
cmpl $VOID_TYPE,%ecx

View File

@ -314,7 +314,9 @@ class Frame {
}
~Frame() {
t->m->system->free(codeMask);
if (next == 0) {
t->m->system->free(codeMask);
}
}
Operand* append(object o) {
@ -378,13 +380,17 @@ class Frame {
}
void storedInt(unsigned index) {
assert(t, index < localSize(t, method));
clearBit(map, index);
if (index >= parameterFootprint(t, method)) {
assert(t, index - parameterFootprint(t, method) < localSize(t, method));
clearBit(map, index - parameterFootprint(t, method));
}
}
void storedObject(unsigned index) {
assert(t, index < localSize(t, method));
markBit(map, index);
if (index >= parameterFootprint(t, method)) {
assert(t, index - parameterFootprint(t, method) < localSize(t, method));
markBit(map, index - parameterFootprint(t, method));
}
}
void dupped() {
@ -2729,7 +2735,8 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
{
unsigned count = ceiling(c->size(), BytesPerWord);
unsigned size = count + singletonMaskSize(count);
object result = allocate2(t, size * BytesPerWord, true, true);
object result = allocate2
(t, SingletonBody + size * BytesPerWord, true, true);
initSingleton(t, result, size, true);
singletonMask(t, result)[0] = 1;
@ -3108,11 +3115,13 @@ visitStack(MyThread* t, Heap::Visitor* v)
while (true) {
object node = findTraceNode(t, *stack);
if (node) {
object method = traceNodeMethod(t, node);
PROTECT(t, node);
// we only need to visit the parameters of this method if the
// caller is native. Otherwise, the caller owns them.
object next = findTraceNode(t, static_cast<void**>(base)[1]);
object method = traceNodeMethod(t, node);
if (next == 0) {
visitParameters(t, v, base, method);
}
@ -3345,7 +3354,7 @@ class MyProcessor: public Processor {
virtual Thread*
makeThread(Machine* m, object javaThread, Thread* parent)
{
MyThread* t = new (s->allocate(sizeof(Thread)))
MyThread* t = new (s->allocate(sizeof(MyThread)))
MyThread(m, javaThread, parent);
t->init();
return t;
@ -3410,21 +3419,23 @@ class MyProcessor: public Processor {
object loader,
unsigned vtableLength)
{
object c = vm::makeClass
return vm::makeClass
(t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize,
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
methodTable, staticTable, loader, vtableLength, false);
}
for (unsigned i = 0; i < vtableLength; ++i) {
virtual void
initVtable(Thread* t, object c)
{
for (unsigned i = 0; i < classLength(t, c); ++i) {
object compiled
= ((flags & ACC_NATIVE)
= ((classFlags(t, c) & ACC_NATIVE)
? getNativeCompiled(static_cast<MyThread*>(t))
: getDefaultCompiled(static_cast<MyThread*>(t)));
classVtable(t, c, i) = &singletonBody(t, compiled, 0);
}
return c;
}
virtual void
@ -3586,6 +3597,13 @@ class MyProcessor: public Processor {
return 0;
}
virtual void dispose(Thread* thread) {
MyThread* t = static_cast<MyThread*>(thread);
while (t->reference) {
vm::dispose(t, t->reference);
}
}
virtual void dispose() {
if (indirectCaller) {
s->free(indirectCaller);
@ -3599,7 +3617,7 @@ class MyProcessor: public Processor {
object nativeCompiled;
object addressTable;
unsigned addressCount;
void* indirectCaller;
uint8_t* indirectCaller;
};
MyProcessor*
@ -3619,8 +3637,11 @@ processor(MyThread* t)
c->jmp(c->indirectTarget());
p->indirectCaller = t->m->system->allocate(c->size());
p->indirectCaller = static_cast<uint8_t*>
(t->m->system->allocate(c->size()));
c->writeTo(p->indirectCaller);
c->dispose();
}
}
return p;
@ -3631,14 +3652,12 @@ compile(MyThread* t, object method)
{
MyProcessor* p = processor(t);
object stub = p->getDefaultCompiled(t);
if (methodCompiled(t, method) == stub) {
if (methodCompiled(t, method) == p->getDefaultCompiled(t)) {
PROTECT(t, method);
ACQUIRE(t, t->m->classLock);
if (methodCompiled(t, method) == stub) {
if (methodCompiled(t, method) == p->getDefaultCompiled(t)) {
PROTECT(t, method);
Compiler* c = makeCompiler(t->m->system, p->indirectCaller);
@ -3655,6 +3674,7 @@ object
findTraceNode(MyThread* t, void* address)
{
MyProcessor* p = processor(t);
ACQUIRE(t, t->m->classLock);
intptr_t key = reinterpret_cast<intptr_t>(address);
unsigned index = static_cast<uintptr_t>(key)
@ -3700,13 +3720,12 @@ void
insertTraceNode(MyThread* t, object node)
{
MyProcessor* p = processor(t);
ENTER(t, Thread::ExclusiveState);
PROTECT(t, node);
ACQUIRE(t, t->m->classLock);
++ p->addressCount;
if (p->addressCount >= arrayLength(t, p->addressTable) * 2) {
PROTECT(t, node);
p->addressTable = resizeTable
(t, p->addressTable, arrayLength(t, p->addressTable) * 2);
}

View File

@ -25,8 +25,19 @@ enum Register {
r15 = 15,
};
const unsigned RegisterCount32 = 8;
const unsigned RegisterCount64 = 16;
const unsigned RegisterCount = BytesPerWord * 2;
class Context;
class ImmediateOperand;
class RegisterOperand;
class MemoryOperand;
class StackOperand;
void NO_RETURN abort(Context*);
#ifndef NDEBUG
void assert(Context*, bool);
#endif // not NDEBUG
inline bool
isInt8(intptr_t v)
@ -40,14 +51,28 @@ isInt32(intptr_t v)
return v == static_cast<int32_t>(v);
}
class IpTask {
public:
IpTask(IpTask* next): next(next) { }
virtual ~IpTask() { }
virtual void run(Context* c, unsigned ip, unsigned start, unsigned end,
uint8_t* code, unsigned offset) = 0;
IpTask* next;
};
class IpMapping {
public:
IpMapping(unsigned ip, unsigned start): ip(ip), start(start), end(-1) { }
IpMapping(int ip, int start):
ip(ip), start(start), end(-1), task(0)
{ }
const int ip;
const int start;
int end;
int offset;
IpTask* task;
};
int
@ -59,45 +84,45 @@ compareIpMappingPointers(const void* a, const void* b)
class MyPromise: public Promise {
public:
MyPromise(intptr_t value): resolved(false), value_(value) { }
MyPromise(intptr_t key): key(key) { }
bool resolved;
intptr_t value_;
intptr_t key;
};
class PoolPromise: public MyPromise {
public:
PoolPromise(intptr_t value): MyPromise(value) { }
PoolPromise(intptr_t key): MyPromise(key) { }
virtual unsigned value(Compiler*);
};
class CodePromise: public MyPromise {
public:
CodePromise(intptr_t value): MyPromise(value) { }
CodePromise(intptr_t key): MyPromise(key) { }
virtual unsigned value(Compiler*);
};
class CodePromiseTask: public IpTask {
public:
CodePromiseTask(CodePromise* p, IpTask* next): IpTask(next), p(p) { }
virtual void run(Context*, unsigned, unsigned start, unsigned, uint8_t*,
unsigned offset)
{
p->key = offset + (p->key - start);
}
CodePromise* p;
};
class IpPromise: public MyPromise {
public:
IpPromise(intptr_t value): MyPromise(value) { }
IpPromise(intptr_t key): MyPromise(key) { }
virtual unsigned value(Compiler*);
};
class Context;
class ImmediateOperand;
class RegisterOperand;
class MemoryOperand;
class StackOperand;
void NO_RETURN abort(Context*);
#ifndef NDEBUG
void assert(Context*, bool);
#endif // not NDEBUG
class MyOperand: public Operand {
public:
enum Operation {
@ -156,8 +181,6 @@ class MyOperand: public Operand {
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
};
class StackOperand;
class RegisterOperand: public MyOperand {
public:
RegisterOperand(Register value):
@ -169,17 +192,25 @@ class RegisterOperand: public MyOperand {
stack = 0;
}
virtual Register asRegister(Context*) {
return value;
}
virtual void release(Context* c UNUSED) {
assert(c, reserved);
reserved = false;
}
virtual void apply(Context* c, Operation) { abort(c); }
virtual void apply(Context*, Operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
operand->accept(c, operation, this);
}
virtual void accept(Context*, Operation, RegisterOperand*);
virtual void accept(Context*, Operation, ImmediateOperand*);
virtual void accept(Context*, Operation, MemoryOperand*);
Register value;
bool reserved;
StackOperand* stack;
@ -191,7 +222,9 @@ class ImmediateOperand: public MyOperand {
value(value)
{ }
virtual void apply(Context* c, Operation) { abort(c); }
virtual StackOperand* logicalPush(Context* c);
virtual void apply(Context* c, Operation operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
operand->accept(c, operation, this);
@ -206,8 +239,10 @@ class AbsoluteOperand: public MyOperand {
value(value)
{ }
virtual void apply(Context* c, Operation operation);
virtual void setAbsolute(Context*, intptr_t v) {
value->value_ = v;
value->key = v;
}
MyPromise* value;
@ -223,10 +258,17 @@ class MemoryOperand: public MyOperand {
scale(scale)
{ }
virtual StackOperand* logicalPush(Context* c);
virtual void apply(Context* c, Operation operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
operand->accept(c, operation, this);
}
virtual void accept(Context*, Operation, RegisterOperand*);
virtual void accept(Context*, Operation, ImmediateOperand*);
MyOperand* base;
int displacement;
MyOperand* index;
@ -271,6 +313,12 @@ class StackOperand: public MyOperand {
}
}
virtual void accept(Context* c, Operation operation,
RegisterOperand* operand)
{
base->accept(c, operation, operand);
}
MyOperand* base;
StackOperand* next;
int index;
@ -287,10 +335,12 @@ class Context {
zone(s, 8 * 1024),
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
stack(0),
machineTable(0),
logicalTable(0)
ipTable(0)
{
for (unsigned i = 0; i < RegisterCount64; ++i) {
ipMappings.appendAddress
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
for (unsigned i = 0; i < RegisterCount; ++i) {
registers[i] = new (zone.allocate(sizeof(RegisterOperand)))
RegisterOperand(static_cast<Register>(i));
}
@ -305,8 +355,7 @@ class Context {
ipMappings.dispose();
constantPool.dispose();
code.dispose();
if (machineTable) s->free(machineTable);
if (logicalTable) s->free(logicalTable);
if (ipTable) s->free(ipTable);
}
System* s;
@ -316,9 +365,8 @@ class Context {
Zone zone;
intptr_t indirectCaller;
StackOperand* stack;
IpMapping** machineTable;
IpMapping** logicalTable;
RegisterOperand* registers[RegisterCount64];
IpMapping** ipTable;
RegisterOperand* registers[RegisterCount];
};
inline void NO_RETURN
@ -367,6 +415,15 @@ memory(Context* c, MyOperand* base, int displacement,
MemoryOperand(base, displacement, index, scale);
}
IpMapping*
currentMapping(Context* c)
{
IpMapping* mapping;
c->ipMappings.get
(c->ipMappings.length() - BytesPerWord, &mapping, BytesPerWord);
return mapping;
}
void
flush(Context* c, StackOperand* s)
{
@ -380,13 +437,14 @@ flush(Context* c, StackOperand* s)
}
RegisterOperand*
temporary(Context* c)
temporary(Context* c, bool reserve)
{
RegisterOperand* r = 0;
for (unsigned i = 0; i < RegisterCount32; ++i) {
// we don't yet support using r9-r15
for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) {
if (not c->registers[i]->reserved) {
if (not c->registers[i]->stack) {
c->registers[i]->reserved = true;
if (c->registers[i]->stack == 0) {
if (reserve) c->registers[i]->reserved = true;
return c->registers[i];
} else if (r == 0 or r->stack->index > c->registers[i]->stack->index) {
r = c->registers[i];
@ -429,14 +487,16 @@ pop(Context* c, MyOperand* dst)
MyOperand*
pop(Context* c)
{
MyOperand* r;
if (c->stack->flushed) {
RegisterOperand* tmp = temporary(c);
RegisterOperand* tmp = temporary(c, true);
tmp->apply(c, MyOperand::pop);
return tmp;
r = tmp;
} else {
return c->stack->base;
r = c->stack->base;
}
c->stack = c->stack->next;
return r;
}
MyOperand*
@ -521,7 +581,6 @@ pushArguments(Context* c, unsigned count, va_list list)
}
}
void
rex(Context* c)
{
@ -567,6 +626,192 @@ encode(Context* c, uint8_t instruction, uint8_t zeroPrefix,
}
}
void
RegisterOperand::apply(Context* c, Operation operation)
{
switch (operation) {
case push:
c->code.append(0x50 | value);
break;
case pop:
c->code.append(0x58 | value);
break;
case jmp:
c->code.append(0xff);
c->code.append(0xe0 | value);
break;
case call:
c->code.append(0xff);
c->code.append(0xd0 | value);
break;
default: abort(c);
}
}
void
RegisterOperand::accept(Context* c, Operation operation,
RegisterOperand* operand)
{
switch (operation) {
case mov:
if (value != operand->value) {
rex(c);
c->code.append(0x89);
c->code.append(0xc0 | (operand->value << 3) | value);
}
break;
case add:
rex(c);
c->code.append(0x01);
c->code.append(0xc0 | (operand->value << 3) | value);
break;
default: abort(c);
}
}
void
RegisterOperand::accept(Context* c, Operation operation,
ImmediateOperand* operand)
{
switch (operation) {
case sub:
assert(c, isInt8(operand->value)); // todo
rex(c);
c->code.append(0x83);
c->code.append(0xe8 | value);
c->code.append(operand->value);
break;
default: abort(c);
}
}
void
RegisterOperand::accept(Context* c, Operation operation,
MemoryOperand* operand)
{
switch (operation) {
case mov:
rex(c);
encode(c, 0x8b, 0, 0x40, 0x80, value, operand->base->asRegister(c),
operand->displacement);
break;
default: abort(c);
}
}
class DirectCallTask: public IpTask {
public:
DirectCallTask(unsigned start, uint8_t* address, IpTask* next):
IpTask(next), start(start), address(address)
{ }
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 = address - instruction;
assert(c, isInt32(v));
int32_t v32 = v;
memcpy(instruction + 1, &v32, 4);
}
unsigned start;
uint8_t* address;
};
StackOperand*
ImmediateOperand::logicalPush(Context* c)
{
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
StackOperand(this, c->stack);
}
void
ImmediateOperand::apply(Context* c, Operation operation)
{
switch (operation) {
case call: {
IpMapping* mapping = currentMapping(c);
mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
DirectCallTask
(c->code.length(), reinterpret_cast<uint8_t*>(value), mapping->task);
c->code.append(0xE8);
c->code.append4(0);
} break;
default: abort(c);
}
}
void
AbsoluteOperand::apply(Context* c, Operation operation)
{
switch (operation) {
default: abort(c);
}
}
StackOperand*
MemoryOperand::logicalPush(Context* c)
{
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;
return c->stack;
}
void
MemoryOperand::apply(Context* c, Operation operation)
{
switch (operation) {
default: abort(c);
}
}
void
MemoryOperand::accept(Context* c, Operation operation,
RegisterOperand* operand)
{
switch (operation) {
case mov:
rex(c);
encode(c, 0x89, 0, 0x40, 0x80, operand->value, base->asRegister(c),
displacement);
break;
default: abort(c);
}
}
void
MemoryOperand::accept(Context* c, Operation operation,
ImmediateOperand* operand)
{
switch (operation) {
case mov:
assert(c, isInt32(operand->value)); // todo
rex(c);
encode(c, 0xc7, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
c->code.append4(operand->value);
break;
default: abort(c);
}
}
class MyCompiler: public Compiler {
public:
MyCompiler(System* s, void* indirectCaller):
@ -579,8 +824,18 @@ class MyCompiler: public Compiler {
}
virtual Promise* codeOffset() {
return new (c.zone.allocate(sizeof(CodePromise)))
CodePromise(c.code.length());
if (c.code.length() == 0) {
return new (c.zone.allocate(sizeof(CodePromise))) CodePromise(0);
} else {
CodePromise* p = new (c.zone.allocate(sizeof(CodePromise)))
CodePromise(c.code.length());
IpMapping* mapping = currentMapping(&c);
mapping->task = new (c.zone.allocate(sizeof(CodePromiseTask)))
CodePromiseTask(p, mapping->task);
return p;
}
}
virtual Operand* poolAppend(Operand* v) {
@ -651,7 +906,7 @@ class MyCompiler: public Compiler {
}
virtual Operand* temporary() {
return ::temporary(&c);
return ::temporary(&c, true);
}
virtual void release(Operand* v) {
@ -868,12 +1123,13 @@ class MyCompiler: public Compiler {
virtual void epilogue() {
register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp));
register_(&c, rbp)->apply(&c, MyOperand::push);
register_(&c, rbp)->apply(&c, MyOperand::pop);
}
virtual void startLogicalIp(unsigned ip) {
new (c.ipMappings.allocate(sizeof(IpMapping)))
IpMapping(ip, c.code.length());
c.ipMappings.appendAddress
(new (c.zone.allocate(sizeof(IpMapping)))
IpMapping(ip, c.code.length()));
}
virtual Operand* logicalIp(unsigned ip) {
@ -888,39 +1144,40 @@ class MyCompiler: public Compiler {
return c.code.length() + c.constantPool.length();
}
virtual void writeTo(void* out) {
unsigned tableSize = (c.ipMappings.length() / sizeof(IpMapping));
virtual void writeTo(uint8_t* out) {
unsigned tableSize = (c.ipMappings.length() / BytesPerWord);
c.machineTable = static_cast<IpMapping**>
(c.s->allocate(tableSize * BytesPerWord));
c.logicalTable = static_cast<IpMapping**>
(c.s->allocate(tableSize * BytesPerWord));
c.ipTable = static_cast<IpMapping**>
(c.s->allocate(c.ipMappings.length()));
for (unsigned i = 0; i < tableSize; ++i) {
IpMapping* mapping = c.ipMappings.peek<IpMapping>(i * sizeof(IpMapping));
IpMapping* mapping;
c.ipMappings.get(i * BytesPerWord, &mapping, BytesPerWord);
if (i + 1 < c.ipMappings.length()) {
mapping->end = c.ipMappings.peek<IpMapping>
((i + 1) * sizeof(IpMapping))->start;
if (i + 1 < tableSize) {
IpMapping* next;
c.ipMappings.get((i + 1) * BytesPerWord, &next, BytesPerWord);
mapping->end = next->start;
} else {
mapping->end = c.code.length();
}
c.machineTable[i] = mapping;
c.logicalTable[i] = mapping;
c.ipTable[i] = mapping;
}
qsort(c.logicalTable, c.ipMappings.length() / sizeof(IpMapping),
BytesPerWord, compareIpMappingPointers);
qsort(c.ipTable, tableSize, BytesPerWord, compareIpMappingPointers);
uint8_t* p = static_cast<uint8_t*>(out);
uint8_t* p = out;
for (unsigned i = 0; i < tableSize; ++i) {
IpMapping* mapping = c.logicalTable[i];
mapping->offset = (p - static_cast<uint8_t*>(out));
IpMapping* mapping = c.ipTable[i];
int length = mapping->end - mapping->start;
memcpy(p, c.code.data + mapping->start, length);
for (IpTask* t = mapping->task; t; t = t->next) {
t->run(&c, mapping->ip, mapping->start, mapping->end, out, p - out);
}
p += length;
}
@ -950,8 +1207,8 @@ PoolPromise::value(Compiler* compiler)
{
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
if (c->logicalTable) {
return c->code.length() + value_;
if (c->ipTable) {
return c->code.length() + key;
}
abort(c);
@ -962,21 +1219,8 @@ CodePromise::value(Compiler* compiler)
{
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
if (c->logicalTable) {
unsigned bottom = 0;
unsigned top = c->ipMappings.length() / sizeof(IpMapping);
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
IpMapping* mapping = c->machineTable[middle];
if (value_ >= mapping->start and value_ < mapping->end) {
return mapping->offset + (value_ - mapping->start);
} else if (value_ < mapping->start) {
top = middle;
} else if (value_ > mapping->start) {
bottom = middle + 1;
}
}
if (c->ipTable) {
return key;
}
abort(c);
@ -987,18 +1231,18 @@ IpPromise::value(Compiler* compiler)
{
Context* c = &(static_cast<MyCompiler*>(compiler)->c);
if (c->logicalTable) {
if (c->ipTable) {
unsigned bottom = 0;
unsigned top = c->ipMappings.length() / sizeof(IpMapping);
unsigned top = c->ipMappings.length() / BytesPerWord;
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
IpMapping* mapping = c->logicalTable[middle];
IpMapping* mapping = c->ipTable[middle];
if (value_ == mapping->ip) {
if (key == mapping->ip) {
return mapping->start;
} else if (value_ < mapping->ip) {
} else if (key < mapping->ip) {
top = middle;
} else if (value_ > mapping->ip) {
} else if (key > mapping->ip) {
bottom = middle + 1;
}
}

View File

@ -95,7 +95,7 @@ class Compiler {
virtual Operand* logicalIp(unsigned) = 0;
virtual unsigned size() = 0;
virtual void writeTo(void*) = 0;
virtual void writeTo(uint8_t*) = 0;
virtual void updateCall(void* returnAddress, void* newTarget) = 0;

View File

@ -2867,6 +2867,12 @@ class MyProcessor: public Processor {
methodTable, staticTable, loader, 0, false);
}
virtual void
initVtable(Thread*, object)
{
// ignore
}
virtual void
initClass(vm::Thread* t, object c)
{
@ -3009,6 +3015,10 @@ class MyProcessor: public Processor {
}
}
virtual void dispose(vm::Thread*) {
// ignore
}
virtual void dispose() {
s->free(this);
}

View File

@ -1498,7 +1498,7 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec,
object vtable = classVirtualTable
(t, arrayBody(t, t->m->types, Machine::JobjectType));
return t->m->processor->makeClass
object c = t->m->processor->makeClass
(t,
0,
0,
@ -1515,6 +1515,10 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec,
elementClass,
t->m->loader,
arrayLength(t, vtable));
t->m->processor->initVtable(t, c);
return c;
}
object
@ -1662,6 +1666,8 @@ bootJavaClass(Thread* t, Machine::Type type, int superType, const char* name,
set(t, class_, ClassVirtualTable, vtable);
t->m->processor->initVtable(t, class_);
hashMapInsert(t, t->m->bootstrapClassMap, n, class_, byteArrayHash);
}
@ -1986,6 +1992,8 @@ Thread::exit()
void
Thread::dispose()
{
m->processor->dispose(this);
if (systemThread) {
systemThread->dispose();
}
@ -2471,6 +2479,8 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
classLoader(t, class_),
vtableLength);
t->m->processor->initVtable(t, real);
updateClassTables(t, real, class_);
return real;

View File

@ -67,6 +67,9 @@ class Processor {
object loader,
unsigned vtableLength) = 0;
virtual void
initVtable(Thread* t, object c) = 0;
virtual void
initClass(Thread* t, object c) = 0;
@ -96,6 +99,9 @@ class Processor {
invokeList(Thread* t, const char* className, const char* methodName,
const char* methodSpec, object this_, va_list arguments) = 0;
virtual void
dispose(Thread* t) = 0;
virtual void
dispose() = 0;

View File

@ -15,24 +15,24 @@ public class Misc {
}
public static void main(String[] args) {
boolean v = Boolean.valueOf("true");
// boolean v = Boolean.valueOf("true");
ClassLoader.getSystemClassLoader().toString();
// ClassLoader.getSystemClassLoader().toString();
int a = 2;
int b = 2;
int c = a + b;
Misc m = new Misc();
String s = "hello";
m.foo(s);
m.bar(s);
baz(s);
// Misc m = new Misc();
// String s = "hello";
// m.foo(s);
// m.bar(s);
// baz(s);
int d = alpha;
beta = 42;
alpha = 43;
int e = beta;
int f = alpha;
// int d = alpha;
// beta = 42;
// alpha = 43;
// int e = beta;
// int f = alpha;
}
}