From 50dae3067dec0250e9264595997b3aaa67ddd055 Mon Sep 17 00:00:00 2001 From: jet Date: Fri, 30 Oct 2009 15:04:15 -0600 Subject: [PATCH 01/15] modified binaryToObject to support ARM --- src/binaryToObject/elf.cpp | 3 +++ src/binaryToObject/main.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/binaryToObject/elf.cpp b/src/binaryToObject/elf.cpp index 81d90616eb..8a6c2417d1 100644 --- a/src/binaryToObject/elf.cpp +++ b/src/binaryToObject/elf.cpp @@ -42,6 +42,7 @@ #define EM_386 3 #define EM_X86_64 62 +#define EM_ARM 40 #define SHT_PROGBITS 1 #define SHT_SYMTAB 2 @@ -352,6 +353,8 @@ MAKE_NAME(writeElf, BITS_PER_WORD, Object) machine = EM_X86_64; } else if (strcmp(architecture, "i386") == 0) { machine = EM_386; + } else if (strcmp(architecture, "arm") == 0) { + machine = EM_ARM; } else { fprintf(stderr, "unsupported architecture: %s\n", architecture); return false; diff --git a/src/binaryToObject/main.cpp b/src/binaryToObject/main.cpp index 0200dd4123..a6fcbd6cce 100644 --- a/src/binaryToObject/main.cpp +++ b/src/binaryToObject/main.cpp @@ -69,7 +69,8 @@ writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName, success = writeElf64Object (data, size, out, startName, endName, architecture, alignment, writable, executable); - } else if (strcmp("i386", architecture) == 0) { + } else if (strcmp("i386", architecture) == 0 || + strcmp("arm", architecture) == 0) { found = true; success = writeElf32Object (data, size, out, startName, endName, architecture, alignment, From b2f5e71d229eebc2b865b80a885707ce4c0d3712 Mon Sep 17 00:00:00 2001 From: JET Date: Wed, 14 Apr 2010 09:26:50 -0600 Subject: [PATCH 02/15] ARM and UTF-8 work --- classpath/avian/Utf8.java | 100 ++++++ classpath/java/io/InputStreamReader.java | 14 +- classpath/java/io/OutputStreamWriter.java | 8 +- classpath/java/lang/String.java | 87 +---- src/arm.h | 19 +- src/interpret.cpp | 24 -- src/jnienv.cpp | 1 - src/powerpc.cpp | 376 ++++++++++------------ 8 files changed, 305 insertions(+), 324 deletions(-) create mode 100644 classpath/avian/Utf8.java diff --git a/classpath/avian/Utf8.java b/classpath/avian/Utf8.java new file mode 100644 index 0000000000..84c4c28058 --- /dev/null +++ b/classpath/avian/Utf8.java @@ -0,0 +1,100 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package avian; + +import java.io.ByteArrayOutputStream; + +public class Utf8 { + public static boolean test(Object data) { + if (!(data instanceof byte[])) return false; + byte[] b = (byte[])data; + for (int i = 0; i < b.length; ++i) { + if (((int)b[i] & 0x080) != 0) return true; + } + return false; + } + + public static byte[] encode(char[] s16, int offset, int length) { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + for (int i = offset; i < offset+length; ++i) { + char c = s16[i]; + if (c == '\u0000') { // null char + buf.write(0); + buf.write(0); + } else if (c < 0x080) { // 1 byte char + buf.write(c); + } else if (c < 0x0800) { // 2 byte char + buf.write(0x0c0 | (c >>> 6)); + buf.write(0x080 | (c & 0x03f)); + } else { // 3 byte char + buf.write(0x0e0 | ((c >>> 12) & 0x0f)); + buf.write(0x080 | ((c >>> 6) & 0x03f)); + buf.write(0x080 | (c & 0x03f)); + } + } + return buf.toByteArray(); + } + + public static Object decode(byte[] s8, int offset, int length) { + Object buf = new byte[length]; + boolean isMultiByte = false; + int i=offset, j=0; + while (i < offset+length) { + int x = s8[i++]; + if ((x & 0x080) == 0x0) { // 1 byte char + if (x == 0) ++i; // 2 byte null char + cram(buf, j++, x); + } else if ((x & 0x0e0) == 0x0c0) { // 2 byte char + if (!isMultiByte) { + buf = widen(buf, j, length-1); + isMultiByte = true; + } + int y = s8[i++]; + cram(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f)); + } else if ((x & 0x0f0) == 0x0e0) { // 3 byte char + if (!isMultiByte) { + buf = widen(buf, j, length-2); + isMultiByte = true; + } + int y = s8[i++]; int z = s8[i++]; + cram(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f)); + } + } + + return trim(buf, j); + } + + public static char[] decode16(byte[] s8, int offset, int length) { + Object decoded = decode(s8, offset, length); + if (decoded instanceof char[]) return (char[])decoded; + return (char[])widen(decoded, length, length); + } + + private static void cram(Object data, int index, int val) { + if (data instanceof byte[]) ((byte[])data)[index] = (byte)val; + else ((char[])data)[index] = (char)val; + } + + private static Object widen(Object data, int length, int capacity) { + byte[] src = (byte[])data; + char[] result = new char[capacity]; + for (int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff); + return result; + } + + private static Object trim(Object data, int length) { + if (data instanceof byte[]) return data; + if (((char[])data).length == length) return data; + char[] result = new char[length]; + System.arraycopy(data, 0, result, 0, length); + return result; + } +} diff --git a/classpath/java/io/InputStreamReader.java b/classpath/java/io/InputStreamReader.java index b83b18c18b..3da80e2189 100644 --- a/classpath/java/io/InputStreamReader.java +++ b/classpath/java/io/InputStreamReader.java @@ -10,6 +10,8 @@ package java.io; +import avian.Utf8; + public class InputStreamReader extends Reader { private final InputStream in; @@ -31,10 +33,16 @@ public class InputStreamReader extends Reader { public int read(char[] b, int offset, int length) throws IOException { byte[] buffer = new byte[length]; int c = in.read(buffer); - for (int i = 0; i < c; ++i) { - b[i + offset] = (char) buffer[i]; + + if (c <= 0) return c; + + char[] buffer16 = Utf8.decode16(buffer, 0, c); + + for (int i = 0; i < buffer16.length; ++i) { + b[i + offset] = buffer16[i]; } - return c; + + return buffer16.length; } public void close() throws IOException { diff --git a/classpath/java/io/OutputStreamWriter.java b/classpath/java/io/OutputStreamWriter.java index ed63ad68e6..1c94a774ac 100644 --- a/classpath/java/io/OutputStreamWriter.java +++ b/classpath/java/io/OutputStreamWriter.java @@ -10,6 +10,8 @@ package java.io; +import avian.Utf8; + public class OutputStreamWriter extends Writer { private final OutputStream out; @@ -18,11 +20,7 @@ public class OutputStreamWriter extends Writer { } public void write(char[] b, int offset, int length) throws IOException { - byte[] buffer = new byte[length]; - for (int i = 0; i < length; ++i) { - buffer[i] = (byte) b[i + offset]; - } - out.write(buffer); + out.write(Utf8.encode(b, offset, length)); } public void flush() throws IOException { diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index 01b66605f1..143c60fd72 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -15,8 +15,8 @@ import java.util.regex.Pattern; import java.util.Comparator; import java.util.Formatter; import java.util.Locale; -import java.io.ByteArrayOutputStream; import java.io.Serializable; +import avian.Utf8; public final class String implements Comparable, CharSequence, Serializable @@ -112,7 +112,7 @@ public final class String (offset + " < 0 or " + offset + " + " + length + " > " + l); } - if(!copy && isUTF8(data)) copy = true; + if(!copy && Utf8.test(data)) copy = true; if (copy) { Object c; @@ -120,7 +120,7 @@ public final class String c = new char[length]; System.arraycopy(data, offset, c, 0, length); } else { - c = decodeUTF8((byte[])data, offset, length); + c = Utf8.decode((byte[])data, offset, length); if(c instanceof char[]) length = ((char[])c).length; } @@ -134,85 +134,6 @@ public final class String } } - private static boolean isUTF8(Object data) { - if(!(data instanceof byte[])) return false; - byte[] b = (byte[])data; - for(int i = 0; i < b.length; ++i) { - if(((int)b[i] & 0x080) != 0) return true; - } - return false; - } - - private static byte[] encodeUTF8(char[] s16, int offset, int length) { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - for(int i = offset; i < offset+length; ++i) { - char c = s16[i]; - if(c == '\u0000') { // null char - buf.write(0); - buf.write(0); - } else if(c < 0x080) { // 1 byte char - buf.write(c); - } else if(c < 0x0800) { // 2 byte char - buf.write(0x0c0 | (c >>> 6)); - buf.write(0x080 | (c & 0x03f)); - } else { // 3 byte char - buf.write(0x0e0 | ((c >>> 12) & 0x0f)); - buf.write(0x080 | ((c >>> 6) & 0x03f)); - buf.write(0x080 | (c & 0x03f)); - } - } - return buf.toByteArray(); - } - - private static void decodeUTF8_insert(Object data, int index, int val) { - if(data instanceof byte[]) ((byte[])data)[index] = (byte)val; - else ((char[])data)[index] = (char)val; - } - - private static Object decodeUTF8_widen(Object data, int length, int capacity) { - byte[] src = (byte[])data; - char[] result = new char[capacity]; - for(int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff); - return result; - } - - private static Object decodeUTF8_trim(Object data, int length) { - if(data instanceof byte[]) return data; - if(((char[])data).length == length) return data; - char[] result = new char[length]; - System.arraycopy(data, 0, result, 0, length); - return result; - } - - private static Object decodeUTF8(byte[] s8, int offset, int length) { - Object buf = new byte[length]; - boolean isMultiByte = false; - int i=offset, j=0; - while(i < offset+length) { - int x = s8[i++]; - if((x & 0x080) == 0x0) { // 1 byte char - if(x == 0) ++i; // 2 byte null char - decodeUTF8_insert(buf, j++, x); - } else if((x & 0x0e0) == 0x0c0) { // 2 byte char - if(!isMultiByte) { - buf = decodeUTF8_widen(buf, j, length-1); - isMultiByte = true; - } - int y = s8[i++]; - decodeUTF8_insert(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f)); - } else if((x & 0x0f0) == 0x0e0) { // 3 byte char - if(!isMultiByte) { - buf = decodeUTF8_widen(buf, j, length-2); - isMultiByte = true; - } - int y = s8[i++]; int z = s8[i++]; - decodeUTF8_insert(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f)); - } - } - - return decodeUTF8_trim(buf, j); - } - public String toString() { return this; } @@ -494,7 +415,7 @@ public final class String getBytes(0, length, b, 0); return b; } - return encodeUTF8((char[])data, offset, length); + return Utf8.encode((char[])data, offset, length); } public byte[] getBytes(String format) diff --git a/src/arm.h b/src/arm.h index f17fa596be..ad08714d91 100644 --- a/src/arm.h +++ b/src/arm.h @@ -69,7 +69,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, uintptr_t gprTable[GprCount]; unsigned gprIndex = 0; - uintptr_t stack[argumentsSize / BytesPerWord]; + uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding unsigned stackIndex = 0; unsigned ai = 0; @@ -77,15 +77,18 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, switch (argumentTypes[ati]) { case DOUBLE_TYPE: case INT64_TYPE: { - if (gprIndex + (8 / BytesPerWord) <= GprCount) { + if (gprIndex + (8 / BytesPerWord) <= GprCount) { // pass argument on registers + if (gprIndex & 1) { // 8-byte alignment + memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck + ++gprIndex; + } memcpy(gprTable + gprIndex, arguments + ai, 8); gprIndex += 8 / BytesPerWord; - } else if (gprIndex == GprCount-1) { // split between last GPR and stack - memcpy(gprTable + gprIndex, arguments + ai, 4); - ++gprIndex; - memcpy(stack + stackIndex, arguments + ai + 4, 4); - ++stackIndex; - } else { + } else { // pass argument on stack + if (stackIndex & 1) { // 8-byte alignment + memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck + ++stackIndex; + } memcpy(stack + stackIndex, arguments + ai, 8); stackIndex += 8 / BytesPerWord; } diff --git a/src/interpret.cpp b/src/interpret.cpp index 6c0d5e4df8..3ca09f7780 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -118,9 +118,6 @@ inline void pushDouble(Thread* t, double v) { uint64_t w = doubleToBits(v); -#ifdef __arm__ - w = w << 32 | w >> 32; -#endif pushLong(t, w); } @@ -175,9 +172,6 @@ inline double popDouble(Thread* t) { uint64_t v = popLong(t); -#ifdef __arm__ - v = v << 32 | v >> 32; -#endif return bitsToDouble(v); } @@ -569,15 +563,6 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect) break; case DoubleField: -#ifdef __arm__ - result = result << 32 | result >> 32; - if (DebugRun) { - fprintf(stderr, "result: %"LLD"\n", result); - } - pushLong(t, result); - break; -#endif - case LongField: if (DebugRun) { fprintf(stderr, "result: %"LLD"\n", result); @@ -629,15 +614,6 @@ marshalArguments(Thread* t, uintptr_t* args, unsigned i, unsigned count, break; case DOUBLE_TYPE: -#ifdef __arm__ - { - uint64_t v = peekLong(t, sp); - v = v << 32 | v >> 32; - memcpy(args + offset, &v, 8); - offset += (8 / BytesPerWord); - sp += 2; - } break; -#endif case INT64_TYPE: { uint64_t v = peekLong(t, sp); memcpy(args + offset, &v, 8); diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 1ab4fe6a26..f16360aecf 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -13,7 +13,6 @@ #include "util.h" #include "processor.h" #include "constants.h" -#include "processor.h" using namespace vm; diff --git a/src/powerpc.cpp b/src/powerpc.cpp index 9cec9a1cdd..391970d755 100644 --- a/src/powerpc.cpp +++ b/src/powerpc.cpp @@ -20,29 +20,6 @@ using namespace vm; namespace { -namespace field { -// BITFIELD MASKS -const int64_t MASK_LO32 = 0x0ffffffff; -const int MASK_LO16 = 0x0ffff; -const int MASK_LO8 = 0x0ff; -// BITFIELD EXTRACTORS -inline int lo32(int64_t i) { return (int)(i & MASK_LO32); } -inline int hi32(int64_t i) { return lo32(i >> 32); } -inline int lo16(int64_t i) { return (int)(i & MASK_LO16); } -inline int hi16(int64_t i) { return lo16(i >> 16); } -inline int lo8(int64_t i) { return (int)(i & MASK_LO8); } -inline int hi8(int64_t i) { return lo8(i >> 8); } - -inline int ha16(int32_t i) { - return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff; -} - -inline int unha16(int32_t high, int32_t low) { - return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low; -} - -} - namespace isa { // INSTRUCTION FORMATS inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); } @@ -155,6 +132,24 @@ inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); } inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); } } +const int64_t MASK_LO32 = 0x0ffffffff; +const int MASK_LO16 = 0x0ffff; +const int MASK_LO8 = 0x0ff; +inline int lo32(int64_t i) { return (int)(i & MASK_LO32); } +inline int hi32(int64_t i) { return lo32(i >> 32); } +inline int lo16(int64_t i) { return (int)(i & MASK_LO16); } +inline int hi16(int64_t i) { return lo16(i >> 16); } +inline int lo8(int64_t i) { return (int)(i & MASK_LO8); } +inline int hi8(int64_t i) { return lo8(i >> 8); } + +inline int ha16(int32_t i) { + return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff; +} + +inline int unha16(int32_t high, int32_t low) { + return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low; +} + inline bool isInt16(intptr_t v) { @@ -445,100 +440,94 @@ branchIndex(ArchitectureContext* c UNUSED, OperandType operand1, // BEGIN OPERATION COMPILERS -using namespace field; using namespace isa; -typedef Assembler::Register Reg; -typedef Assembler::Constant Const; - -inline void issue(Context* con, int code) { con->code.append4(code); } -inline int getTemp(Context* con) { return con->client->acquireTemporary(); } +inline void emit(Context* con, int code) { con->code.append4(code); } +inline int newTemp(Context* con) { return con->client->acquireTemporary(); } inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); } -inline int64_t getVal(Const* c) { return c->value->value(); } -inline int R(Reg* r) { return r->low; } -inline int H(Reg* r) { return r->high; } +inline int64_t getValue(Assembler::Constant* c) { return c->value->value(); } -void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) +void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { if(size == 8) { - Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp; - issue(con, subfic(H(tmp), R(a), 32)); - issue(con, slw(H(t), H(b), R(a))); - issue(con, srw(R(tmp), R(b), H(tmp))); - issue(con, or_(H(t), H(t), R(tmp))); - issue(con, addi(H(tmp), R(a), -32)); - issue(con, slw(R(tmp), R(b), H(tmp))); - issue(con, or_(H(t), H(t), R(tmp))); - freeTemp(con, H(tmp)); freeTemp(con, R(tmp)); + Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + emit(con, subfic(tmp->high, a->low, 32)); + emit(con, slw(t->high, b->high, a->low)); + emit(con, srw(tmp->low, b->low, tmp->high)); + emit(con, or_(t->high, t->high, tmp->low)); + emit(con, addi(tmp->high, a->low, -32)); + emit(con, slw(tmp->low, b->low, tmp->high)); + emit(con, or_(t->high, t->high, tmp->low)); + freeTemp(con, tmp->high); freeTemp(con, tmp->low); } - issue(con, slw(R(t), R(b), R(a))); + emit(con, slw(t->low, b->low, a->low)); } -void shiftLeftC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) +void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { - int sh = getVal(a); + int sh = getValue(a); if (size == 8) { if (sh < 32) { - issue(con, rlwinm(H(t),H(b),sh,0,31-sh)); - issue(con, rlwimi(H(t),R(b),sh,32-sh,31)); + emit(con, rlwinm(t->high,b->high,sh,0,31-sh)); + emit(con, rlwimi(t->high,b->low,sh,32-sh,31)); } else { - issue(con, rlwinm(H(t),R(b),sh-32,0,63-sh)); - issue(con, li(R(t),0)); + emit(con, rlwinm(t->high,b->low,sh-32,0,63-sh)); + emit(con, li(t->low,0)); } } - issue(con, slwi(R(t), R(b), sh)); + emit(con, slwi(t->low, b->low, sh)); } -void shiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) +void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { if(size == 8) { - Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp; - issue(con, subfic(H(tmp), R(a), 32)); - issue(con, srw(R(t), R(b), R(a))); - issue(con, slw(R(tmp), H(b), H(tmp))); - issue(con, or_(R(t), R(t), R(tmp))); - issue(con, addic(H(tmp), R(a), -32)); - issue(con, sraw(R(tmp), H(b), H(tmp))); - issue(con, ble(8)); - issue(con, ori(R(t), R(tmp), 0)); - issue(con, sraw(H(t), H(b), R(a))); - freeTemp(con, H(tmp)); freeTemp(con, R(tmp)); + Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + emit(con, subfic(tmp->high, a->low, 32)); + emit(con, srw(t->low, b->low, a->low)); + emit(con, slw(tmp->low, b->high, tmp->high)); + emit(con, or_(t->low, t->low, tmp->low)); + emit(con, addic(tmp->high, a->low, -32)); + emit(con, sraw(tmp->low, b->high, tmp->high)); + emit(con, ble(8)); + emit(con, ori(t->low, tmp->low, 0)); + emit(con, sraw(t->high, b->high, a->low)); + freeTemp(con, tmp->high); freeTemp(con, tmp->low); } else { - issue(con, sraw(R(t), R(b), R(a))); + emit(con, sraw(t->low, b->low, a->low)); } } -void shiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) +void shiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { - int sh = getVal(a); + int sh = getValue(a); if(size == 8) { if (sh < 32) { - issue(con, rlwinm(R(t),R(b),32-sh,sh,31)); - issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1)); - issue(con, srawi(H(t),H(b),sh)); + emit(con, rlwinm(t->low,b->low,32-sh,sh,31)); + emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1)); + emit(con, srawi(t->high,b->high,sh)); } else { - issue(con, srawi(H(t),H(b),31)); - issue(con, srawi(R(t),H(b),sh-32)); + emit(con, srawi(t->high,b->high,31)); + emit(con, srawi(t->low,b->high,sh-32)); } } else { - issue(con, srawi(R(t), R(b), sh)); + emit(con, srawi(t->low, b->low, sh)); } } -void unsignedShiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) +void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { - issue(con, srw(R(t), R(b), R(a))); + emit(con, srw(t->low, b->low, a->low)); if(size == 8) { - Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp; - issue(con, subfic(H(tmp), R(a), 32)); - issue(con, slw(R(tmp), H(b), H(tmp))); - issue(con, or_(R(t), R(t), R(tmp))); - issue(con, addi(H(tmp), R(a), -32)); - issue(con, srw(R(tmp), H(b), H(tmp))); - issue(con, or_(R(t), R(t), R(tmp))); - issue(con, srw(H(t), H(b), R(a))); - freeTemp(con, H(tmp)); freeTemp(con, R(tmp)); + Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + emit(con, subfic(tmp->high, a->low, 32)); + emit(con, slw(tmp->low, b->high, tmp->high)); + emit(con, or_(t->low, t->low, tmp->low)); + emit(con, addi(tmp->high, a->low, -32)); + emit(con, srw(tmp->low, b->high, tmp->high)); + emit(con, or_(t->low, t->low, tmp->low)); + emit(con, srw(t->high, b->high, a->low)); + freeTemp(con, tmp->high); freeTemp(con, tmp->low); } } @@ -546,24 +535,24 @@ void moveRR(Context* c, unsigned srcSize, Assembler::Register* src, unsigned dstSize, Assembler::Register* dst); -void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) +void unsignedShiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { - int sh = getVal(a); + int sh = getValue(a); if (size == 8) { if (sh == 32) { Assembler::Register high(b->high); moveRR(con, 4, &high, 4, t); - issue(con, li(H(t),0)); + emit(con, li(t->high,0)); } else if (sh < 32) { - issue(con, srwi(R(t), R(b), sh)); - issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1)); - issue(con, rlwinm(H(t),H(b),32-sh,sh,31)); + emit(con, srwi(t->low, b->low, sh)); + emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1)); + emit(con, rlwinm(t->high,b->high,32-sh,sh,31)); } else { - issue(con, rlwinm(R(t),H(b),64-sh,sh-32,31)); - issue(con, li(H(t),0)); + emit(con, rlwinm(t->low,b->high,64-sh,sh-32,31)); + emit(con, li(t->high,0)); } } else { - issue(con, srwi(R(t), R(b), sh)); + emit(con, srwi(t->low, b->low, sh)); } } @@ -683,8 +672,8 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target) { assert(c, size == BytesPerWord); - issue(c, mtctr(target->low)); - issue(c, bctr()); + emit(c, mtctr(target->low)); + emit(c, bctr()); } void @@ -707,18 +696,18 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src, { switch (srcSize) { case 1: - issue(c, extsb(dst->low, src->low)); + emit(c, extsb(dst->low, src->low)); break; case 2: - issue(c, extsh(dst->low, src->low)); + emit(c, extsh(dst->low, src->low)); break; case 4: case 8: if (srcSize == 4 and dstSize == 8) { moveRR(c, 4, src, 4, dst); - issue(c, srawi(dst->high, src->low, 31)); + emit(c, srawi(dst->high, src->low, 31)); } else if (srcSize == 8 and dstSize == 8) { Assembler::Register srcHigh(src->high); Assembler::Register dstHigh(dst->high); @@ -735,7 +724,7 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src, moveRR(c, 4, &srcHigh, 4, &dstHigh); } } else if (src->low != dst->low) { - issue(c, mr(dst->low, src->low)); + emit(c, mr(dst->low, src->low)); } break; @@ -749,7 +738,7 @@ moveZRR(Context* c, unsigned srcSize, Assembler::Register* src, { switch (srcSize) { case 2: - issue(c, andi(dst->low, src->low, 0xFFFF)); + emit(c, andi(dst->low, src->low, 0xFFFF)); break; default: abort(c); @@ -764,16 +753,16 @@ moveCR2(Context* c, unsigned, Assembler::Constant* src, if (src->value->resolved()) { int32_t v = src->value->value(); if (isInt16(v)) { - issue(c, li(dst->low, v)); + emit(c, li(dst->low, v)); } else { - issue(c, lis(dst->low, v >> 16)); - issue(c, ori(dst->low, dst->low, v)); + emit(c, lis(dst->low, v >> 16)); + emit(c, ori(dst->low, dst->low, v)); } } else { appendImmediateTask (c, src->value, offset(c), BytesPerWord, promiseOffset, false); - issue(c, lis(dst->low, 0)); - issue(c, ori(dst->low, dst->low, 0)); + emit(c, lis(dst->low, 0)); + emit(c, ori(dst->low, dst->low, 0)); } } else { abort(c); // todo @@ -787,38 +776,38 @@ moveCR(Context* c, unsigned srcSize, Assembler::Constant* src, moveCR2(c, srcSize, src, dstSize, dst, 0); } -void addR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) { +void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { if(size == 8) { - issue(con, addc(R(t), R(a), R(b))); - issue(con, adde(H(t), H(a), H(b))); + emit(con, addc(t->low, a->low, b->low)); + emit(con, adde(t->high, a->high, b->high)); } else { - issue(con, add(R(t), R(a), R(b))); + emit(con, add(t->low, a->low, b->low)); } } -void addC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) { +void addC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { assert(con, size == BytesPerWord); - int32_t i = getVal(a); + int32_t i = getValue(a); if(i) { - issue(con, addi(R(t), R(b), lo16(i))); + emit(con, addi(t->low, b->low, lo16(i))); if(not isInt16(i)) - issue(con, addis(R(t), R(t), hi16(i) + carry16(i))); + emit(con, addis(t->low, t->low, hi16(i) + carry16(i))); } else { moveRR(con, size, b, size, t); } } -void subR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) { +void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { if(size == 8) { - issue(con, subfc(R(t), R(a), R(b))); - issue(con, subfe(H(t), H(a), H(b))); + emit(con, subfc(t->low, a->low, b->low)); + emit(con, subfe(t->high, a->high, b->high)); } else { - issue(con, subf(R(t), R(a), R(b))); + emit(con, subf(t->low, a->low, b->low)); } } -void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) { +void subC(Context* c, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { assert(c, size == BytesPerWord); ResolvedPromise promise(- a->value->value()); @@ -826,7 +815,7 @@ void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) { addC(c, size, &constant, b, t); } -void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) { +void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { if(size == 8) { bool useTemporaries = b->low == t->low; int tmpLow; @@ -839,28 +828,28 @@ void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) { tmpHigh = t->high; } - issue(con, mullw(tmpHigh, H(a), R(b))); - issue(con, mullw(tmpLow, R(a), H(b))); - issue(con, add(H(t), tmpHigh, tmpLow)); - issue(con, mulhwu(tmpLow, R(a), R(b))); - issue(con, add(H(t), H(t), tmpLow)); - issue(con, mullw(R(t), R(a), R(b))); + emit(con, mullw(tmpHigh, a->high, b->low)); + emit(con, mullw(tmpLow, a->low, b->high)); + emit(con, add(t->high, tmpHigh, tmpLow)); + emit(con, mulhwu(tmpLow, a->low, b->low)); + emit(con, add(t->high, t->high, tmpLow)); + emit(con, mullw(t->low, a->low, b->low)); if (useTemporaries) { con->client->releaseTemporary(tmpLow); con->client->releaseTemporary(tmpHigh); } } else { - issue(con, mullw(R(t), R(a), R(b))); + emit(con, mullw(t->low, a->low, b->low)); } } -void divideR(Context* con, unsigned size UNUSED, Reg* a, Reg* b, Reg* t) { +void divideR(Context* con, unsigned size UNUSED, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { assert(con, size == 4); - issue(con, divw(R(t), R(b), R(a))); + emit(con, divw(t->low, b->low, a->low)); } -void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) { +void remainderR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { bool useTemporary = b->low == t->low; Assembler::Register tmp(t->low); if (useTemporary) { @@ -935,15 +924,15 @@ store(Context* c, unsigned size, Assembler::Register* src, switch (size) { case 1: - issue(c, stbx(src->low, base, normalized)); + emit(c, stbx(src->low, base, normalized)); break; case 2: - issue(c, sthx(src->low, base, normalized)); + emit(c, sthx(src->low, base, normalized)); break; case 4: - issue(c, stwx(src->low, base, normalized)); + emit(c, stwx(src->low, base, normalized)); break; case 8: { @@ -959,15 +948,15 @@ store(Context* c, unsigned size, Assembler::Register* src, } else { switch (size) { case 1: - issue(c, stb(src->low, base, offset)); + emit(c, stb(src->low, base, offset)); break; case 2: - issue(c, sth(src->low, base, offset)); + emit(c, sth(src->low, base, offset)); break; case 4: - issue(c, stw(src->low, base, offset)); + emit(c, stw(src->low, base, offset)); break; case 8: { @@ -998,12 +987,12 @@ moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src, assert(c, dstSize == BytesPerWord); if (dst->index == NoRegister) { - issue(c, stwu(src->low, dst->base, dst->offset)); + emit(c, stwu(src->low, dst->base, dst->offset)); } else { assert(c, dst->offset == 0); assert(c, dst->scale == 1); - issue(c, stwux(src->low, dst->base, dst->index)); + emit(c, stwux(src->low, dst->base, dst->index)); } } @@ -1019,17 +1008,17 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, switch (srcSize) { case 1: - issue(c, lbzx(dst->low, base, normalized)); + emit(c, lbzx(dst->low, base, normalized)); if (signExtend) { - issue(c, extsb(dst->low, dst->low)); + emit(c, extsb(dst->low, dst->low)); } break; case 2: if (signExtend) { - issue(c, lhax(dst->low, base, normalized)); + emit(c, lhax(dst->low, base, normalized)); } else { - issue(c, lhzx(dst->low, base, normalized)); + emit(c, lhzx(dst->low, base, normalized)); } break; @@ -1043,7 +1032,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, load(c, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false); load(c, 4, base, 4, normalized, 1, 4, dst, preserveIndex, false); } else { - issue(c, lwzx(dst->low, base, normalized)); + emit(c, lwzx(dst->low, base, normalized)); } } break; @@ -1054,22 +1043,22 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, } else { switch (srcSize) { case 1: - issue(c, lbz(dst->low, base, offset)); + emit(c, lbz(dst->low, base, offset)); if (signExtend) { - issue(c, extsb(dst->low, dst->low)); + emit(c, extsb(dst->low, dst->low)); } break; case 2: if (signExtend) { - issue(c, lha(dst->low, base, offset)); + emit(c, lha(dst->low, base, offset)); } else { - issue(c, lha(dst->low, base, offset)); + emit(c, lha(dst->low, base, offset)); } break; case 4: - issue(c, lwz(dst->low, base, offset)); + emit(c, lwz(dst->low, base, offset)); break; case 8: { @@ -1078,7 +1067,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, load(c, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false); load(c, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false); } else { - issue(c, lwzx(dst->low, base, offset)); + emit(c, lwzx(dst->low, base, offset)); } } break; @@ -1103,19 +1092,6 @@ moveZMR(Context* c, unsigned srcSize, Assembler::Memory* src, dstSize, dst, true, false); } -// void moveCR3(Context* con, unsigned aSize, Const* a, unsigned tSize, Reg* t) { -// int64_t i = getVal(a); -// if(tSize == 8) { -// int64_t j; -// if(aSize == 8) j = i; // 64-bit const -> load high bits into high register -// else j = 0; // 32-bit const -> clear high register -// issue(con, lis(H(t), hi16(hi32(j)))); -// issue(con, ori(H(t), H(t), lo16(hi32(j)))); -// } -// issue(con, lis(R(t), hi16(i))); -// issue(con, ori(R(t), R(t), lo16(i))); -// } - void andR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* dst) @@ -1128,7 +1104,7 @@ andR(Context* c, unsigned size, Assembler::Register* a, andR(c, 4, a, b, dst); andR(c, 4, &ah, &bh, &dh); } else { - issue(c, and_(dst->low, a->low, b->low)); + emit(c, and_(dst->low, a->low, b->low)); } } @@ -1181,9 +1157,9 @@ andC(Context* c, unsigned size, Assembler::Constant* a, // the topmost or bottommost 16 bits are zero. if ((v32 >> 16) == 0) { - issue(c, andi(dst->low, b->low, v32)); + emit(c, andi(dst->low, b->low, v32)); } else if ((v32 & 0xFFFF) == 0) { - issue(c, andis(dst->low, b->low, v32 >> 16)); + emit(c, andis(dst->low, b->low, v32 >> 16)); } else { bool useTemporary = b->low == dst->low; Assembler::Register tmp(dst->low); @@ -1206,12 +1182,12 @@ andC(Context* c, unsigned size, Assembler::Constant* a, if (state) { if (start != 0 or end != 31) { - issue(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start)); + emit(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start)); } else { moveRR(c, 4, b, 4, dst); } } else { - issue(c, li(dst->low, 0)); + emit(c, li(dst->low, 0)); } } } @@ -1228,7 +1204,7 @@ orR(Context* c, unsigned size, Assembler::Register* a, orR(c, 4, a, b, dst); orR(c, 4, &ah, &bh, &dh); } else { - issue(c, or_(dst->low, a->low, b->low)); + emit(c, or_(dst->low, a->low, b->low)); } } @@ -1251,9 +1227,9 @@ orC(Context* c, unsigned size, Assembler::Constant* a, orC(c, 4, &al, b, dst); orC(c, 4, &ah, &bh, &dh); } else { - issue(c, ori(b->low, dst->low, v)); + emit(c, ori(b->low, dst->low, v)); if (v >> 16) { - issue(c, oris(dst->low, dst->low, v >> 16)); + emit(c, oris(dst->low, dst->low, v >> 16)); } } } @@ -1270,7 +1246,7 @@ xorR(Context* c, unsigned size, Assembler::Register* a, xorR(c, 4, a, b, dst); xorR(c, 4, &ah, &bh, &dh); } else { - issue(c, xor_(dst->low, a->low, b->low)); + emit(c, xor_(dst->low, a->low, b->low)); } } @@ -1294,10 +1270,10 @@ xorC(Context* c, unsigned size, Assembler::Constant* a, xorC(c, 4, &ah, &bh, &dh); } else { if (v >> 16) { - issue(c, xoris(b->low, dst->low, v >> 16)); - issue(c, xori(dst->low, dst->low, v)); + emit(c, xoris(b->low, dst->low, v >> 16)); + emit(c, xori(dst->low, dst->low, v)); } else { - issue(c, xori(b->low, dst->low, v)); + emit(c, xori(b->low, dst->low, v)); } } } @@ -1313,7 +1289,7 @@ moveAR2(Context* c, unsigned srcSize UNUSED, Assembler::Address* src, appendImmediateTask (c, src->address, offset(c), BytesPerWord, promiseOffset, true); - issue(c, lis(dst->low, 0)); + emit(c, lis(dst->low, 0)); moveMR(c, dstSize, &memory, dstSize, dst); } @@ -1330,7 +1306,7 @@ compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, { assert(c, aSize == 4 and bSize == 4); - issue(c, cmpw(b->low, a->low)); + emit(c, cmpw(b->low, a->low)); } void @@ -1340,7 +1316,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, assert(c, aSize == 4 and bSize == 4); if (a->value->resolved() and isInt16(a->value->value())) { - issue(c, cmpwi(b->low, a->value->value())); + emit(c, cmpwi(b->low, a->value->value())); } else { Assembler::Register tmp(c->client->acquireTemporary()); moveCR(c, aSize, a, bSize, &tmp); @@ -1379,7 +1355,7 @@ compareUnsignedRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, { assert(c, aSize == 4 and bSize == 4); - issue(c, cmplw(b->low, a->low)); + emit(c, cmplw(b->low, a->low)); } void @@ -1389,7 +1365,7 @@ compareUnsignedCR(Context* c, unsigned aSize, Assembler::Constant* a, assert(c, aSize == 4 and bSize == 4); if (a->value->resolved() and (a->value->value() >> 16) == 0) { - issue(c, cmplwi(b->low, a->value->value())); + emit(c, cmplwi(b->low, a->value->value())); } else { Assembler::Register tmp(c->client->acquireTemporary()); moveCR(c, aSize, a, bSize, &tmp); @@ -1429,7 +1405,7 @@ void conditional(Context* c, int32_t branch, Assembler::Constant* target) { appendOffsetTask(c, target->value, offset(c), true); - issue(c, branch); + emit(c, branch); } void @@ -1452,7 +1428,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, switch (op) { case JumpIfEqual: next = c->code.length(); - issue(c, bne(0)); + emit(c, bne(0)); compareSigned(c, 4, al, 4, bl); conditional(c, beq(0), target); @@ -1469,7 +1445,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, blt(0), target); next = c->code.length(); - issue(c, bgt(0)); + emit(c, bgt(0)); compareUnsigned(c, 4, al, 4, bl); conditional(c, blt(0), target); @@ -1479,7 +1455,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, bgt(0), target); next = c->code.length(); - issue(c, blt(0)); + emit(c, blt(0)); compareUnsigned(c, 4, al, 4, bl); conditional(c, bgt(0), target); @@ -1489,7 +1465,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, blt(0), target); next = c->code.length(); - issue(c, bgt(0)); + emit(c, bgt(0)); compareUnsigned(c, 4, al, 4, bl); conditional(c, ble(0), target); @@ -1499,7 +1475,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, bgt(0), target); next = c->code.length(); - issue(c, blt(0)); + emit(c, blt(0)); compareUnsigned(c, 4, al, 4, bl); conditional(c, bge(0), target); @@ -1621,10 +1597,10 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src, if (srcSize == 8) { Assembler::Register dstHigh(dst->high); - issue(c, subfic(dst->low, src->low, 0)); - issue(c, subfze(dst->high, src->high)); + emit(c, subfic(dst->low, src->low, 0)); + emit(c, subfze(dst->high, src->high)); } else { - issue(c, neg(dst->low, src->low)); + emit(c, neg(dst->low, src->low)); } } @@ -1633,8 +1609,8 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* target) { assert(c, size == BytesPerWord); - issue(c, mtctr(target->low)); - issue(c, bctrl()); + emit(c, mtctr(target->low)); + emit(c, bctrl()); } void @@ -1643,7 +1619,7 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), false); - issue(c, bl(0)); + emit(c, bl(0)); } void @@ -1696,7 +1672,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), false); - issue(c, b(0)); + emit(c, b(0)); } void @@ -1705,7 +1681,7 @@ jumpIfEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, beq(0)); + emit(c, beq(0)); } void @@ -1714,7 +1690,7 @@ jumpIfNotEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, bne(0)); + emit(c, bne(0)); } void @@ -1723,7 +1699,7 @@ jumpIfGreaterC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, bgt(0)); + emit(c, bgt(0)); } void @@ -1733,7 +1709,7 @@ jumpIfGreaterOrEqualC(Context* c, unsigned size UNUSED, assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, bge(0)); + emit(c, bge(0)); } void @@ -1742,7 +1718,7 @@ jumpIfLessC(Context* c, unsigned size UNUSED, Assembler::Constant* target) assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, blt(0)); + emit(c, blt(0)); } void @@ -1752,19 +1728,19 @@ jumpIfLessOrEqualC(Context* c, unsigned size UNUSED, assert(c, size == BytesPerWord); appendOffsetTask(c, target->value, offset(c), true); - issue(c, ble(0)); + emit(c, ble(0)); } void return_(Context* c) { - issue(c, blr()); + emit(c, blr()); } void memoryBarrier(Context* c) { - issue(c, sync(0)); + emit(c, sync(0)); } // END OPERATION COMPILERS @@ -2268,7 +2244,7 @@ class MyAssembler: public Assembler { virtual void allocateFrame(unsigned footprint) { Register returnAddress(0); - issue(&c, mflr(returnAddress.low)); + emit(&c, mflr(returnAddress.low)); Memory returnAddressDst(StackRegister, 8); moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst); @@ -2296,7 +2272,7 @@ class MyAssembler: public Assembler { Memory returnAddressSrc(StackRegister, 8); moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress); - issue(&c, mtlr(returnAddress.low)); + emit(&c, mtlr(returnAddress.low)); } virtual void popFrameForTailCall(unsigned footprint, @@ -2310,7 +2286,7 @@ class MyAssembler: public Assembler { Memory returnAddressSrc(StackRegister, 8 + (footprint * BytesPerWord)); moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp); - issue(&c, mtlr(tmp.low)); + emit(&c, mtlr(tmp.low)); Memory stackSrc(StackRegister, footprint * BytesPerWord); moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp); From b6936fb5972c5cca39db521e1a18a1d3078527be Mon Sep 17 00:00:00 2001 From: JET Date: Wed, 14 Apr 2010 09:43:56 -0600 Subject: [PATCH 03/15] optimized InputStreamReader.read() --- classpath/java/io/InputStreamReader.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/classpath/java/io/InputStreamReader.java b/classpath/java/io/InputStreamReader.java index 3da80e2189..a2049b1b62 100644 --- a/classpath/java/io/InputStreamReader.java +++ b/classpath/java/io/InputStreamReader.java @@ -38,9 +38,7 @@ public class InputStreamReader extends Reader { char[] buffer16 = Utf8.decode16(buffer, 0, c); - for (int i = 0; i < buffer16.length; ++i) { - b[i + offset] = buffer16[i]; - } + System.arraycopy(buffer16, 0, b, offset, buffer16.length); return buffer16.length; } From e5fad036322e9b0e841a36eecc9841cd31e67e9b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 15 Apr 2010 11:11:10 -0600 Subject: [PATCH 04/15] fix MSVC build rot --- makefile | 1 + src/arch.h | 8 ++ src/jnienv.cpp | 342 +++++++++++++++++++++++++------------------------ src/x86.h | 6 +- 4 files changed, 187 insertions(+), 170 deletions(-) diff --git a/makefile b/makefile index 7685864f6b..3c3176619d 100644 --- a/makefile +++ b/makefile @@ -277,6 +277,7 @@ ifdef msvc ld = "$(msvc)/BIN/link.exe" mt = "mt.exe" cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \ + -DUSE_ATOMIC_OPERATIONS \ -Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \ -I"$(native-build)" -I"$(windows-java-home)/include" \ -I"$(windows-java-home)/include/win32" diff --git a/src/arch.h b/src/arch.h index 622e99a2fc..a49cf5078f 100644 --- a/src/arch.h +++ b/src/arch.h @@ -11,6 +11,14 @@ #ifndef ARCH_H #define ARCH_H +#ifdef _MSC_VER +# include "windows.h" +# pragma push_macro("assert") +# include "intrin.h" +# pragma pop_macro("assert") +# undef interface +#endif + #include "common.h" extern "C" void NO_RETURN diff --git a/src/jnienv.cpp b/src/jnienv.cpp index f16360aecf..86ab284829 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -18,6 +18,8 @@ using namespace vm; namespace { +namespace local { + const uintptr_t InterfaceMethodID = (static_cast(1) << (BitsPerWord - 1)); @@ -117,7 +119,7 @@ GetEnv(Machine* m, Thread** t, jint version) } } -jsize JNICALL +jint JNICALL GetVersion(Thread* t) { ENTER(t, Thread::ActiveState); @@ -1906,6 +1908,8 @@ append(char** p, const char* value, unsigned length, char tail) } } +} // namespace local + } // namespace namespace vm { @@ -1926,170 +1930,171 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable) { memset(vmTable, 0, sizeof(JavaVMVTable)); - vmTable->DestroyJavaVM = DestroyJavaVM; - vmTable->AttachCurrentThread = AttachCurrentThread; - vmTable->AttachCurrentThreadAsDaemon = AttachCurrentThreadAsDaemon; - vmTable->DetachCurrentThread = DetachCurrentThread; - vmTable->GetEnv = GetEnv; + vmTable->DestroyJavaVM = local::DestroyJavaVM; + vmTable->AttachCurrentThread = local::AttachCurrentThread; + vmTable->AttachCurrentThreadAsDaemon = local::AttachCurrentThreadAsDaemon; + vmTable->DetachCurrentThread = local::DetachCurrentThread; + vmTable->GetEnv = local::GetEnv; memset(envTable, 0, sizeof(JNIEnvVTable)); - envTable->GetVersion = ::GetVersion; - envTable->GetStringLength = ::GetStringLength; - envTable->GetStringChars = ::GetStringChars; - envTable->ReleaseStringChars = ::ReleaseStringChars; - envTable->GetStringUTFLength = ::GetStringUTFLength; - envTable->GetStringUTFChars = ::GetStringUTFChars; - envTable->ReleaseStringUTFChars = ::ReleaseStringUTFChars; - envTable->GetArrayLength = ::GetArrayLength; - envTable->NewString = ::NewString; - envTable->NewStringUTF = ::NewStringUTF; - envTable->FindClass = ::FindClass; - envTable->ThrowNew = ::ThrowNew; - envTable->ExceptionCheck = ::ExceptionCheck; - envTable->NewDirectByteBuffer = ::NewDirectByteBuffer; - envTable->GetDirectBufferAddress = ::GetDirectBufferAddress; - envTable->GetDirectBufferCapacity = ::GetDirectBufferCapacity; - envTable->DeleteLocalRef = ::DeleteLocalRef; - envTable->GetObjectClass = ::GetObjectClass; - envTable->IsInstanceOf = ::IsInstanceOf; - envTable->GetFieldID = ::GetFieldID; - envTable->GetMethodID = ::GetMethodID; - envTable->GetStaticMethodID = ::GetStaticMethodID; - envTable->NewObject = ::NewObject; - envTable->NewObjectV = ::NewObjectV; - envTable->CallObjectMethodV = ::CallObjectMethodV; - envTable->CallObjectMethod = ::CallObjectMethod; - envTable->CallBooleanMethodV = ::CallBooleanMethodV; - envTable->CallBooleanMethod = ::CallBooleanMethod; - envTable->CallByteMethodV = ::CallByteMethodV; - envTable->CallByteMethod = ::CallByteMethod; - envTable->CallCharMethodV = ::CallCharMethodV; - envTable->CallCharMethod = ::CallCharMethod; - envTable->CallShortMethodV = ::CallShortMethodV; - envTable->CallShortMethod = ::CallShortMethod; - envTable->CallIntMethodV = ::CallIntMethodV; - envTable->CallIntMethod = ::CallIntMethod; - envTable->CallLongMethodV = ::CallLongMethodV; - envTable->CallLongMethod = ::CallLongMethod; - envTable->CallFloatMethodV = ::CallFloatMethodV; - envTable->CallFloatMethod = ::CallFloatMethod; - envTable->CallDoubleMethodV = ::CallDoubleMethodV; - envTable->CallDoubleMethod = ::CallDoubleMethod; - envTable->CallVoidMethodV = ::CallVoidMethodV; - envTable->CallVoidMethod = ::CallVoidMethod; - envTable->CallStaticObjectMethodV = ::CallStaticObjectMethodV; - envTable->CallStaticObjectMethod = ::CallStaticObjectMethod; - envTable->CallStaticBooleanMethodV = ::CallStaticBooleanMethodV; - envTable->CallStaticBooleanMethod = ::CallStaticBooleanMethod; - envTable->CallStaticByteMethodV = ::CallStaticByteMethodV; - envTable->CallStaticByteMethod = ::CallStaticByteMethod; - envTable->CallStaticCharMethodV = ::CallStaticCharMethodV; - envTable->CallStaticCharMethod = ::CallStaticCharMethod; - envTable->CallStaticShortMethodV = ::CallStaticShortMethodV; - envTable->CallStaticShortMethod = ::CallStaticShortMethod; - envTable->CallStaticIntMethodV = ::CallStaticIntMethodV; - envTable->CallStaticIntMethod = ::CallStaticIntMethod; - envTable->CallStaticLongMethodV = ::CallStaticLongMethodV; - envTable->CallStaticLongMethod = ::CallStaticLongMethod; - envTable->CallStaticFloatMethodV = ::CallStaticFloatMethodV; - envTable->CallStaticFloatMethod = ::CallStaticFloatMethod; - envTable->CallStaticDoubleMethodV = ::CallStaticDoubleMethodV; - envTable->CallStaticDoubleMethod = ::CallStaticDoubleMethod; - envTable->CallStaticVoidMethodV = ::CallStaticVoidMethodV; - envTable->CallStaticVoidMethod = ::CallStaticVoidMethod; - envTable->GetStaticFieldID = ::GetStaticFieldID; - envTable->GetObjectField = ::GetObjectField; - envTable->GetBooleanField = ::GetBooleanField; - envTable->GetByteField = ::GetByteField; - envTable->GetCharField = ::GetCharField; - envTable->GetShortField = ::GetShortField; - envTable->GetIntField = ::GetIntField; - envTable->GetLongField = ::GetLongField; - envTable->GetFloatField = ::GetFloatField; - envTable->GetDoubleField = ::GetDoubleField; - envTable->SetObjectField = ::SetObjectField; - envTable->SetBooleanField = ::SetBooleanField; - envTable->SetByteField = ::SetByteField; - envTable->SetCharField = ::SetCharField; - envTable->SetShortField = ::SetShortField; - envTable->SetIntField = ::SetIntField; - envTable->SetLongField = ::SetLongField; - envTable->SetFloatField = ::SetFloatField; - envTable->SetDoubleField = ::SetDoubleField; - envTable->GetStaticObjectField = ::GetStaticObjectField; - envTable->GetStaticBooleanField = ::GetStaticBooleanField; - envTable->GetStaticByteField = ::GetStaticByteField; - envTable->GetStaticCharField = ::GetStaticCharField; - envTable->GetStaticShortField = ::GetStaticShortField; - envTable->GetStaticIntField = ::GetStaticIntField; - envTable->GetStaticLongField = ::GetStaticLongField; - envTable->GetStaticFloatField = ::GetStaticFloatField; - envTable->GetStaticDoubleField = ::GetStaticDoubleField; - envTable->SetStaticObjectField = ::SetStaticObjectField; - envTable->SetStaticBooleanField = ::SetStaticBooleanField; - envTable->SetStaticByteField = ::SetStaticByteField; - envTable->SetStaticCharField = ::SetStaticCharField; - envTable->SetStaticShortField = ::SetStaticShortField; - envTable->SetStaticIntField = ::SetStaticIntField; - envTable->SetStaticLongField = ::SetStaticLongField; - envTable->SetStaticFloatField = ::SetStaticFloatField; - envTable->SetStaticDoubleField = ::SetStaticDoubleField; - envTable->NewGlobalRef = ::NewGlobalRef; - envTable->NewWeakGlobalRef = ::NewGlobalRef; - envTable->DeleteGlobalRef = ::DeleteGlobalRef; - envTable->ExceptionOccurred = ::ExceptionOccurred; - envTable->ExceptionDescribe = ::ExceptionDescribe; - envTable->ExceptionClear = ::ExceptionClear; - envTable->NewObjectArray = ::NewObjectArray; - envTable->GetObjectArrayElement = ::GetObjectArrayElement; - envTable->SetObjectArrayElement = ::SetObjectArrayElement; - envTable->NewBooleanArray = ::NewBooleanArray; - envTable->NewByteArray = ::NewByteArray; - envTable->NewCharArray = ::NewCharArray; - envTable->NewShortArray = ::NewShortArray; - envTable->NewIntArray = ::NewIntArray; - envTable->NewLongArray = ::NewLongArray; - envTable->NewFloatArray = ::NewFloatArray; - envTable->NewDoubleArray = ::NewDoubleArray; - envTable->GetBooleanArrayElements = ::GetBooleanArrayElements; - envTable->GetByteArrayElements = ::GetByteArrayElements; - envTable->GetCharArrayElements = ::GetCharArrayElements; - envTable->GetShortArrayElements = ::GetShortArrayElements; - envTable->GetIntArrayElements = ::GetIntArrayElements; - envTable->GetLongArrayElements = ::GetLongArrayElements; - envTable->GetFloatArrayElements = ::GetFloatArrayElements; - envTable->GetDoubleArrayElements = ::GetDoubleArrayElements; - envTable->ReleaseBooleanArrayElements = ::ReleaseBooleanArrayElements; - envTable->ReleaseByteArrayElements = ::ReleaseByteArrayElements; - envTable->ReleaseCharArrayElements = ::ReleaseCharArrayElements; - envTable->ReleaseShortArrayElements = ::ReleaseShortArrayElements; - envTable->ReleaseIntArrayElements = ::ReleaseIntArrayElements; - envTable->ReleaseLongArrayElements = ::ReleaseLongArrayElements; - envTable->ReleaseFloatArrayElements = ::ReleaseFloatArrayElements; - envTable->ReleaseDoubleArrayElements = ::ReleaseDoubleArrayElements; - envTable->GetBooleanArrayRegion = ::GetBooleanArrayRegion; - envTable->GetByteArrayRegion = ::GetByteArrayRegion; - envTable->GetCharArrayRegion = ::GetCharArrayRegion; - envTable->GetShortArrayRegion = ::GetShortArrayRegion; - envTable->GetIntArrayRegion = ::GetIntArrayRegion; - envTable->GetLongArrayRegion = ::GetLongArrayRegion; - envTable->GetFloatArrayRegion = ::GetFloatArrayRegion; - envTable->GetDoubleArrayRegion = ::GetDoubleArrayRegion; - envTable->SetBooleanArrayRegion = ::SetBooleanArrayRegion; - envTable->SetByteArrayRegion = ::SetByteArrayRegion; - envTable->SetCharArrayRegion = ::SetCharArrayRegion; - envTable->SetShortArrayRegion = ::SetShortArrayRegion; - envTable->SetIntArrayRegion = ::SetIntArrayRegion; - envTable->SetLongArrayRegion = ::SetLongArrayRegion; - envTable->SetFloatArrayRegion = ::SetFloatArrayRegion; - envTable->SetDoubleArrayRegion = ::SetDoubleArrayRegion; - envTable->GetPrimitiveArrayCritical = ::GetPrimitiveArrayCritical; - envTable->ReleasePrimitiveArrayCritical = ::ReleasePrimitiveArrayCritical; - envTable->MonitorEnter = MonitorEnter; - envTable->MonitorExit = MonitorExit; - envTable->GetJavaVM = ::GetJavaVM; - envTable->IsSameObject = ::IsSameObject; + envTable->GetVersion = local::GetVersion; + envTable->GetStringLength = local::GetStringLength; + envTable->GetStringChars = local::GetStringChars; + envTable->ReleaseStringChars = local::ReleaseStringChars; + envTable->GetStringUTFLength = local::GetStringUTFLength; + envTable->GetStringUTFChars = local::GetStringUTFChars; + envTable->ReleaseStringUTFChars = local::ReleaseStringUTFChars; + envTable->GetArrayLength = local::GetArrayLength; + envTable->NewString = local::NewString; + envTable->NewStringUTF = local::NewStringUTF; + envTable->FindClass = local::FindClass; + envTable->ThrowNew = local::ThrowNew; + envTable->ExceptionCheck = local::ExceptionCheck; + envTable->NewDirectByteBuffer = local::NewDirectByteBuffer; + envTable->GetDirectBufferAddress = local::GetDirectBufferAddress; + envTable->GetDirectBufferCapacity = local::GetDirectBufferCapacity; + envTable->DeleteLocalRef = local::DeleteLocalRef; + envTable->GetObjectClass = local::GetObjectClass; + envTable->IsInstanceOf = local::IsInstanceOf; + envTable->GetFieldID = local::GetFieldID; + envTable->GetMethodID = local::GetMethodID; + envTable->GetStaticMethodID = local::GetStaticMethodID; + envTable->NewObject = local::NewObject; + envTable->NewObjectV = local::NewObjectV; + envTable->CallObjectMethodV = local::CallObjectMethodV; + envTable->CallObjectMethod = local::CallObjectMethod; + envTable->CallBooleanMethodV = local::CallBooleanMethodV; + envTable->CallBooleanMethod = local::CallBooleanMethod; + envTable->CallByteMethodV = local::CallByteMethodV; + envTable->CallByteMethod = local::CallByteMethod; + envTable->CallCharMethodV = local::CallCharMethodV; + envTable->CallCharMethod = local::CallCharMethod; + envTable->CallShortMethodV = local::CallShortMethodV; + envTable->CallShortMethod = local::CallShortMethod; + envTable->CallIntMethodV = local::CallIntMethodV; + envTable->CallIntMethod = local::CallIntMethod; + envTable->CallLongMethodV = local::CallLongMethodV; + envTable->CallLongMethod = local::CallLongMethod; + envTable->CallFloatMethodV = local::CallFloatMethodV; + envTable->CallFloatMethod = local::CallFloatMethod; + envTable->CallDoubleMethodV = local::CallDoubleMethodV; + envTable->CallDoubleMethod = local::CallDoubleMethod; + envTable->CallVoidMethodV = local::CallVoidMethodV; + envTable->CallVoidMethod = local::CallVoidMethod; + envTable->CallStaticObjectMethodV = local::CallStaticObjectMethodV; + envTable->CallStaticObjectMethod = local::CallStaticObjectMethod; + envTable->CallStaticBooleanMethodV = local::CallStaticBooleanMethodV; + envTable->CallStaticBooleanMethod = local::CallStaticBooleanMethod; + envTable->CallStaticByteMethodV = local::CallStaticByteMethodV; + envTable->CallStaticByteMethod = local::CallStaticByteMethod; + envTable->CallStaticCharMethodV = local::CallStaticCharMethodV; + envTable->CallStaticCharMethod = local::CallStaticCharMethod; + envTable->CallStaticShortMethodV = local::CallStaticShortMethodV; + envTable->CallStaticShortMethod = local::CallStaticShortMethod; + envTable->CallStaticIntMethodV = local::CallStaticIntMethodV; + envTable->CallStaticIntMethod = local::CallStaticIntMethod; + envTable->CallStaticLongMethodV = local::CallStaticLongMethodV; + envTable->CallStaticLongMethod = local::CallStaticLongMethod; + envTable->CallStaticFloatMethodV = local::CallStaticFloatMethodV; + envTable->CallStaticFloatMethod = local::CallStaticFloatMethod; + envTable->CallStaticDoubleMethodV = local::CallStaticDoubleMethodV; + envTable->CallStaticDoubleMethod = local::CallStaticDoubleMethod; + envTable->CallStaticVoidMethodV = local::CallStaticVoidMethodV; + envTable->CallStaticVoidMethod = local::CallStaticVoidMethod; + envTable->GetStaticFieldID = local::GetStaticFieldID; + envTable->GetObjectField = local::GetObjectField; + envTable->GetBooleanField = local::GetBooleanField; + envTable->GetByteField = local::GetByteField; + envTable->GetCharField = local::GetCharField; + envTable->GetShortField = local::GetShortField; + envTable->GetIntField = local::GetIntField; + envTable->GetLongField = local::GetLongField; + envTable->GetFloatField = local::GetFloatField; + envTable->GetDoubleField = local::GetDoubleField; + envTable->SetObjectField = local::SetObjectField; + envTable->SetBooleanField = local::SetBooleanField; + envTable->SetByteField = local::SetByteField; + envTable->SetCharField = local::SetCharField; + envTable->SetShortField = local::SetShortField; + envTable->SetIntField = local::SetIntField; + envTable->SetLongField = local::SetLongField; + envTable->SetFloatField = local::SetFloatField; + envTable->SetDoubleField = local::SetDoubleField; + envTable->GetStaticObjectField = local::GetStaticObjectField; + envTable->GetStaticBooleanField = local::GetStaticBooleanField; + envTable->GetStaticByteField = local::GetStaticByteField; + envTable->GetStaticCharField = local::GetStaticCharField; + envTable->GetStaticShortField = local::GetStaticShortField; + envTable->GetStaticIntField = local::GetStaticIntField; + envTable->GetStaticLongField = local::GetStaticLongField; + envTable->GetStaticFloatField = local::GetStaticFloatField; + envTable->GetStaticDoubleField = local::GetStaticDoubleField; + envTable->SetStaticObjectField = local::SetStaticObjectField; + envTable->SetStaticBooleanField = local::SetStaticBooleanField; + envTable->SetStaticByteField = local::SetStaticByteField; + envTable->SetStaticCharField = local::SetStaticCharField; + envTable->SetStaticShortField = local::SetStaticShortField; + envTable->SetStaticIntField = local::SetStaticIntField; + envTable->SetStaticLongField = local::SetStaticLongField; + envTable->SetStaticFloatField = local::SetStaticFloatField; + envTable->SetStaticDoubleField = local::SetStaticDoubleField; + envTable->NewGlobalRef = local::NewGlobalRef; + envTable->NewWeakGlobalRef = local::NewGlobalRef; + envTable->DeleteGlobalRef = local::DeleteGlobalRef; + envTable->ExceptionOccurred = local::ExceptionOccurred; + envTable->ExceptionDescribe = local::ExceptionDescribe; + envTable->ExceptionClear = local::ExceptionClear; + envTable->NewObjectArray = local::NewObjectArray; + envTable->GetObjectArrayElement = local::GetObjectArrayElement; + envTable->SetObjectArrayElement = local::SetObjectArrayElement; + envTable->NewBooleanArray = local::NewBooleanArray; + envTable->NewByteArray = local::NewByteArray; + envTable->NewCharArray = local::NewCharArray; + envTable->NewShortArray = local::NewShortArray; + envTable->NewIntArray = local::NewIntArray; + envTable->NewLongArray = local::NewLongArray; + envTable->NewFloatArray = local::NewFloatArray; + envTable->NewDoubleArray = local::NewDoubleArray; + envTable->GetBooleanArrayElements = local::GetBooleanArrayElements; + envTable->GetByteArrayElements = local::GetByteArrayElements; + envTable->GetCharArrayElements = local::GetCharArrayElements; + envTable->GetShortArrayElements = local::GetShortArrayElements; + envTable->GetIntArrayElements = local::GetIntArrayElements; + envTable->GetLongArrayElements = local::GetLongArrayElements; + envTable->GetFloatArrayElements = local::GetFloatArrayElements; + envTable->GetDoubleArrayElements = local::GetDoubleArrayElements; + envTable->ReleaseBooleanArrayElements = local::ReleaseBooleanArrayElements; + envTable->ReleaseByteArrayElements = local::ReleaseByteArrayElements; + envTable->ReleaseCharArrayElements = local::ReleaseCharArrayElements; + envTable->ReleaseShortArrayElements = local::ReleaseShortArrayElements; + envTable->ReleaseIntArrayElements = local::ReleaseIntArrayElements; + envTable->ReleaseLongArrayElements = local::ReleaseLongArrayElements; + envTable->ReleaseFloatArrayElements = local::ReleaseFloatArrayElements; + envTable->ReleaseDoubleArrayElements = local::ReleaseDoubleArrayElements; + envTable->GetBooleanArrayRegion = local::GetBooleanArrayRegion; + envTable->GetByteArrayRegion = local::GetByteArrayRegion; + envTable->GetCharArrayRegion = local::GetCharArrayRegion; + envTable->GetShortArrayRegion = local::GetShortArrayRegion; + envTable->GetIntArrayRegion = local::GetIntArrayRegion; + envTable->GetLongArrayRegion = local::GetLongArrayRegion; + envTable->GetFloatArrayRegion = local::GetFloatArrayRegion; + envTable->GetDoubleArrayRegion = local::GetDoubleArrayRegion; + envTable->SetBooleanArrayRegion = local::SetBooleanArrayRegion; + envTable->SetByteArrayRegion = local::SetByteArrayRegion; + envTable->SetCharArrayRegion = local::SetCharArrayRegion; + envTable->SetShortArrayRegion = local::SetShortArrayRegion; + envTable->SetIntArrayRegion = local::SetIntArrayRegion; + envTable->SetLongArrayRegion = local::SetLongArrayRegion; + envTable->SetFloatArrayRegion = local::SetFloatArrayRegion; + envTable->SetDoubleArrayRegion = local::SetDoubleArrayRegion; + envTable->GetPrimitiveArrayCritical = local::GetPrimitiveArrayCritical; + envTable->ReleasePrimitiveArrayCritical + = local::ReleasePrimitiveArrayCritical; + envTable->MonitorEnter = local::MonitorEnter; + envTable->MonitorExit = local::MonitorExit; + envTable->GetJavaVM = local::GetJavaVM; + envTable->IsSameObject = local::IsSameObject; } } // namespace vm @@ -2111,7 +2116,7 @@ JNI_GetDefaultJavaVMInitArgs(void*) extern "C" JNIEXPORT jint JNICALL JNI_CreateJavaVM(Machine** m, Thread** t, void* args) { - JavaVMInitArgs* a = static_cast(args); + local::JavaVMInitArgs* a = static_cast(args); unsigned heapLimit = 0; const char* bootLibrary = 0; @@ -2127,7 +2132,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args) if (strncmp(a->options[i].optionString, "-X", 2) == 0) { const char* p = a->options[i].optionString + 2; if (strncmp(p, "mx", 2) == 0) { - heapLimit = parseSize(p + 2); + heapLimit = local::parseSize(p + 2); } else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":", sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0) { @@ -2174,10 +2179,11 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args) RUNTIME_ARRAY(char, classpathBuffer, classpathBufferSize); char* classpathPointer = RUNTIME_ARRAY_BODY(classpathBuffer); - append(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR); - append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR); - append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR); - append(&classpathPointer, classpath, cpl, 0); + local::append + (&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR); + local::append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR); + local::append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR); + local::append(&classpathPointer, classpath, cpl, 0); System* s = makeSystem(crashDumpDirectory); Heap* h = makeHeap(s, heapLimit); diff --git a/src/x86.h b/src/x86.h index a3450377a7..93278cdd7d 100644 --- a/src/x86.h +++ b/src/x86.h @@ -199,7 +199,8 @@ inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_) { #ifdef _MSC_VER - InterlockedCompareExchange(p, new_, old); + return old == InterlockedCompareExchange + (reinterpret_cast(p), new_, old); #elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) return __sync_bool_compare_and_swap(p, old, new_); #else @@ -218,7 +219,8 @@ inline bool atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_) { #ifdef _MSC_VER - InterlockedCompareExchange64(p, new_, old); + return old == InterlockedCompareExchange64 + (reinterpret_cast(p), new_, old); #elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) return __sync_bool_compare_and_swap(p, old, new_); #else From c666ab58e308588906aea75b106b232338bb204e Mon Sep 17 00:00:00 2001 From: JET Date: Tue, 20 Apr 2010 10:03:07 -0600 Subject: [PATCH 05/15] Improved (should now be complete) Unicode support (UTF-8 for *nix and UTF-16 for Windows). --- classpath/java-io.cpp | 145 ++++++++++++++++++++++++------------------ src/jnienv.cpp | 7 +- src/machine.cpp | 60 +++++++++++++++++ src/machine.h | 6 ++ 4 files changed, 154 insertions(+), 64 deletions(-) diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 09c058206c..22880146ac 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -28,10 +28,11 @@ # define CLOSE _close # define READ _read # define WRITE _write -# define STAT _stat +# define STAT _wstat # define STRUCT_STAT struct _stat -# define MKDIR(path, mode) _mkdir(path) -# define UNLINK _unlink +# define MKDIR(path, mode) _wmkdir(path) +# define UNLINK _wunlink +# define RENAME _wrename # define OPEN_MASK O_BINARY # ifdef _MSC_VER @@ -40,10 +41,15 @@ # define S_IRUSR _S_IREAD # define S_IWUSR _S_IWRITE # else -# define OPEN _open -# define CREAT _creat +# define OPEN _wopen +# define CREAT _wcreat # endif +# define GET_CHARS GetStringChars +# define RELEASE_CHARS(path, chars) ReleaseStringChars(path, reinterpret_cast(chars)) + +typedef wchar_t char_t; + #else // not PLATFORM_WINDOWS # include @@ -59,42 +65,50 @@ # define MKDIR mkdir # define CREAT creat # define UNLINK unlink +# define RENAME rename # define OPEN_MASK 0 +# define GET_CHARS GetStringUTFChars +# define RELEASE_CHARS ReleaseStringUTFChars + +typedef char char_t; + #endif // not PLATFORM_WINDOWS inline void* operator new(size_t, void* p) throw() { return p; } +typedef const char_t* string_t; + namespace { #ifdef _MSC_VER -inline int -OPEN(const char* path, int mask, int mode) +inline int +OPEN(string_t path, int mask, int mode) { - int fd; - if (_sopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) { - return fd; + int fd; + if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) { + return fd; } else { - return -1; + return -1; } } inline int -CREAT(const char* path, int mode) +CREAT(string_t path, int mode) { return OPEN(path, _O_CREAT, mode); } #endif inline bool -exists(const char* path) +exists(string_t path) { STRUCT_STAT s; return STAT(path, &s) == 0; } inline int -doOpen(JNIEnv* e, const char* path, int mask) +doOpen(JNIEnv* e, string_t path, int mask) { int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR); if (fd == -1) { @@ -157,11 +171,11 @@ class Mapping { }; inline Mapping* -map(JNIEnv* e, const char* path) +map(JNIEnv* e, string_t path) { Mapping* result = 0; - HANDLE file = CreateFile(path, FILE_READ_DATA, FILE_SHARE_READ, 0, - OPEN_EXISTING, 0, 0); + HANDLE file = CreateFileW(path, FILE_READ_DATA, FILE_SHARE_READ, 0, + OPEN_EXISTING, 0, 0); if (file != INVALID_HANDLE_VALUE) { unsigned size = GetFileSize(file, 0); if (size != INVALID_FILE_SIZE) { @@ -205,10 +219,10 @@ class Directory { public: Directory(): handle(0), findNext(false) { } - virtual const char* next() { + virtual string_t next() { if (handle and handle != INVALID_HANDLE_VALUE) { if (findNext) { - if (FindNextFile(handle, &data)) { + if (FindNextFileW(handle, &data)) { return data.cFileName; } } else { @@ -227,7 +241,7 @@ class Directory { } HANDLE handle; - WIN32_FIND_DATA data; + WIN32_FIND_DATAW data; bool findNext; }; @@ -245,7 +259,7 @@ class Mapping { }; inline Mapping* -map(JNIEnv* e, const char* path) +map(JNIEnv* e, string_t path) { Mapping* result = 0; int fd = open(path, O_RDONLY); @@ -280,6 +294,14 @@ unmap(JNIEnv*, Mapping* mapping) } // namespace +inline string_t getChars(JNIEnv* e, jstring path) { + return reinterpret_cast(e->GET_CHARS(path, 0)); +} + +inline void releaseChars(JNIEnv* e, jstring path, string_t chars) { + e->RELEASE_CHARS(path, chars); +} + extern "C" JNIEXPORT jstring JNICALL Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path) { @@ -297,14 +319,14 @@ Java_java_io_File_toAbsolutePath(JNIEnv* /*e*/, jclass, jstring path) extern "C" JNIEXPORT jlong JNICALL Java_java_io_File_length(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { STRUCT_STAT s; int r = STAT(chars, &s); if (r == 0) { return s.st_size; } - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); } return -1; @@ -313,7 +335,7 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path) extern "C" JNIEXPORT void JNICALL Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { if (not exists(chars)) { int r = ::MKDIR(chars, 0700); @@ -321,14 +343,14 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path) throwNewErrno(e, "java/io/IOException"); } } - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); } } extern "C" JNIEXPORT void JNICALL Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { if (not exists(chars)) { int fd = CREAT(chars, 0600); @@ -338,38 +360,38 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path) doClose(e, fd); } } - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); } } extern "C" JNIEXPORT void JNICALL Java_java_io_File_delete(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { int r = UNLINK(chars); if (r != 0) { throwNewErrno(e, "java/io/IOException"); } - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); } } extern "C" JNIEXPORT jboolean JNICALL Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_) { - const char* oldChars = e->GetStringUTFChars(old, 0); - const char* newChars = e->GetStringUTFChars(new_, 0); + string_t oldChars = getChars(e, old); + string_t newChars = getChars(e, new_); if (oldChars) { bool v; if (newChars) { - v = rename(oldChars, newChars) == 0; + v = RENAME(oldChars, newChars) == 0; - e->ReleaseStringUTFChars(new_, newChars); + releaseChars(e, new_, newChars); } else { v = false; } - e->ReleaseStringUTFChars(old, oldChars); + releaseChars(e, old, oldChars); return v; } else { return false; @@ -379,12 +401,12 @@ Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_) extern "C" JNIEXPORT jboolean JNICALL Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { STRUCT_STAT s; int r = STAT(chars, &s); bool v = (r == 0 and S_ISDIR(s.st_mode)); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); return v; } else { return false; @@ -394,12 +416,12 @@ Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path) extern "C" JNIEXPORT jboolean JNICALL Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { STRUCT_STAT s; int r = STAT(chars, &s); bool v = (r == 0 and S_ISREG(s.st_mode)); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); return v; } else { return false; @@ -409,10 +431,10 @@ Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path) extern "C" JNIEXPORT jboolean JNICALL Java_java_io_File_exists(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { bool v = exists(chars); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); return v; } else { return false; @@ -424,18 +446,19 @@ Java_java_io_File_exists(JNIEnv* e, jclass, jstring path) extern "C" JNIEXPORT jlong JNICALL Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { - unsigned length = strlen(chars); + unsigned length = wcslen(chars); + unsigned size = length * sizeof(char_t); - RUNTIME_ARRAY(char, buffer, length + 3); - memcpy(RUNTIME_ARRAY_BODY(buffer), chars, length); - memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3); + RUNTIME_ARRAY(char_t, buffer, length + 3); + memcpy(RUNTIME_ARRAY_BODY(buffer), chars, size); + memcpy(RUNTIME_ARRAY_BODY(buffer) + length, L"\\*", 6); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); Directory* d = new (malloc(sizeof(Directory))) Directory; - d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data)); + d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data)); if (d->handle == INVALID_HANDLE_VALUE) { d->dispose(); d = 0; @@ -451,14 +474,14 @@ extern "C" JNIEXPORT jstring JNICALL Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle) { Directory* d = reinterpret_cast(handle); - + while (true) { - const char* s = d->next(); + string_t s = d->next(); if (s) { - if (strcmp(s, ".") == 0 || strcmp(s, "..") == 0) { + if (wcscmp(s, L".") == 0 || wcscmp(s, L"..") == 0) { // skip . or .. and try again } else { - return e->NewStringUTF(s); + return e->NewString(reinterpret_cast(s), wcslen(s)); } } else { return 0; @@ -477,10 +500,10 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle) extern "C" JNIEXPORT jlong JNICALL Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { jlong handle = reinterpret_cast(opendir(chars)); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); return handle; } else { return 0; @@ -522,13 +545,13 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle) extern "C" JNIEXPORT jint JNICALL Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { int fd = doOpen(e, chars, O_RDONLY); - e->ReleaseStringUTFChars(path, chars); - return fd; + releaseChars(e, path, chars); + return fd; } else { - return -1; + return -1; } } @@ -572,10 +595,10 @@ Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd) extern "C" JNIEXPORT jint JNICALL Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); return fd; } else { return -1; @@ -618,7 +641,7 @@ extern "C" JNIEXPORT void JNICALL Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path, jlongArray result) { - const char* chars = e->GetStringUTFChars(path, 0); + string_t chars = getChars(e, path); if (chars) { Mapping* mapping = map(e, chars); @@ -628,7 +651,7 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path, jlong length = (mapping ? mapping->length : 0); e->SetLongArrayRegion(result, 1, 1, &length); - e->ReleaseStringUTFChars(path, chars); + releaseChars(e, path, chars); } } diff --git a/src/jnienv.cpp b/src/jnienv.cpp index f16360aecf..3fdd3d15cb 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -159,7 +159,7 @@ GetStringUTFLength(Thread* t, jstring s) { ENTER(t, Thread::ActiveState); - return stringLength(t, *s); + return stringUTFLength(t, *s); } const char* JNICALL @@ -167,9 +167,10 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy) { ENTER(t, Thread::ActiveState); + int length = stringUTFLength(t, *s); char* chars = static_cast - (t->m->heap->allocate(stringLength(t, *s) + 1)); - stringChars(t, *s, chars); + (t->m->heap->allocate(length + 1)); + stringUTFChars(t, *s, chars, length); if (isCopy) *isCopy = true; return chars; diff --git a/src/machine.cpp b/src/machine.cpp index 44247f52cb..3b3c1fb215 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2690,6 +2690,30 @@ makeString(Thread* t, const char* format, ...) return makeString(t, s, 0, byteArrayLength(t, s) - 1, 0); } + +int +stringUTFLength(Thread* t, object string) { + int length = 0; + + if (stringLength(t, string)) { + object data = stringData(t, string); + if (objectClass(t, data) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) { + length = stringLength(t, string); + } else { + for (unsigned i = 0; i < stringLength(t, string); ++i) { + uint16_t c = charArrayBody(t, data, stringOffset(t, string) + i); + if (!c) length += 1; // null char (was 2 bytes in Java) + else if (c < 0x80) length += 1; // ASCII char + else if (c < 0x800) length += 2; // two-byte char + else length += 3; // three-byte char + } + } + } + + return length; +} + void stringChars(Thread* t, object string, char* chars) { @@ -2730,6 +2754,42 @@ stringChars(Thread* t, object string, uint16_t* chars) chars[stringLength(t, string)] = 0; } +void +stringUTFChars(Thread* t, object string, char* chars, unsigned length UNUSED) +{ + assert(t, static_cast(stringUTFLength(t, string)) == length); + + if (stringLength(t, string)) { + object data = stringData(t, string); + if (objectClass(t, data) + == arrayBody(t, t->m->types, Machine::ByteArrayType)) + { + memcpy(chars, + &byteArrayBody(t, data, stringOffset(t, string)), + stringLength(t, string)); + chars[stringLength(t, string)] = 0; + } else { + int j = 0; + for (unsigned i = 0; i < stringLength(t, string); ++i) { + uint16_t c = charArrayBody(t, data, stringOffset(t, string) + i); + if(!c) { // null char + chars[j++] = 0; + } else if (c < 0x80) { // ASCII char + chars[j++] = static_cast(c); + } else if (c < 0x800) { // two-byte char + chars[j++] = static_cast(0x0c0 | (c >> 6)); + chars[j++] = static_cast(0x080 | (c & 0x03f)); + } else { // three-byte char + chars[j++] = static_cast(0x0e0 | ((c >> 12) & 0x0f)); + chars[j++] = static_cast(0x080 | ((c >> 6) & 0x03f)); + chars[j++] = static_cast(0x080 | (c & 0x03f)); + } + } + chars[j] = 0; + } + } +} + bool isAssignableFrom(Thread* t, object a, object b) { diff --git a/src/machine.h b/src/machine.h index 2ea8b94bd5..8f705ba166 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1901,12 +1901,18 @@ makeByteArray(Thread* t, const char* format, ...); object makeString(Thread* t, const char* format, ...); +int +stringUTFLength(Thread* t, object string); + void stringChars(Thread* t, object string, char* chars); void stringChars(Thread* t, object string, uint16_t* chars); +void +stringUTFChars(Thread* t, object string, char* chars, unsigned length); + bool isAssignableFrom(Thread* t, object a, object b); From 3aac50555bbca39330cbb39db32fdd4d82383234 Mon Sep 17 00:00:00 2001 From: JET Date: Tue, 20 Apr 2010 15:51:35 -0600 Subject: [PATCH 06/15] fixed ARM interpreted-mode regression --- makefile | 13 +------------ src/arm.h | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/makefile b/makefile index 3c3176619d..6322e4f2bf 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ MAKEFLAGS = -s name = avian version = 0.3 -build-arch := $(shell uname -m | sed 's/^i.86$$/i386/') +build-arch := $(shell uname -m | sed 's/^i.86$$/i386/' | sed 's/^arm.*$$/arm/') ifeq (Power,$(filter Power,$(build-arch))) build-arch = powerpc endif @@ -145,19 +145,8 @@ ifeq ($(arch),powerpc) pointer-size = 4 endif ifeq ($(arch),arm) - lflags := -L/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/lib -L$(root)/arm/lib $(lflags) - cflags := -I/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/include -I$(root)/arm/include $(cflags) - asm = arm - object-arch = arm - object-format = elf32-littlearm pointer-size = 4 - cxx = arm-unknown-linux-gnu-g++ - cc = arm-unknown-linux-gnu-gcc - ar = arm-unknown-linux-gnu-ar - ranlib = arm-unknown-linux-gnu-ranlib - objcopy = arm-unknown-linux-gnu-objcopy - strip = arm-unknown-linux-gnu-strip endif ifeq ($(platform),darwin) diff --git a/src/arm.h b/src/arm.h index ad08714d91..b7b844685d 100644 --- a/src/arm.h +++ b/src/arm.h @@ -14,9 +14,9 @@ #include "types.h" #include "common.h" -#define IP_REGISTER(context) (context->uc_mcontext.gregs[15]) -#define STACK_REGISTER(context) (context->uc_mcontext.gregs[13]) -#define THREAD_REGISTER(context) (context->uc_mcontext.gregs[12]) +#define IP_REGISTER(context) (context->uc_mcontext.arm_pc) +#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp) +#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip) extern "C" uint64_t vmNativeCall(void* function, unsigned stackTotal, void* memoryTable, @@ -60,9 +60,25 @@ syncInstructionCache(const void* start UNUSED, unsigned size UNUSED) asm("nop"); } +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) + +inline bool +atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_) +{ + int r = __kernel_cmpxchg(static_cast(old), static_cast(new_), reinterpret_cast(p)); + return (!r ? true : false); +} + +inline bool +atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_) +{ + return atomicCompareAndSwap32(reinterpret_cast(p), old, new_); +} + inline uint64_t dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, - unsigned argumentCount, unsigned argumentsSize, + unsigned argumentCount, unsigned argumentsSize UNUSED, unsigned returnType UNUSED) { const unsigned GprCount = 4; From 9909c0cec3f15fa764f2ccb10ffc1ea0a3343b2b Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Mon, 26 Apr 2010 10:24:53 -0600 Subject: [PATCH 07/15] Fix Mac OS X specific path bug In Mac OS X, if a path contains a space, the path of the main executable will contain a special URL-encoded character (%20 in this case). This probably happens when any non-ASCII character is provided. The fix is to use CFURLCreateStringByReplacingPercentEscapes which creates a path that the POSIX API likes better. --- src/posix.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/posix.cpp b/src/posix.cpp index 569f0b08f9..0d34e2828a 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -93,6 +93,8 @@ pathOfExecutable(System* s, const char** retBuf, unsigned* size) CFBundleRef bundle = CFBundleGetMainBundle(); CFURLRef url = CFBundleCopyExecutableURL(bundle); CFStringRef path = CFURLCopyPath(url); + path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, + path, CFSTR("")); CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path); char* buffer = reinterpret_cast(allocate(s, pathSize)); if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) { From 3e111f87c3663a58d3e12f2e928756155086d0bf Mon Sep 17 00:00:00 2001 From: mjensen Date: Mon, 10 May 2010 10:16:36 -0600 Subject: [PATCH 08/15] Added files to be ignored that are used in eclipse --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index aff794f5e5..8028923871 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .gdb_history build -*~ \ No newline at end of file +*~ +.classpath +.project +.settings +bin From a6998238d5b714b8e7b11105578cdea12e3ccf3d Mon Sep 17 00:00:00 2001 From: mjensen Date: Mon, 10 May 2010 10:17:06 -0600 Subject: [PATCH 09/15] Additional of several interfaces which can be used in serialization --- classpath/java/io/Externalizable.java | 16 ++++++++++++++++ classpath/java/io/ObjectInput.java | 21 +++++++++++++++++++++ classpath/java/io/ObjectOutput.java | 20 ++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 classpath/java/io/Externalizable.java create mode 100644 classpath/java/io/ObjectInput.java create mode 100644 classpath/java/io/ObjectOutput.java diff --git a/classpath/java/io/Externalizable.java b/classpath/java/io/Externalizable.java new file mode 100644 index 0000000000..c08b67587f --- /dev/null +++ b/classpath/java/io/Externalizable.java @@ -0,0 +1,16 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.io; + +public interface Externalizable { + public void readExternal(ObjectInput in); + public void writeExternal(ObjectOutput out); +} diff --git a/classpath/java/io/ObjectInput.java b/classpath/java/io/ObjectInput.java new file mode 100644 index 0000000000..fd8c702bd9 --- /dev/null +++ b/classpath/java/io/ObjectInput.java @@ -0,0 +1,21 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.io; + +public interface ObjectInput { + public int available(); + public void close(); + public void read(); + public void read(byte[] b); + public void read(byte[] b, int off, int len); + public Object readObject(); + public long skip(long n); +} diff --git a/classpath/java/io/ObjectOutput.java b/classpath/java/io/ObjectOutput.java new file mode 100644 index 0000000000..cf794447ce --- /dev/null +++ b/classpath/java/io/ObjectOutput.java @@ -0,0 +1,20 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.io; + +public interface ObjectOutput { + public void close(); + public void flush(); + public void write(byte[] b); + public void write(byte[] b, int off, int len); + public void write(int b); + public void writeObject(Object obj); +} From 83c51f48018db4206bf3bc592f3b94cc1111edb3 Mon Sep 17 00:00:00 2001 From: Matt Klich Date: Thu, 13 May 2010 16:38:58 -0600 Subject: [PATCH 10/15] Fix signed vs. unsigned comparison for 32bit build with mingw64 --- classpath/java-nio.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 07e33cc353..540cb89364 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -742,9 +742,9 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass, if (FD_ISSET(s->control.writer(), &(s->write)) or FD_ISSET(s->control.writer(), &(s->except))) { - unsigned socket = s->control.writer(); - FD_CLR(socket, &(s->write)); - FD_CLR(socket, &(s->except)); + int socket = s->control.writer(); + FD_CLR(static_cast(socket), &(s->write)); + FD_CLR(static_cast(socket), &(s->except)); int error; socklen_t size = sizeof(int); From 62c741d969e38f7a1d08f570c82c1e8bd6eaea5c Mon Sep 17 00:00:00 2001 From: Matt Klich Date: Thu, 13 May 2010 17:01:55 -0600 Subject: [PATCH 11/15] Specify -m flag on windows x86_64 gcc/g++ compilers. --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 6322e4f2bf..f0dcab31a5 100644 --- a/makefile +++ b/makefile @@ -212,8 +212,8 @@ ifeq ($(platform),windows) endif ifeq ($(arch),x86_64) - cxx = x86_64-w64-mingw32-g++ - cc = x86_64-w64-mingw32-gcc + cxx = x86_64-w64-mingw32-g++ $(mflag) + cc = x86_64-w64-mingw32-gcc $(mflag) dlltool = x86_64-w64-mingw32-dlltool ar = x86_64-w64-mingw32-ar ranlib = x86_64-w64-mingw32-ranlib From 74e282a3d3af94e7f0c3c3b18f4740f849d7f618 Mon Sep 17 00:00:00 2001 From: Matt Klich Date: Mon, 17 May 2010 12:36:39 -0600 Subject: [PATCH 12/15] win32 i386 build should use mingw64 if available --- makefile | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index f0dcab31a5..0451a7724c 100644 --- a/makefile +++ b/makefile @@ -193,12 +193,21 @@ ifeq ($(platform),windows) cflags = -I$(inc) $(common-cflags) ifeq (,$(filter mingw32 cygwin,$(build-platform))) - cxx = i586-mingw32msvc-g++ - cc = i586-mingw32msvc-gcc - dlltool = i586-mingw32msvc-dlltool - ar = i586-mingw32msvc-ar - ranlib = i586-mingw32msvc-ranlib - strip = i586-mingw32msvc-strip + ifeq (,$(shell which x86_64-w64-mingw32-g++)) + cxx = i586-mingw32msvc-g++ + cc = i586-mingw32msvc-gcc + dlltool = i586-mingw32msvc-dlltool + ar = i586-mingw32msvc-ar + ranlib = i586-mingw32msvc-ranlib + strip = i586-mingw32msvc-strip + else + cxx = x86_64-w64-mingw32-g++ $(mflag) + cc = x86_64-w64-mingw32-gcc $(mflag) + dlltool = x86_64-w64-mingw32-dlltool -mi386 --as-flags=--32 + ar = x86_64-w64-mingw32-ar + ranlib = x86_64-w64-mingw32-ranlib + strip = x86_64-w64-mingw32-strip + endif else common-cflags += "-I$(JAVA_HOME)/include/win32" build-cflags = $(common-cflags) -I$(src) -mthreads From b908f575d5460791182c1e53d01c803b57ff5134 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 4 Jun 2010 15:37:22 -0600 Subject: [PATCH 13/15] fix several blocking SocketChannel bugs In java-nio.cpp, we can't use GetPrimitiveArrayCritical when reading from or writing to blocking sockets since it may block the rest of the VM indefinitely. In SelectableChannel.java, we can't use a null test on SelectableChannel.key to determine whether the channel is open since it might never be registered with a Selector. According to the Sun documentation, a SelectableChannel is open as soon as it's created, so that's what we now implement. --- classpath/java-nio.cpp | 60 +++++++++++++++---- .../java/nio/channels/SelectableChannel.java | 8 +-- .../java/nio/channels/SocketChannel.java | 8 +-- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 540cb89364..4b052d98b1 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -428,13 +428,32 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e, jint socket, jbyteArray buffer, jint offset, - jint length) + jint length, + jboolean blocking) { - jboolean isCopy; - uint8_t *buf = static_cast - (e->GetPrimitiveArrayCritical(buffer, &isCopy)); - int r = ::doRead(socket, buf + offset, length); - e->ReleasePrimitiveArrayCritical(buffer, buf, 0); + int r; + if (blocking) { + uint8_t* buf = static_cast(allocate(e, length)); + if (buf) { + r = ::doRead(socket, buf, length); + if (r > 0) { + e->SetByteArrayRegion + (buffer, offset, r, reinterpret_cast(buf)); + } + free(buf); + } else { + return 0; + } + } else { + jboolean isCopy; + uint8_t* buf = static_cast + (e->GetPrimitiveArrayCritical(buffer, &isCopy)); + + r = ::doRead(socket, buf + offset, length); + + e->ReleasePrimitiveArrayCritical(buffer, buf, 0); + } + if (r < 0) { if (eagain()) { return 0; @@ -453,13 +472,30 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e, jint socket, jbyteArray buffer, jint offset, - jint length) + jint length, + jboolean blocking) { - jboolean isCopy; - uint8_t *buf = static_cast - (e->GetPrimitiveArrayCritical(buffer, &isCopy)); - int r = ::doWrite(socket, buf + offset, length); - e->ReleasePrimitiveArrayCritical(buffer, buf, 0); + int r; + if (blocking) { + uint8_t* buf = static_cast(allocate(e, length)); + if (buf) { + e->GetByteArrayRegion + (buffer, offset, length, reinterpret_cast(buf)); + r = ::doWrite(socket, buf, length); + free(buf); + } else { + return 0; + } + } else { + jboolean isCopy; + uint8_t* buf = static_cast + (e->GetPrimitiveArrayCritical(buffer, &isCopy)); + + r = ::doWrite(socket, buf + offset, length); + + e->ReleasePrimitiveArrayCritical(buffer, buf, 0); + } + if (r < 0) { if (eagain()) { return 0; diff --git a/classpath/java/nio/channels/SelectableChannel.java b/classpath/java/nio/channels/SelectableChannel.java index 126dc9d935..7cec3b69aa 100644 --- a/classpath/java/nio/channels/SelectableChannel.java +++ b/classpath/java/nio/channels/SelectableChannel.java @@ -15,6 +15,7 @@ import java.nio.ByteBuffer; public abstract class SelectableChannel implements Channel { private SelectionKey key; + private boolean open = true; abstract int socketFD(); @@ -30,12 +31,11 @@ public abstract class SelectableChannel implements Channel { } public boolean isOpen() { - return key != null; + return open; } public void close() throws IOException { - if (key != null) { - key = null; - } + open = false; + key = null; } } diff --git a/classpath/java/nio/channels/SocketChannel.java b/classpath/java/nio/channels/SocketChannel.java index 809142a56f..25da62684c 100644 --- a/classpath/java/nio/channels/SocketChannel.java +++ b/classpath/java/nio/channels/SocketChannel.java @@ -92,7 +92,7 @@ public class SocketChannel extends SelectableChannel byte[] array = b.array(); if (array == null) throw new NullPointerException(); - int r = natRead(socket, array, b.arrayOffset() + b.position(), b.remaining()); + int r = natRead(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking); if (r > 0) { b.position(b.position() + r); } @@ -108,7 +108,7 @@ public class SocketChannel extends SelectableChannel byte[] array = b.array(); if (array == null) throw new NullPointerException(); - int w = natWrite(socket, array, b.arrayOffset() + b.position(), b.remaining()); + int w = natWrite(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking); if (w > 0) { b.position(b.position() + w); } @@ -139,9 +139,9 @@ public class SocketChannel extends SelectableChannel throws IOException; private static native boolean natFinishConnect(int socket) throws IOException; - private static native int natRead(int socket, byte[] buffer, int offset, int length) + private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking) throws IOException; - private static native int natWrite(int socket, byte[] buffer, int offset, int length) + private static native int natWrite(int socket, byte[] buffer, int offset, int length, boolean blocking) throws IOException; private static native void natThrowWriteError(int socket) throws IOException; private static native void natCloseSocket(int socket); From f3a1c3253efa3a8577018e4d5bdae143a5d41a47 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 4 Jun 2010 18:45:13 -0600 Subject: [PATCH 14/15] use closesocket instead of close on Windows MinGW's close apparently does nothing, and MSVC's headers don't even declare it, so closesocket is the way to go. --- classpath/java-nio.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 4b052d98b1..b8a2222bcb 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -56,13 +56,15 @@ charsToArray(JNIEnv* e, const char* s) return a; } -#ifdef _MSC_VER inline void -close(int socket) +doClose(int socket) { +#ifdef PLATFORM_WINDOWS closesocket(socket); -} +#else + close(socket); #endif +} inline jbyteArray errorString(JNIEnv* e, int n) @@ -528,7 +530,7 @@ Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv *, jclass, jint socket) { - close(socket); + doClose(socket); } namespace { @@ -562,9 +564,9 @@ class Pipe { } void dispose() { - if (listener_ >= 0) ::close(listener_); - if (reader_ >= 0) ::close(reader_); - if (writer_ >= 0) ::close(writer_); + if (listener_ >= 0) ::doClose(listener_); + if (reader_ >= 0) ::doClose(reader_); + if (writer_ >= 0) ::doClose(writer_); } bool connected() { @@ -615,8 +617,8 @@ class Pipe { } void dispose() { - ::close(pipe[0]); - ::close(pipe[1]); + ::doClose(pipe[0]); + ::doClose(pipe[1]); open_ = false; } From 686f1ba983f43293720370e4763e2f696fad40be Mon Sep 17 00:00:00 2001 From: Matt Klich Date: Wed, 9 Jun 2010 16:03:48 -0600 Subject: [PATCH 15/15] Revert "win32 i386 build should use mingw64 if available" This reverts commit 74e282a3d3af94e7f0c3c3b18f4740f849d7f618. --- makefile | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/makefile b/makefile index 0451a7724c..f0dcab31a5 100644 --- a/makefile +++ b/makefile @@ -193,21 +193,12 @@ ifeq ($(platform),windows) cflags = -I$(inc) $(common-cflags) ifeq (,$(filter mingw32 cygwin,$(build-platform))) - ifeq (,$(shell which x86_64-w64-mingw32-g++)) - cxx = i586-mingw32msvc-g++ - cc = i586-mingw32msvc-gcc - dlltool = i586-mingw32msvc-dlltool - ar = i586-mingw32msvc-ar - ranlib = i586-mingw32msvc-ranlib - strip = i586-mingw32msvc-strip - else - cxx = x86_64-w64-mingw32-g++ $(mflag) - cc = x86_64-w64-mingw32-gcc $(mflag) - dlltool = x86_64-w64-mingw32-dlltool -mi386 --as-flags=--32 - ar = x86_64-w64-mingw32-ar - ranlib = x86_64-w64-mingw32-ranlib - strip = x86_64-w64-mingw32-strip - endif + cxx = i586-mingw32msvc-g++ + cc = i586-mingw32msvc-gcc + dlltool = i586-mingw32msvc-dlltool + ar = i586-mingw32msvc-ar + ranlib = i586-mingw32msvc-ranlib + strip = i586-mingw32msvc-strip else common-cflags += "-I$(JAVA_HOME)/include/win32" build-cflags = $(common-cflags) -I$(src) -mthreads