diff --git a/makefile b/makefile index 90b9cc5c96..1bc59372f5 100644 --- a/makefile +++ b/makefile @@ -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 diff --git a/src/compile.S b/src/compile.S index 328685e374..f37abea206 100644 --- a/src/compile.S +++ b/src/compile.S @@ -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 diff --git a/src/compile.cpp b/src/compile.cpp index 716e4ee092..be3fbcfa92 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(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(t)) : getDefaultCompiled(static_cast(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(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 + (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(address); unsigned index = static_cast(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); } diff --git a/src/compiler.cpp b/src/compiler.cpp index 14fd089f0d..112968c4c3 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -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(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(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(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(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 - (c.s->allocate(tableSize * BytesPerWord)); - c.logicalTable = static_cast - (c.s->allocate(tableSize * BytesPerWord)); + c.ipTable = static_cast + (c.s->allocate(c.ipMappings.length())); for (unsigned i = 0; i < tableSize; ++i) { - IpMapping* mapping = c.ipMappings.peek(i * sizeof(IpMapping)); + IpMapping* mapping; + c.ipMappings.get(i * BytesPerWord, &mapping, BytesPerWord); - if (i + 1 < c.ipMappings.length()) { - mapping->end = c.ipMappings.peek - ((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(out); + uint8_t* p = out; for (unsigned i = 0; i < tableSize; ++i) { - IpMapping* mapping = c.logicalTable[i]; - mapping->offset = (p - static_cast(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(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(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(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; } } diff --git a/src/compiler.h b/src/compiler.h index aa15a5a3a4..acc9546173 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -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; diff --git a/src/interpret.cpp b/src/interpret.cpp index d0b865a80c..ebfc73c1c0 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -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); } diff --git a/src/machine.cpp b/src/machine.cpp index c094602a9c..a6cff9c1b1 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -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; diff --git a/src/processor.h b/src/processor.h index d08b257af4..d53148fbac 100644 --- a/src/processor.h +++ b/src/processor.h @@ -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; diff --git a/test/Misc.java b/test/Misc.java index 59b7d88d55..a0a1910f30 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -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; } }