From 79603e284d4ebb6574e044a08573b8e1afeafb9c Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 28 Sep 2007 17:41:03 -0600 Subject: [PATCH] sketch of Compiler.compileNative() and ifnull instruction implementation --- makefile | 2 - src/builtin.cpp | 3 +- src/compile.cpp | 619 ++++++++++++++++++++++++++++++----------- src/interpret.cpp | 102 +++---- src/machine.cpp | 31 +-- src/machine.h | 52 ++++ src/process.h | 13 + test/Instructions.java | 7 +- 8 files changed, 572 insertions(+), 257 deletions(-) diff --git a/makefile b/makefile index 75c10ad1ff..c22d4a44d5 100644 --- a/makefile +++ b/makefile @@ -147,8 +147,6 @@ classpath-objects = $(classpath-classes) $(jni-library) test-sources = $(shell find $(test) -name '*.java') test-classes = $(call java-classes,$(test-sources),$(test)) -classpath-objects = $(classpath-classes) $(jni-library) - class-name = $(patsubst $(cls)/%.class,%,$(1)) class-names = $(foreach x,$(1),$(call class-name,$(x))) diff --git a/src/builtin.cpp b/src/builtin.cpp index 03889d38aa..8b3bfd1053 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -491,8 +491,7 @@ Java_java_lang_Runtime_load(Thread* t, jclass, jstring name, jboolean mapName) char n[stringLength(t, *name) + 1]; stringChars(t, *name, n); - for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) - { + for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { if (lib->name() and strcmp(lib->name(), n) == 0 and lib->mapName() == mapName) diff --git a/src/compile.cpp b/src/compile.cpp index 76cced7240..b558370906 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -18,55 +18,80 @@ const unsigned FrameMethod = FrameThread + BytesPerWord; const unsigned FrameNext = FrameNext + BytesPerWord; const unsigned FrameFootprint = BytesPerWord * 3; -class Rope { +class Buffer { public: - class Node { - public: - static const unsigned Size = 32; - - Node(): - next(0) - { } - - Node* next; - uint8_t data[Size]; - }; - - Rope() { } - - Rope(System* s): + Buffer(System* s, unsigned minimumCapacity): s(s), - front(0), - rear(0), - count(0), - position(Node::Size) + data(0), + position(0), + capacity(0), + minimumCapacity(minimumCapacity) { } - void append(uint8_t v) { - if (position == Node::Size) { - if (front == 0 or rear->next == 0) { - Node* n = new (s->allocate(sizeof(Node))) Node; - if (front == 0) { - front = rear = n; - } else { - rear->next = n; - rear = n; - } - } else { - rear = rear->next; - } - position = 0; - ++ count; + ~Buffer() { + if (data) { + s->free(data); } + } - rear->data[position++] = v; + void ensure(unsigned space) { + if (position + space > capacity) { + unsigned newCapacity = max + (position + space, max(minimumCapacity, capacity * 2)); + uint8_t* newData = static_cast(s->allocate(newCapacity)); + if (data) { + memcpy(newData, data, position); + s->free(data); + } + data = newData; + } + } + + void append(uint8_t v) { + ensure(1); + data[position++] = v; + } + + void append2(uint32_t v) { + ensure(2); + data[position++] = (v >> 0) & 0xFF; + data[position++] = (v >> 8) & 0xFF; } void append4(uint32_t v) { - append((v >> 0) & 0xFF); - append((v >> 8) & 0xFF); - append((v >> 16) & 0xFF); - append((v >> 24) & 0xFF); + ensure(4); + data[position++] = (v >> 0) & 0xFF; + data[position++] = (v >> 8) & 0xFF; + data[position++] = (v >> 16) & 0xFF; + data[position++] = (v >> 24) & 0xFF; + } + + void set2(unsigned offset, uint32_t v) { + assert(s, offset + 2 < position); + data[offset++] = (v >> 0) & 0xFF; + data[offset++] = (v >> 8) & 0xFF; + } + + void set4(unsigned offset, uint32_t v) { + assert(s, offset + 4 < position); + data[offset++] = (v >> 0) & 0xFF; + data[offset++] = (v >> 8) & 0xFF; + data[offset++] = (v >> 16) & 0xFF; + data[offset++] = (v >> 24) & 0xFF; + } + + uint16_t get2(unsigned offset) { + assert(s, offset + 2 < position); + return ((data[offset++] << 0) | + (data[offset++] << 8)); + } + + uint32_t get4(unsigned offset) { + assert(s, offset + 4 < position); + return ((data[offset++] << 0) | + (data[offset++] << 8) | + (data[offset++] << 16) | + (data[offset++] << 24)); } void appendAddress(uintptr_t v) { @@ -77,30 +102,20 @@ class Rope { } unsigned length() { - return (count * Node::Size) + position; + return position; } void copyTo(uint8_t* b) { - if (front) { - Node* n = front; - while (true) { - if (n == rear) { - memcpy(b, n->data, position); - break; - } else { - memcpy(b, n->data, Node::Size); - b += Node::Size; - n = n->next; - } - } + if (data) { + memcpy(b, data, position); } } System* s; - Node* front; - Node* rear; - unsigned count; + uint8_t* data; unsigned position; + unsigned capacity; + unsigned minimumCapacity; }; class ArgumentList; @@ -123,16 +138,40 @@ isByte(int32_t v) return v == static_cast(v); } +enum Register { + rax = 0, + rcx = 1, + rdx = 2, + rbx = 3, + rsp = 4, + rbp = 5, + rsi = 6, + rdi = 7, + r8 = 8, + r9 = 9, + r10 = 10, + r11 = 11, + r12 = 12, + r13 = 13, + r14 = 14, + r15 = 15, +}; + +enum SSERegister { + xmm0 = 0, + xmm1 = 1, + xmm2 = 2, + xmm3 = 3, + xmm4 = 4, + xmm5 = 5, + xmm6 = 6, + xmm7 = 7 +}; + class Assembler { public: class Label { public: - class Snapshot { - public: - Rope code; - unsigned ip; - }; - static const unsigned Capacity = 8; Label(Assembler* a): @@ -141,45 +180,34 @@ class Assembler { mark_(-1) { } - void reference(unsigned ip) { + void reference() { if (mark_ == -1) { expect(code->s, unresolvedCount < Capacity); - unresolved[unresolvedCount].code = *code; - unresolved[unresolvedCount].ip = ip; + unresolved[unresolvedCount] = code->length(); ++ unresolvedCount; - code->appendAddress(0); + code->append4(0); } else { - code->appendAddress(mark_ - ip); + code->append4(mark_ - (code->length() + 4)); } } void mark() { mark_ = code->length(); for (unsigned i = 0; i < unresolvedCount; ++i) { - unresolved[i].code.appendAddress(mark_ - unresolved[i].ip); + code->set4(unresolved[i], mark_ - (unresolved[i] + 4)); } } - Rope* code; - Snapshot unresolved[Capacity]; + Buffer* code; + unsigned unresolved[Capacity]; unsigned unresolvedCount; int mark_; }; - enum Register { - rax = 0, - rcx = 1, - rdx = 2, - rbx = 3, - rsp = 4, - rbp = 5, - rsi = 6, - rdi = 7 - }; - Assembler(System* s): - code(s) + code(s, 1024), + jumps(s, 32) { } void rex() { @@ -196,7 +224,7 @@ class Assembler { void offsetInstruction(uint8_t instruction, uint8_t zeroPrefix, uint8_t bytePrefix, uint8_t wordPrefix, - Register a, Register b, int32_t offset) + unsigned a, unsigned b, int32_t offset) { code.append(instruction); @@ -232,6 +260,12 @@ class Assembler { offsetInstruction(0x89, 0, 0x40, 0x80, src, dst, dstOffset); } + void mov(Register src, int32_t srcOffset, SSERegister dst) { + code.append(0xf3); + code.append(0x0f); + offsetInstruction(0x7e, 0, 0x40, 0x80, dst, src, srcOffset); + } + void mov(Register src, int32_t srcOffset, Register dst) { rex(); mov4(src, srcOffset, dst); @@ -377,7 +411,16 @@ class Assembler { void jmp(Label& label) { code.append(0xE9); - label.reference(code.length() + BytesPerWord); + label.reference(); + } + + void jmp(unsigned javaIP) { + code.append(0xE9); + + jumps.append4(javaIP); + jumps.append4(code.length()); + + code.append4(0); } void jmp(Register reg) { @@ -388,21 +431,33 @@ class Assembler { void jz(Label& label) { code.append(0x0F); code.append(0x84); - label.reference(code.length() + BytesPerWord); + label.reference(); } - void je(Label& label) { - jz(label); + void jz(unsigned javaIP) { + code.append(0x0F); + code.append(0x84); + + jumps.append4(javaIP); + jumps.append4(code.length()); + + code.append4(0); } void jnz(Label& label) { code.append(0x0F); code.append(0x85); - label.reference(code.length() + BytesPerWord); + label.reference(); } - void jne(Label& label) { - jnz(label); + void jnz(unsigned javaIP) { + code.append(0x0F); + code.append(0x85); + + jumps.append4(javaIP); + jumps.append4(code.length()); + + code.append4(0); } void cmp(int v, Register reg) { @@ -416,7 +471,8 @@ class Assembler { code.append(0xd0 | reg); } - Rope code; + Buffer code; + Buffer jumps; }; void @@ -433,10 +489,48 @@ localOffset(int v, int parameterFootprint) } } +Register +gpRegister(Thread* t, unsigned index) +{ + switch (index) { + case 0: + return rdi; + case 1: + return rsi; + case 2: + return rdx; + case 3: + return rcx; + case 4: + return r8; + case 5: + return r9; + default: + abort(t); + } +} + +SSERegister +sseRegister(Thread* t, unsigned index) +{ + assert(t, index < 8); + return static_cast(index); +} + +unsigned +parameterOffset(Thread* t, object method, unsigned index) +{ + return FrameFootprint + + (((methodParameterFootprint(t, method) - index - 1) + 2) + * BytesPerWord); +} + class Compiler: public Assembler { public: Compiler(System* s): - Assembler(s) + Assembler(s), + javaIPs(s, 1024), + machineIPs(s, 1024) { } void pushReturnValue(Thread* t, unsigned code) { @@ -493,7 +587,6 @@ class Compiler: public Assembler { } mov(function, rax); - call(rax); if (BytesPerWord == 4) { @@ -501,11 +594,176 @@ class Compiler: public Assembler { } } - void compile(Thread* t, object method) { - PROTECT(t, method); + void compile(MyThread* t, object method) { + if (methodFlags(t, method) & ACC_NATIVE) { + compileNative(t, method); + } else { + compileJava(t, method); + } + } + + void compileNative(MyThread* t, object method) { + unsigned frameOffset = reinterpret_cast(&(t->frame)) + - reinterpret_cast(t); + + void* function = resolveNativeMethod(t, method); push(rbp); mov(rsp, rbp); + + mov(rbp, FrameThread, rax); + mov(rbp, rax, frameOffset); // set thread frame to current + + unsigned index; + if (methodFlags(t, method) & ACC_STATIC) { + pushAddress(reinterpret_cast(methodClass(t, method))); + index = 0; + } else { + index = 1; + } + + MethodSpecIterator it(t, reinterpret_cast + (&byteArrayBody(t, methodSpec(t, method), 0))); + + unsigned stackFootprint; + + if (BytesPerWord == 4) { + while (it.hasNext()) { + unsigned offset = parameterOffset(t, method, index); + + switch (fieldCode(t, *it.next())) { + case BooleanField: + case ByteField: + case ShortField: + case CharField: + case IntField: + case FloatField: { + push(rbp, offset); + ++ index; + } break; + + case LongField: + case DoubleField: { + push(rbp, offset); + push(rbp, offset - BytesPerWord); + index += 2; + } break; + + case ObjectField: { + mov(rbp, rax); + add(offset, rax); + push(rax); + ++ index; + } break; + + default: + abort(t); + } + } + + if (methodFlags(t, method) & ACC_STATIC) { + mov(rbp, rax); + sub(BytesPerWord, rax); + push(rax); // push pointer to class pointer + } else { + unsigned offset = parameterOffset(t, method, 0); + mov(rbp, rax); + add(offset, rax); + push(rax); // push pointer to this pointer + } + + push(rbp, FrameThread); // push thread pointer + + stackFootprint = FrameFootprint + + (methodParameterFootprint(t, method) * BytesPerWord); + } else { + const unsigned GprCount = 6; + unsigned gprIndex = 0; + + const unsigned SseCount = 8; + unsigned sseIndex = 0; + + stackFootprint = 0; + + while (it.hasNext()) { + unsigned offset = parameterOffset(t, method, index); + + switch (fieldCode(t, *it.next())) { + case BooleanField: + case ByteField: + case ShortField: + case CharField: + case IntField: + case LongField: { + if (gprIndex < GprCount - 2) { + Register reg = gpRegister(t, gprIndex + 2); + mov(rbp, offset, reg); + ++ gprIndex; + } else { + push(rbp, offset); + stackFootprint += BytesPerWord; + } + } break; + + case ObjectField: { + if (gprIndex < GprCount - 2) { + Register reg = gpRegister(t, gprIndex + 2); + mov(rbp, reg); + add(offset, reg); + ++ gprIndex; + } else { + mov(rbp, rax); + add(offset, rax); + push(rax); + stackFootprint += BytesPerWord; + } + } break; + + case FloatField: + case DoubleField: { + if (sseIndex < SseCount) { + SSERegister reg = sseRegister(t, sseIndex); + mov(rbp, offset, reg); + ++ sseIndex; + } else { + push(rbp, offset); + stackFootprint += BytesPerWord; + } + } break; + + default: + abort(t); + } + + ++ index; + } + + if (methodFlags(t, method) & ACC_STATIC) { + mov(rbp, rsi); + sub(BytesPerWord, rsi); // push pointer to class pointer + } else { + unsigned offset = parameterOffset(t, method, 0); + mov(rbp, rsi); + add(offset, rsi); // push pointer to this pointer + } + + mov(rbp, FrameThread, rdi); // push thread pointer + } + + mov(reinterpret_cast(function), rax); + call(rax); + + if (stackFootprint) { + add(stackFootprint, rsp); + } + + mov(rbp, rsp); + pop(rbp); + ret(); + } + + void compileJava(MyThread* t, object method) { + PROTECT(t, method); object code = methodCode(t, method); PROTECT(t, code); @@ -515,15 +773,51 @@ class Compiler: public Assembler { unsigned localFootprint = codeMaxLocals(t, code) * BytesPerWord; + push(rbp); + mov(rsp, rbp); + if (localFootprint > parameterFootprint) { // reserve space for local variables sub(localFootprint - parameterFootprint, rsp); } for (unsigned ip = 0; ip < codeLength(t, code);) { + javaIPs.append2(ip); + machineIPs.append4(this->code.length()); + unsigned instruction = codeBody(t, code, ip++); switch (instruction) { + case aload: + case iload: + case fload: + push(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint)); + break; + + case aload_0: + case iload_0: + case fload_0: + push(rbp, localOffset(0, parameterFootprint)); + break; + + case aload_1: + case iload_1: + case fload_1: + push(rbp, localOffset(1, parameterFootprint)); + break; + + case aload_2: + case iload_2: + case fload_2: + push(rbp, localOffset(2, parameterFootprint)); + break; + + case aload_3: + case iload_3: + case fload_3: + push(rbp, localOffset(3, parameterFootprint)); + break; + case areturn: pop(rax); mov(rbp, rsp); @@ -531,6 +825,36 @@ class Compiler: public Assembler { ret(); break; + case astore: + case istore: + case fstore: + pop(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint)); + break; + + case astore_0: + case istore_0: + case fstore_0: + pop(rbp, localOffset(0, parameterFootprint)); + break; + + case astore_1: + case istore_1: + case fstore_1: + pop(rbp, localOffset(1, parameterFootprint)); + break; + + case astore_2: + case istore_2: + case fstore_2: + pop(rbp, localOffset(2, parameterFootprint)); + break; + + case astore_3: + case istore_3: + case fstore_3: + pop(rbp, localOffset(3, parameterFootprint)); + break; + case bipush: { push(static_cast(codeBody(t, code, ip++))); } break; @@ -565,7 +889,7 @@ class Compiler: public Assembler { Label next(this); cmp(0, rax); - je(zero); + jz(zero); push4(rax, IntValue); jmp(next); @@ -582,7 +906,7 @@ class Compiler: public Assembler { Label next(this); cmp(0, rax); - je(zero); + jz(zero); push4(rax, LongValue); push4(rax, LongValue + 4); @@ -638,35 +962,13 @@ class Compiler: public Assembler { push(5); break; - case aload: - case iload: - case fload: - push(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint)); - break; - - case aload_0: - case iload_0: - case fload_0: - push(rbp, localOffset(0, parameterFootprint)); - break; - - case aload_1: - case iload_1: - case fload_1: - push(rbp, localOffset(1, parameterFootprint)); - break; - - case aload_2: - case iload_2: - case fload_2: - push(rbp, localOffset(2, parameterFootprint)); - break; - - case aload_3: - case iload_3: - case fload_3: - push(rbp, localOffset(3, parameterFootprint)); - break; + case ifnull: { + int16_t offset = codeReadInt16(t, code, ip); + + pop(rax); + cmp(0, rax); + jz((ip - 3) + offset); + } break; case invokespecial: { uint16_t index = codeReadInt16(t, code, ip); @@ -728,36 +1030,6 @@ class Compiler: public Assembler { pushReturnValue(t, methodReturnCode(t, method)); } break; - case astore: - case istore: - case fstore: - pop(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint)); - break; - - case astore_0: - case istore_0: - case fstore_0: - pop(rbp, localOffset(0, parameterFootprint)); - break; - - case astore_1: - case istore_1: - case fstore_1: - pop(rbp, localOffset(1, parameterFootprint)); - break; - - case astore_2: - case istore_2: - case fstore_2: - pop(rbp, localOffset(2, parameterFootprint)); - break; - - case astore_3: - case istore_3: - case fstore_3: - pop(rbp, localOffset(3, parameterFootprint)); - break; - case ldc: case ldc_w: { uint16_t index; @@ -870,6 +1142,31 @@ class Compiler: public Assembler { abort(t); } } + + resolveJumps(); + } + + void resolveJumps() { + for (unsigned i = 0; i < jumps.length(); i += 8) { + uint32_t ip = jumps.get4(i); + uint32_t offset = jumps.get4(i + 4); + + unsigned bottom = 0; + unsigned top = javaIPs.length() / 2; + for (unsigned span = top - bottom; span; span = top - bottom) { + unsigned middle = bottom + (span / 2); + uint32_t k = javaIPs.get2(middle * 2); + + if (ip < k) { + top = middle; + } else if (ip > k) { + bottom = middle + 1; + } else { + code.set4(offset, machineIPs.get4(middle * 4) - (offset + 4)); + break; + } + } + } } void compileStub(MyThread* t) { @@ -906,6 +1203,9 @@ class Compiler: public Assembler { add(CompiledBody, rax); jmp(rax); // call compiled code } + + Buffer javaIPs; + Buffer machineIPs; }; void @@ -937,13 +1237,13 @@ updateCaller(MyThread* t, object method) (&compiledBody(t, t->m->processor->methodStub(t), 0)); Assembler a(t->m->system); - a.mov(stub, Assembler::rax); + a.mov(stub, rax); unsigned offset = a.code.length() - BytesPerWord; - a.call(Assembler::rax); + a.call(rax); uint8_t* caller = static_cast(t->frame)[1] - a.code.length(); - if (memcmp(a.code.front->data, caller, a.code.length()) == 0) { + if (memcmp(a.code.data, caller, a.code.length()) == 0) { // it's a direct call - update caller to point to new code // address must be aligned on a word boundary for this write to @@ -1272,6 +1572,7 @@ class MyProcessor: public Processor { if (classVmFlags(t, c) & NeedInitFlag and (classVmFlags(t, c) & InitFlag) == 0) { + classVmFlags(t, c) |= InitFlag; invoke(t, classInitializer(t, c), 0); if (t->exception) { t->exception = makeExceptionInInitializerError(t, t->exception); diff --git a/src/interpret.cpp b/src/interpret.cpp index 10f43551ad..98a47366e5 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -442,26 +442,18 @@ resolveNativeMethodData(Thread* t, object method) if (objectClass(t, methodCode(t, method)) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { - object data = 0; - for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { - void* p = lib->resolve(reinterpret_cast - (&byteArrayBody(t, methodCode(t, method), 0))); - if (p) { - PROTECT(t, method); - data = makeNativeMethodData(t, method, p); - break; - } - } - - if (LIKELY(data)) { + void* p = resolveNativeMethod(t, method); + if (LIKELY(p)) { + PROTECT(t, method); + object data = makeNativeMethodData(t, method, p); set(t, methodCode(t, method), data); + return data; } else { object message = makeString (t, "%s", &byteArrayBody(t, methodCode(t, method), 0)); t->exception = makeUnsatisfiedLinkError(t, message); + return 0; } - - return data; } else { return methodCode(t, method); } @@ -1526,170 +1518,154 @@ interpret(Thread* t) } goto loop; case if_acmpeq: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); object b = popObject(t); object a = popObject(t); if (a == b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset); } } goto loop; case if_acmpne: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); object b = popObject(t); object a = popObject(t); if (a != b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmpeq: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a == b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmpne: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a != b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmpgt: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a > b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmpge: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a >= b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmplt: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a < b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case if_icmple: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); int32_t b = popInt(t); int32_t a = popInt(t); if (a <= b) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifeq: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (popInt(t) == 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifne: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (popInt(t)) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifgt: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (static_cast(popInt(t)) > 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifge: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (static_cast(popInt(t)) >= 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case iflt: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (static_cast(popInt(t)) < 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifle: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (static_cast(popInt(t)) <= 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifnonnull: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (popObject(t)) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; case ifnull: { - uint8_t offset1 = codeBody(t, code, ip++); - uint8_t offset2 = codeBody(t, code, ip++); + int16_t offset = codeReadInt16(t, code, ip); if (popObject(t) == 0) { - ip = (ip - 3) + static_cast(((offset1 << 8) | offset2)); + ip = (ip - 3) + offset; } } goto loop; @@ -2956,7 +2932,7 @@ class MyProcessor: public Processor { and (classVmFlags(t, c) & InitFlag) == 0) { classVmFlags(t, c) |= InitFlag; - t->m->processor->invoke(t, classInitializer(t, c), 0); + invoke(t, classInitializer(t, c), 0); } else { release(t, t->m->classLock); } diff --git a/src/machine.cpp b/src/machine.cpp index 69ff225287..272f31eec0 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -881,38 +881,13 @@ scanMethodSpec(Thread* t, const char* s, unsigned* parameterCount, unsigned* returnCode) { unsigned count = 0; - ++ s; // skip '(' - while (*s and *s != ')') { - switch (*s) { - case 'L': - while (*s and *s != ';') ++ s; - ++ s; - break; - - case '[': - while (*s == '[') ++ s; - switch (*s) { - case 'L': - while (*s and *s != ';') ++ s; - ++ s; - break; - - default: - ++ s; - break; - } - break; - - default: - ++ s; - break; - } - + MethodSpecIterator it(t, s); + for (; it.hasNext(); it.next()) { ++ count; } *parameterCount = count; - *returnCode = fieldCode(t, s[1]); + *returnCode = fieldCode(t, *it.returnSpec()); } void diff --git a/src/machine.h b/src/machine.h index fd411b6f85..1bf0900852 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1839,6 +1839,58 @@ listAppend(Thread* t, object list, object value); object vectorAppend(Thread* t, object vector, object value); +class MethodSpecIterator { + public: + MethodSpecIterator(Thread* t, const char* s): + t(t), s(s + 1) + { } + + const char* next() { + assert(t, *s != ')'); + + const char* p = s; + + switch (*s) { + case 'L': + while (*s and *s != ';') ++ s; + ++ s; + break; + + case '[': + while (*s == '[') ++ s; + switch (*s) { + case 'L': + while (*s and *s != ';') ++ s; + ++ s; + break; + + default: + ++ s; + break; + } + break; + + default: + ++ s; + break; + } + + return p; + } + + bool hasNext() { + return *s != ')'; + } + + const char* returnSpec() { + assert(t, *s == ')'); + return s + 1; + } + + Thread* t; + const char* s; +}; + unsigned fieldCode(Thread* t, unsigned javaCode); diff --git a/src/process.h b/src/process.h index e56fb3e65d..547f452ab9 100644 --- a/src/process.h +++ b/src/process.h @@ -132,6 +132,19 @@ methodVirtual(Thread* t, object method) == 0; } +inline void* +resolveNativeMethod(Thread* t, object method) +{ + for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { + void* p = lib->resolve(reinterpret_cast + (&byteArrayBody(t, methodCode(t, method), 0))); + if (p) { + return p; + } + } + return 0; +} + } // namespace vm #endif//PROCESS_H diff --git a/test/Instructions.java b/test/Instructions.java index 63401eefcb..ff99203834 100644 --- a/test/Instructions.java +++ b/test/Instructions.java @@ -20,9 +20,10 @@ public class Instructions { int c = a + b; Instructions i = new Instructions(); - i.foo("hello"); - i.bar("hello"); - baz("hello"); + String s = "hello"; + i.foo(s); + i.bar(s); + baz(s); int d = alpha; beta = 42;