diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 08cb08bc65..82ad349756 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -431,6 +431,70 @@ Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name) return r; } +extern "C" JNIEXPORT jboolean JNICALL +Java_java_lang_Double_isInfinite(JNIEnv*, jclass, jdouble val) +{ + return !isfinite(val); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_java_lang_Double_isNaN(JNIEnv*, jclass, jdouble val) +{ + return isnan(val); +} + +extern "C" JNIEXPORT jdouble JNICALL +Java_java_lang_Double_doubleFromString(JNIEnv*e, jclass, jstring s, + jintArray numDoublesRead) +{ + const char* chars = e->GetStringUTFChars(s, 0); + double d = 0.0; + jint numRead = 0; + + if (chars) { + char* lastRead; + d = strtod(chars, &lastRead); + if ((lastRead != chars) && ((chars + strlen(chars)) == lastRead)) { + numRead = 1; + } + e->ReleaseStringUTFChars(s, chars); + } + e->SetIntArrayRegion(numDoublesRead, 0, 1, &numRead); + return d; +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_java_lang_Float_isInfinite(JNIEnv*, jclass, jfloat val) +{ + return !isfinite(val); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_java_lang_Float_isNaN(JNIEnv*, jclass, jfloat val) +{ + return isnan(val); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_java_lang_Float_floatFromString(JNIEnv*e, jclass, jstring s, + jintArray numFloatsRead) +{ + const char* chars = e->GetStringUTFChars(s, 0); + float f = 0.0; + jint numRead = 0; + + if (chars) { + char* lastRead; + f = strtof(chars, &lastRead); + if ((lastRead != chars) && ((chars + strlen(chars)) == lastRead)) { + numRead = 1; + } + e->ReleaseStringUTFChars(s, chars); + } + e->SetIntArrayRegion(numFloatsRead, 0, 1, &numRead); + return f; +} + extern "C" JNIEXPORT jdouble JNICALL Java_java_lang_Math_sin(JNIEnv*, jclass, jdouble val) { @@ -469,7 +533,12 @@ extern "C" JNIEXPORT jdouble JNICALL Java_java_lang_Math_natRandom(JNIEnv*, jclass) { #ifdef WIN32 - return rand(); + double r = static_cast(rand()) / static_cast(RAND_MAX); + if (r < 0 or r >= 1) { + return 0; + } else { + return r; + } #else return drand48(); #endif diff --git a/classpath/java/lang/Double.java b/classpath/java/lang/Double.java index d9dc8314a5..a58f9fcb39 100644 --- a/classpath/java/lang/Double.java +++ b/classpath/java/lang/Double.java @@ -31,6 +31,10 @@ public final class Double extends Number { return new Double(value); } + public static Double valueOf(String s) { + return new Double(s); + } + public boolean equals(Object o) { return o instanceof Double && ((Double) o).value == value; } @@ -74,9 +78,22 @@ public final class Double extends Number { return value; } + public boolean isInfinite() { + return isInfinite(value); + } + + public boolean isNaN() { + return isNaN(value); + } + public static double parseDouble(String s) { - // todo - throw new NumberFormatException(s); + int[] numRead = new int[1]; + double d = doubleFromString(s, numRead); + if (numRead[0] == 1) { + return d; + } else { + throw new NumberFormatException(s); + } } public static native int fillBufferWithDouble(double value, byte[] buffer, @@ -85,4 +102,10 @@ public final class Double extends Number { public static native long doubleToRawLongBits(double value); public static native double longBitsToDouble(long bits); + + public static native boolean isInfinite(double value); + + public static native boolean isNaN(double value); + + public static native double doubleFromString(String s, int[] numRead); } diff --git a/classpath/java/lang/Float.java b/classpath/java/lang/Float.java index 85e2b54d72..1e2c62972b 100644 --- a/classpath/java/lang/Float.java +++ b/classpath/java/lang/Float.java @@ -15,6 +15,10 @@ public final class Float extends Number { private final float value; + public Float(String value) { + this.value = parseFloat(value); + } + public Float(float value) { this.value = value; } @@ -23,6 +27,10 @@ public final class Float extends Number { return new Float(value); } + public static Float valueOf(String s) { + return new Float(s); + } + public boolean equals(Object o) { return o instanceof Float && ((Float) o).value == value; } @@ -63,12 +71,31 @@ public final class Float extends Number { return (double) value; } + public boolean isInfinite() { + return isInfinite(value); + } + + public boolean isNaN() { + return isNaN(value); + } + public static float parseFloat(String s) { - // todo - throw new NumberFormatException(s); + int[] numRead = new int[1]; + float f = floatFromString(s, numRead); + if (numRead[0] == 1) { + return f; + } else { + throw new NumberFormatException(s); + } } public static native int floatToRawIntBits(float value); public static native float intBitsToFloat(int bits); + + public static native boolean isInfinite(float value); + + public static native boolean isNaN(float value); + + public static native float floatFromString(String s, int[] numRead); } diff --git a/classpath/java/lang/StringBuilder.java b/classpath/java/lang/StringBuilder.java index e2968f9dab..e629a1aa26 100644 --- a/classpath/java/lang/StringBuilder.java +++ b/classpath/java/lang/StringBuilder.java @@ -118,7 +118,7 @@ public class StringBuilder { } public StringBuilder insert(int i, String s) { - if (i < 0 || i >= length) { + if (i < 0 || i > length) { throw new IndexOutOfBoundsException(); } diff --git a/classpath/java/util/ArrayList.java b/classpath/java/util/ArrayList.java index f8d3ba8ab1..00482f5722 100644 --- a/classpath/java/util/ArrayList.java +++ b/classpath/java/util/ArrayList.java @@ -24,11 +24,9 @@ public class ArrayList implements List { this(0); } - public ArrayList(Collection source) { + public ArrayList(Collection source) { this(source.size()); - for (T o : source) { - add(o); - } + addAll(source); } private void grow() { @@ -91,6 +89,11 @@ public class ArrayList implements List { return true; } + public boolean addAll(Collection collection) { + for (T t: collection) add(t); + return true; + } + public int indexOf(T element) { for (int i = 0; i < size; ++i) { if (equal(element, array[i])) { @@ -157,20 +160,7 @@ public class ArrayList implements List { } public S[] toArray(S[] a) { - Object[] retVal = null; - - if (a.length >= size) { - retVal = a; - } else { - retVal = new Object[size]; - } - for (int i = 0; i < size; ++i) { - retVal[i] = array[i]; - } - if (a.length > size) { - a[size] = null; - } - return (S[])retVal; + return Collections.toArray(this, a); } public void clear() { diff --git a/classpath/java/util/Arrays.java b/classpath/java/util/Arrays.java index dd2aba24b7..d51b8e6b7a 100644 --- a/classpath/java/util/Arrays.java +++ b/classpath/java/util/Arrays.java @@ -21,6 +21,14 @@ public class Arrays { return (a == null && b == null) || (a != null && a.equals(b)); } + public static void sort(Object[] array) { + sort(array, new Comparator() { + public int compare(Object a, Object b) { + return ((Comparable) a).compareTo(b); + } + }); + } + public static void sort(T[] array, Comparator comparator) { // insertion sort for (int j = 1; j < array.length; ++j) { @@ -48,6 +56,10 @@ public class Arrays { throw new UnsupportedOperationException(); } + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(); + } + public void add(int index, T element) { throw new UnsupportedOperationException(); } diff --git a/classpath/java/util/Collection.java b/classpath/java/util/Collection.java index 5ce1105811..cfde456aab 100644 --- a/classpath/java/util/Collection.java +++ b/classpath/java/util/Collection.java @@ -19,7 +19,11 @@ public interface Collection extends Iterable { public boolean add(T element); + public boolean addAll(Collection collection); + public boolean remove(T element); + public S[] toArray(S[] array); + public void clear(); } diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index afcc38391b..59c9a0d532 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -13,6 +13,25 @@ package java.util; public class Collections { private Collections() { } + static T[] toArray(Collection collection, T[] array) { + Class c = array.getClass().getComponentType(); + + if (array.length < collection.size()) { + array = (T[]) java.lang.reflect.Array.newInstance(c, collection.size()); + } + + int i = 0; + for (Object o: collection) { + if (c.isInstance(o)) { + array[i++] = (T) o; + } else { + throw new ArrayStoreException(); + } + } + + return array; + } + static String toString(Collection c) { StringBuilder sb = new StringBuilder(); sb.append("["); @@ -67,10 +86,18 @@ public class Collections { synchronized (lock) { return collection.add(e); } } + public boolean addAll(Collection collection) { + synchronized (lock) { return this.collection.addAll(collection); } + } + public boolean remove(T e) { synchronized (lock) { return collection.remove(e); } } + public T[] toArray(T[] array) { + synchronized (lock) { return collection.toArray(array); } + } + public void clear() { synchronized (lock) { collection.clear(); } } @@ -87,10 +114,6 @@ public class Collections { public SynchronizedSet(Object lock, Set set) { super(lock, set); } - - public void addAll(Collection c) { - synchronized (lock) { ((Set)collection).addAll(c); } - } } static class SynchronizedIterator implements Iterator { diff --git a/classpath/java/util/HashMap.java b/classpath/java/util/HashMap.java index b94bb54fd3..43ee2e8148 100644 --- a/classpath/java/util/HashMap.java +++ b/classpath/java/util/HashMap.java @@ -32,6 +32,13 @@ public class HashMap implements Map { this(0); } + public HashMap(Map map) { + this(map.size()); + for (Map.Entry entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"); @@ -307,10 +314,6 @@ public class HashMap implements Map { return HashMap.this.isEmpty(); } - public void addAll(Collection> c) { - throw new UnsupportedOperationException(); - } - public boolean contains(Entry e) { return containsKey(e.getKey()); } @@ -319,10 +322,20 @@ public class HashMap implements Map { return putCell(e.getKey(), e.getValue()) != null; } + public boolean addAll(Collection> collection) { + boolean change = false; + for (Entry e: collection) if (add(e)) change = true; + return change; + } + public boolean remove(Entry e) { return removeCell(e.getKey()) != null; } + public T[] toArray(T[] array) { + return Collections.toArray(this, array); + } + public void clear() { HashMap.this.clear(); } @@ -345,18 +358,24 @@ public class HashMap implements Map { return containsKey(key); } - public void addAll(Collection c) { - throw new UnsupportedOperationException(); - } - public boolean add(K key) { return putCell(key, null) != null; } + public boolean addAll(Collection collection) { + boolean change = false; + for (K k: collection) if (add(k)) change = true; + return change; + } + public boolean remove(K key) { return removeCell(key) != null; } + public T[] toArray(T[] array) { + return Collections.toArray(this, array); + } + public void clear() { HashMap.this.clear(); } @@ -384,10 +403,18 @@ public class HashMap implements Map { throw new UnsupportedOperationException(); } + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(); + } + public boolean remove(V value) { throw new UnsupportedOperationException(); } + public T[] toArray(T[] array) { + return Collections.toArray(this, array); + } + public void clear() { HashMap.this.clear(); } diff --git a/classpath/java/util/HashSet.java b/classpath/java/util/HashSet.java index 30207e61e1..690dc7cd3c 100644 --- a/classpath/java/util/HashSet.java +++ b/classpath/java/util/HashSet.java @@ -15,7 +15,7 @@ public class HashSet implements Set { private final HashMap map; - public HashSet(Collection c) { + public HashSet(Collection c) { map = new HashMap(c.size()); addAll(c); } @@ -40,18 +40,24 @@ public class HashSet implements Set { return map.containsKey(element); } - public void addAll(Collection c) { - for (T t: c) add(t); - } - public boolean add(T element) { return map.put(element, Value) != Value; } + public boolean addAll(Collection collection) { + boolean change = false; + for (T t: collection) if (add(t)) change = true; + return change; + } + public boolean remove(T element) { return map.remove(element) != Value; } + public T[] toArray(T[] array) { + return Collections.toArray(this, array); + } + public void clear() { map.clear(); } diff --git a/classpath/java/util/LinkedList.java b/classpath/java/util/LinkedList.java index 17e9ed24b7..a9f4c442ce 100644 --- a/classpath/java/util/LinkedList.java +++ b/classpath/java/util/LinkedList.java @@ -15,7 +15,7 @@ public class LinkedList implements List { private Cell rear; private int size; - public LinkedList(Collection c) { + public LinkedList(Collection c) { addAll(c); } @@ -86,20 +86,7 @@ public class LinkedList implements List { } public S[] toArray(S[] a) { - Object[] retVal = null; - if (a.length >= size) { - retVal = a; - } else { - retVal = new Object[size]; - } - int i=0; - for (Object o : this) { - retVal[i++] = o; - } - if (a.length > size) { - a[size] = null; - } - return (S[])retVal; + return Collections.toArray(this, a); } public int size() { @@ -119,6 +106,11 @@ public class LinkedList implements List { return true; } + public boolean addAll(Collection collection) { + for (T t: collection) add(t); + return true; + } + public void add(int index, T element) { if (index == 0) { addFirst(element); diff --git a/classpath/java/util/List.java b/classpath/java/util/List.java index 9c997daffa..0577e4b3e7 100644 --- a/classpath/java/util/List.java +++ b/classpath/java/util/List.java @@ -22,6 +22,4 @@ public interface List extends Collection { public void add(int index, T element); public boolean isEmpty(); - - public S[] toArray(S[] a); } diff --git a/classpath/java/util/Random.java b/classpath/java/util/Random.java index 975b5b8b13..2ab3f95a45 100644 --- a/classpath/java/util/Random.java +++ b/classpath/java/util/Random.java @@ -18,4 +18,8 @@ public class Random { public int nextInt() { return (int)(Math.random()*Integer.MAX_VALUE); } + + public double nextDouble() { + return Math.random(); + } } diff --git a/classpath/java/util/Set.java b/classpath/java/util/Set.java index 2ac227b70b..b1281aebbc 100644 --- a/classpath/java/util/Set.java +++ b/classpath/java/util/Set.java @@ -10,6 +10,4 @@ package java.util; -public interface Set extends Collection { - public void addAll(Collection c); -} +public interface Set extends Collection { } diff --git a/classpath/java/util/TreeSet.java b/classpath/java/util/TreeSet.java index 5deaca8cef..4a0c16cf4d 100644 --- a/classpath/java/util/TreeSet.java +++ b/classpath/java/util/TreeSet.java @@ -41,6 +41,12 @@ public class TreeSet implements Collection { return false; } + public boolean addAll(Collection collection) { + boolean change = false; + for (T t: collection) if (add(t)) change = true; + return change; + } + // Used by hashMaps for replacement public void addAndReplace(T value) { PersistentSet.Path> p = set.find(new Cell(value, null)); @@ -69,6 +75,10 @@ public class TreeSet implements Collection { } } + public T[] toArray(T[] array) { + return Collections.toArray(this, array); + } + public int size() { return size; } diff --git a/classpath/java/util/Vector.java b/classpath/java/util/Vector.java index 138cfbd665..20d6a8323e 100644 --- a/classpath/java/util/Vector.java +++ b/classpath/java/util/Vector.java @@ -21,11 +21,8 @@ public class Vector implements List { this(0); } - public Vector(List list) { - this(list.size()); - for (T o : list) { - add(o); - } + public Vector(Collection source) { + list = new ArrayList(source); } public synchronized int size() { @@ -44,6 +41,10 @@ public class Vector implements List { return list.add(element); } + public synchronized boolean addAll(Collection collection) { + return list.addAll(collection); + } + public void addElement(T element) { add(element); } diff --git a/makefile b/makefile index aede4afc31..e4c489b2a9 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,7 @@ #MAKEFLAGS = -s name = avian +version = 0.0.1 build-arch = $(shell uname -m) ifeq ($(build-arch),i586) @@ -22,6 +23,7 @@ endif mode = fast process = compile +root = $(shell (cd .. && pwd)) build = build native-build = $(build)/$(platform)-$(arch)-$(process)-$(mode) classpath-build = $(build)/classpath @@ -55,7 +57,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter \ common-cflags = $(warnings) -fno-rtti -fno-exceptions \ -I$(JAVA_HOME)/include -idirafter $(src) -I$(native-build) \ - -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ + -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ -I$(JAVA_HOME)/include/linux -I$(src) -pthread @@ -88,8 +90,8 @@ ifeq ($(platform),darwin) endif ifeq ($(platform),windows) - inc = /usr/local/win32/include - lib = /usr/local/win32/lib + inc = $(root)/win32/include + lib = $(root)/win32/lib system = windows object-format = pe-i386 @@ -266,7 +268,7 @@ $(classpath-dep): $(classpath-sources) @echo "compiling classpath classes" @mkdir -p $(dir $(@)) $(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \ - $(shell make -s $(classpath-classes)) + $(shell make -s --no-print-directory $(classpath-classes)) @touch $(@) $(test-build)/%.class: $(test)/%.java @@ -276,7 +278,7 @@ $(test-dep): $(test-sources) @echo "compiling test classes" @mkdir -p $(dir $(@)) $(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \ - $(shell make -s $(test-classes)) + $(shell make -s --no-print-directory $(test-classes)) @touch $(@) define compile-object diff --git a/readme.txt b/readme.txt index b1b2eca1b2..608e7cc42b 100644 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Quick Start ----------- on Linux: - $ export JAVA_HOME=/usr/local/java + $ export JAVA_HOME=/usr/local/java # or wherever you have Java installed $ make $ build/linux-i386-compile-fast/avian -cp build/test Hello @@ -12,6 +12,25 @@ on Mac OS X: $ build/darwin-i386-compile-fast/avian -cp build/test Hello +Introduction +------------ + +Avian is a lightweight virtual machine and class library designed to +provide a useful subset of Java's features, suitable for building +self-contained applications. More information is available at the +project web site: + + http://oss.readytalk.com/avian + +If you have any trouble building, running, or embedding Avian, please +post a message to our discussion group: + + http://groups.google.com/group/avian + +That's also the place for any other questions, comments, or +suggestions you might have. + + Supported Platforms ------------------- @@ -29,6 +48,27 @@ but patches to enable them are welcome. Building -------- +Build requirements include: + + * GNU make 3.80 or later + * GCC 3.4 or later + * JDK 1.5 or later + * GNU binutils 2.17 or later (not needed on OS X) + * MinGW 3.4 or later (only if cross-compiling for Windows) + * zlib 1.2.3 or later + +Earlier versions of some of these packages may also work but have not +been tested. + +If you are cross-compiling for Windows, you may find it useful to use +our win32 repository: (run this from the directory containing the +avian directory) + + $ git clone git://oss.readytalk.com/win32.git + +This gives you the Windows JNI headers, zlib headers and library, and +a few other useful libraries like OpenSSL and libjpeg. + The build is directed by a single makefile and may be influenced via certain flags described below. @@ -43,7 +83,7 @@ certain flags described below. * mode - which set of compilation flags to use, which determine optimization level, debug symbols, and whether to enable - assertions. + assertions default: fast * process - choice between pure interpreter or JIT compiler diff --git a/src/builtin.cpp b/src/builtin.cpp index 58b4199cab..f711e86808 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -441,7 +441,7 @@ Java_java_lang_System_getVMProperty(Thread* t, jclass, jstring name, if (strcmp(n, "java.lang.classpath") == 0) { r = makeLocalReference(t, makeString(t, "%s", t->m->finder->path())); } else if (strcmp(n, "avian.version") == 0) { - r = makeLocalReference(t, makeString(t, "0.0")); + r = makeLocalReference(t, makeString(t, AVIAN_VERSION)); } if (r) { diff --git a/src/compile.cpp b/src/compile.cpp index c30ccebacd..3fde1abb61 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -427,6 +427,7 @@ class Context { TraceElement* traceLog; uint16_t* visitTable; uintptr_t* rootTable; + bool dirtyRoots; Vector eventLog; MyProtector protector; }; @@ -3297,7 +3298,8 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, // that position, or the contents of that position are as yet // unknown. - while (eventIndex < context->eventLog.length()) { + unsigned length = context->eventLog.length(); + while (eventIndex < length) { Event e = static_cast(context->eventLog.get(eventIndex++)); switch (e) { case PushEvent: { @@ -3309,6 +3311,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, case IpEvent: { ip = context->eventLog.get2(eventIndex); + eventIndex += 2; if (DebugFrameMaps) { fprintf(stderr, " roots at ip %3d: ", ip); @@ -3320,7 +3323,20 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, if (context->visitTable[ip] > 1) { for (unsigned wi = 0; wi < mapSize; ++wi) { - tableRoots[wi] &= roots[wi]; + uintptr_t newRoots = tableRoots[wi] & roots[wi]; + + if ((eventIndex == length + or context->eventLog.get(eventIndex) == PopEvent) + and newRoots != tableRoots[wi]) + { + if (DebugFrameMaps) { + fprintf(stderr, "dirty roots!\n"); + } + + context->dirtyRoots = true; + } + + tableRoots[wi] = newRoots; roots[wi] &= tableRoots[wi]; } @@ -3332,92 +3348,20 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, } else { memcpy(tableRoots, roots, mapSize * BytesPerWord); } - - eventIndex += 2; } break; case MarkEvent: { unsigned i = context->eventLog.get2(eventIndex); - markBit(roots, i); - eventIndex += 2; + + markBit(roots, i); } break; case ClearEvent: { unsigned i = context->eventLog.get2(eventIndex); + eventIndex += 2; + clearBit(roots, i); - - eventIndex += 2; - } break; - - case TraceEvent: { - eventIndex += BytesPerWord; - } break; - - default: abort(t); - } - } - - return eventIndex; -} - -unsigned -updateTraceElements(MyThread* t, Context* context, uintptr_t* originalRoots, - unsigned eventIndex) -{ - unsigned mapSize = frameMapSizeInWords(t, context->method); - - uintptr_t roots[mapSize]; - if (originalRoots) { - memcpy(roots, originalRoots, mapSize * BytesPerWord); - } else { - memset(roots, 0, mapSize * BytesPerWord); - } - - int32_t ip = -1; - - while (eventIndex < context->eventLog.length()) { - Event e = static_cast(context->eventLog.get(eventIndex++)); - switch (e) { - case PushEvent: { - eventIndex = updateTraceElements(t, context, roots, eventIndex); - } break; - - case PopEvent: - return eventIndex; - - case IpEvent: { - ip = context->eventLog.get2(eventIndex); - - if (DebugFrameMaps) { - fprintf(stderr, " map at ip %3d: ", ip); - printSet(*roots); - fprintf(stderr, "\n"); - } - - if (context->visitTable[ip] > 1) { - uintptr_t* tableRoots = context->rootTable + (ip * mapSize); - - for (unsigned wi = 0; wi < mapSize; ++wi) { - roots[wi] &= tableRoots[wi]; - } - } - - eventIndex += 2; - } break; - - case MarkEvent: { - unsigned i = context->eventLog.get2(eventIndex); - markBit(roots, i); - - eventIndex += 2; - } break; - - case ClearEvent: { - unsigned i = context->eventLog.get2(eventIndex); - clearBit(roots, i); - - eventIndex += 2; } break; case TraceEvent: { @@ -3586,6 +3530,7 @@ compile(MyThread* t, Context* context) compile(t, &frame, 0); if (UNLIKELY(t->exception)) return 0; + context->dirtyRoots = false; unsigned eventIndex = calculateFrameMaps(t, context, 0, 0); object eht = codeExceptionHandlerTable(t, methodCode(t, context->method)); @@ -3642,7 +3587,10 @@ compile(MyThread* t, Context* context) } } - updateTraceElements(t, context, 0, 0); + while (context->dirtyRoots) { + context->dirtyRoots = false; + calculateFrameMaps(t, context, 0, 0); + } return finish(t, context); } diff --git a/test/GC.java b/test/GC.java index 2b9b46fc8d..eb657ef786 100644 --- a/test/GC.java +++ b/test/GC.java @@ -87,6 +87,23 @@ public class GC { System.gc(); } + private static void stackMap6(boolean predicate) { + if (predicate) { + int a = 42; + } else { + Object a = null; + } + + if (predicate) { + noop(); + } else { + Object a = null; + } + + noop(); + System.gc(); + } + public static void main(String[] args) { Object[] array = new Object[1024 * 1024]; array[0] = new Object(); @@ -119,6 +136,9 @@ public class GC { stackMap5(true); stackMap5(false); + + stackMap6(true); + stackMap6(false); } } diff --git a/test/test.sh b/test/test.sh index ffdeca54fb..cfd03fe2df 100644 --- a/test/test.sh +++ b/test/test.sh @@ -17,7 +17,7 @@ for test in ${tests}; do printf "%16s" "${test}: " case ${mode} in - debug ) + debug|debug-fast|fast ) ${vm} ${flags} ${test} >>${log} 2>&1;; stress* ) diff --git a/vm.pro b/vm.pro index 99da344d58..7e024896ce 100644 --- a/vm.pro +++ b/vm.pro @@ -59,6 +59,11 @@ -keepnames public class java.lang.** +# Don't optimize calls to ResourceBundle +-keep,allowshrinking,allowobfuscation public class java.util.ResourceBundle { + public static java.util.ResourceBundle getBundle(...); +} + # musn't obfuscate native method names: -keepclasseswithmembernames class * {