diff --git a/classpath/java/lang/AssertionError.java b/classpath/java/lang/AssertionError.java new file mode 100644 index 0000000000..ba5d2589e4 --- /dev/null +++ b/classpath/java/lang/AssertionError.java @@ -0,0 +1,45 @@ +/* Copyright (c) 2008, 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.lang; + +public class AssertionError extends Error { + public AssertionError() { + super("", null); + } + + public AssertionError(boolean detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(char detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(double detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(float detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(int detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(long detailMessage) { + super(""+detailMessage, null); + } + + public AssertionError(Object detailMessage) { + super(""+detailMessage, null); + } +} diff --git a/classpath/java/lang/Character.java b/classpath/java/lang/Character.java index 6627ae3170..7d097366a8 100644 --- a/classpath/java/lang/Character.java +++ b/classpath/java/lang/Character.java @@ -96,6 +96,8 @@ public final class Character implements Comparable { digit = c - '0'; } else if ((c >= 'a') && (c <= 'z')) { digit = c - 'a' + 10; + } else if ((c >= 'A') && (c <= 'Z')) { + digit = c - 'A' + 10; } else { return -1; } diff --git a/classpath/java/lang/Enum.java b/classpath/java/lang/Enum.java index 21485d2625..5edcbf6cd5 100644 --- a/classpath/java/lang/Enum.java +++ b/classpath/java/lang/Enum.java @@ -46,6 +46,10 @@ public abstract class Enum> implements Comparable { return ordinal; } + public final String name() { + return name; + } + public String toString() { return name; } diff --git a/classpath/java/lang/Override.java b/classpath/java/lang/Override.java index ce25b9559a..428ae9c4f0 100644 --- a/classpath/java/lang/Override.java +++ b/classpath/java/lang/Override.java @@ -1,3 +1,13 @@ +/* Copyright (c) 2008, 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.lang; public @interface Override { diff --git a/classpath/java/lang/SuppressWarnings.java b/classpath/java/lang/SuppressWarnings.java index 5e35ed01ba..6862f2df87 100644 --- a/classpath/java/lang/SuppressWarnings.java +++ b/classpath/java/lang/SuppressWarnings.java @@ -1,3 +1,13 @@ +/* Copyright (c) 2008, 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.lang; diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 08a9d23b5f..39a9328c29 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -17,6 +17,7 @@ public class Method extends AccessibleObject implements Member { private byte parameterFootprint; private short flags; private short offset; + private int nativeID; private byte[] name; private byte[] spec; private Class class_; diff --git a/classpath/java/nio/ByteBuffer.java b/classpath/java/nio/ByteBuffer.java index d06b239735..e8191f90a3 100644 --- a/classpath/java/nio/ByteBuffer.java +++ b/classpath/java/nio/ByteBuffer.java @@ -149,6 +149,16 @@ public class ByteBuffer extends Buffer implements Comparable { return array[arrayOffset+position]; } + public int getInt(int position) { + checkGet(position, 4); + + int p = arrayOffset + position; + return ((array[p] & 0xFF) << 24) + | ((array[p + 1] & 0xFF) << 16) + | ((array[p + 2] & 0xFF) << 8) + | ((array[p + 3] & 0xFF)); + } + public int getInt() { checkGet(4); int i = get() << 24; diff --git a/src/compile.cpp b/src/compile.cpp index fdc503e2b8..30124ebdcb 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -215,10 +215,8 @@ class MyStackWalker: public Processor::StackWalker { if (trace and trace->nativeMethod) { method_ = trace->nativeMethod; state = NativeMethod; - } else if (ip_) { - state = Next; } else { - state = Finish; + state = Next; } break; @@ -228,16 +226,14 @@ class MyStackWalker: public Processor::StackWalker { if (method_) { state = Method; } else if (trace) { - base = trace->base; stack = static_cast(trace->stack); ip_ = (stack ? *static_cast(stack) : 0); + base = trace->base; + trace = trace->next; - if (trace->nativeMethod) { + if (trace and trace->nativeMethod) { method_ = trace->nativeMethod; state = NativeMethod; - } else { - trace = trace->next; - state = Next; } } else { state = Finish; @@ -266,30 +262,23 @@ class MyStackWalker: public Processor::StackWalker { stack = static_cast(base) + 1; ip_ = (stack ? *static_cast(stack) : 0); base = *static_cast(base); - state = Next; break; case NativeMethod: - trace = trace->next; - state = Next; break; default: abort(t); } + + state = Next; } virtual object method() { - switch (state) { - case Method: - return method_; - - case NativeMethod: - return trace->nativeMethod; - - default: - abort(t); - } +// fprintf(stderr, "method %s.%s\n", &byteArrayBody +// (t, className(t, methodClass(t, method_)), 0), +// &byteArrayBody(t, methodName(t, method_), 0)); + return method_; } virtual int ip() { @@ -4595,7 +4584,7 @@ class MyProcessor: public Processor { { return vm::makeMethod (t, vmFlags, returnCode, parameterCount, parameterFootprint, flags, - offset, name, spec, class_, code, + offset, 0, name, spec, class_, code, ::defaultThunk(static_cast(t))); } @@ -5137,6 +5126,7 @@ compile(MyThread* t, object method) methodParameterFootprint(t, method), methodFlags(t, method), methodOffset(t, method), + methodNativeID(t, method), methodName(t, method), methodSpec(t, method), methodClass(t, method), diff --git a/src/jnienv.cpp b/src/jnienv.cpp index ab0f18a304..329e948687 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -34,6 +34,14 @@ DestroyJavaVM(Machine* m) Finder* f = m->finder; Thread* t = m->rootThread; + // wait for other threads to exit + { ACQUIRE(t, m->stateLock); + + while (m->liveCount > 1) { + t->m->stateLock->wait(t->systemThread, 0); + } + } + int exitCode = (t->exception ? -1 : 0); enter(t, Thread::ActiveState); t->exit(); @@ -272,6 +280,23 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec) return vm::findMethod(t, *c, n, s); } +jint +methodID(Thread* t, object method) +{ + if (methodNativeID(t, method) == 0) { + PROTECT(t, method); + + ACQUIRE(t, t->m->referenceLock); + + if (methodNativeID(t, method) == 0) { + t->m->jniMethodTable = vectorAppend(t, t->m->jniMethodTable, method); + methodNativeID(t, method) = vectorSize(t, t->m->jniMethodTable); + } + } + + return methodNativeID(t, method); +} + jmethodID JNICALL GetMethodID(Thread* t, jclass c, const char* name, const char* spec) { @@ -280,26 +305,9 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec) object method = findMethod(t, c, name, spec); if (UNLIKELY(t->exception)) return 0; - if (classFlags(t, *c) & ACC_INTERFACE) { - PROTECT(t, method); + assert(t, (methodFlags(t, method) & ACC_STATIC) == 0); - ACQUIRE(t, t->m->referenceLock); - - for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) { - if (method == vectorBody(t, t->m->jniInterfaceTable, i)) { - return i; - } - } - - t->m->jniInterfaceTable - = vectorAppend(t, t->m->jniInterfaceTable, method); - - return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID; - } else if (methodVirtual(t, method)) { - return methodOffset(t, method) + 1; - } else { - return methodOffset(t, method) | NonVirtualMethodID; - } + return methodID(t, method); } jmethodID JNICALL @@ -310,29 +318,19 @@ GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec) object method = findMethod(t, c, name, spec); if (UNLIKELY(t->exception)) return 0; - return methodOffset(t, method) + 1; + assert(t, methodFlags(t, method) & ACC_STATIC); + + return methodID(t, method); } inline object -getMethod(Thread* t, object o, jmethodID m) +getMethod(Thread* t, jmethodID m) { - if (m & InterfaceMethodID) { - return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); - } else { - if (classVmFlags(t, objectClass(t, o)) & BootstrapFlag) { - PROTECT(t, o); + object method = vectorBody(t, t->m->jniMethodTable, m - 1); - resolveClass(t, className(t, objectClass(t, o))); - if (UNLIKELY(t->exception)) return 0; - } + assert(t, (methodFlags(t, method) & ACC_STATIC) == 0); - if (m & NonVirtualMethodID) { - return arrayBody(t, classMethodTable(t, objectClass(t, o)), - m & (~NonVirtualMethodID)); - } else { - return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); - } - } + return method; } jobject JNICALL @@ -343,7 +341,7 @@ NewObjectV(Thread* t, jclass c, jmethodID m, va_list a) object o = make(t, *c); PROTECT(t, o); - t->m->processor->invokeList(t, getMethod(t, o, m), o, true, a); + t->m->processor->invokeList(t, getMethod(t, m), o, true, a); return makeLocalReference(t, o); } @@ -366,7 +364,7 @@ CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); return makeLocalReference (t, t->m->processor->invokeList(t, method, *o, true, a)); } @@ -389,7 +387,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? false : (intValue(t, r) != 0)); } @@ -412,7 +410,7 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -435,7 +433,7 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -458,7 +456,7 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -481,7 +479,7 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -504,7 +502,7 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -527,7 +525,7 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } @@ -550,7 +548,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } @@ -573,7 +571,7 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); t->m->processor->invokeList(t, method, *o, true, a); } @@ -589,25 +587,22 @@ CallVoidMethod(Thread* t, jobject o, jmethodID m, ...) } inline object -getStaticMethod(Thread* t, object c, jmethodID m) +getStaticMethod(Thread* t, jmethodID m) { - if (classVmFlags(t, c) & BootstrapFlag) { - PROTECT(t, c); + object method = vectorBody(t, t->m->jniMethodTable, m - 1); - resolveClass(t, className(t, c)); - if (UNLIKELY(t->exception)) return 0; - } + assert(t, methodFlags(t, method) & ACC_STATIC); - return arrayBody(t, classMethodTable(t, c), m - 1); + return method; } jobject JNICALL -CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticObjectMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a)); + (t, getStaticMethod(t, m), 0, true, a)); } jobject JNICALL @@ -624,12 +619,11 @@ CallStaticObjectMethod(Thread* t, jclass c, jmethodID m, ...) } jboolean JNICALL -CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticBooleanMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : (intValue(t, r) != 0)); } @@ -647,12 +641,11 @@ CallStaticBooleanMethod(Thread* t, jclass c, jmethodID m, ...) } jbyte JNICALL -CallStaticByteMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticByteMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -670,12 +663,11 @@ CallStaticByteMethod(Thread* t, jclass c, jmethodID m, ...) } jchar JNICALL -CallStaticCharMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticCharMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -693,12 +685,11 @@ CallStaticCharMethod(Thread* t, jclass c, jmethodID m, ...) } jshort JNICALL -CallStaticShortMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticShortMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -716,12 +707,11 @@ CallStaticShortMethod(Thread* t, jclass c, jmethodID m, ...) } jint JNICALL -CallStaticIntMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticIntMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -739,12 +729,11 @@ CallStaticIntMethod(Thread* t, jclass c, jmethodID m, ...) } jlong JNICALL -CallStaticLongMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticLongMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -762,12 +751,11 @@ CallStaticLongMethod(Thread* t, jclass c, jmethodID m, ...) } jfloat JNICALL -CallStaticFloatMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticFloatMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } @@ -785,12 +773,11 @@ CallStaticFloatMethod(Thread* t, jclass c, jmethodID m, ...) } jdouble JNICALL -CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticDoubleMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } @@ -808,11 +795,11 @@ CallStaticDoubleMethod(Thread* t, jclass c, jmethodID m, ...) } void JNICALL -CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticVoidMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - t->m->processor->invokeList(t, getStaticMethod(t, *c, m), 0, true, a); + t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); } void JNICALL diff --git a/src/machine.cpp b/src/machine.cpp index ef44e79169..2bf6674f10 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -356,15 +356,7 @@ postVisit(Thread* t, Heap::Visitor* v) Machine* m = t->m; bool major = m->heap->collectionType() == Heap::MajorCollection; - for (object* p = &(m->finalizeQueue); *p; p = &(finalizerNext(t, *p))) { - v->visit(p); - v->visit(&finalizerTarget(t, *p)); - } - - for (object* p = &(m->finalizeQueue); *p; p = &(finalizerNext(t, *p))) { - v->visit(p); - v->visit(&finalizerTarget(t, *p)); - } + assert(t, m->finalizeQueue == 0); object firstNewTenuredFinalizer = 0; object lastNewTenuredFinalizer = 0; @@ -469,7 +461,8 @@ postVisit(Thread* t, Heap::Visitor* v) } if (lastNewTenuredWeakReference) { - jreferenceVmNext(t, lastNewTenuredWeakReference) = m->tenuredWeakReferences; + jreferenceVmNext(t, lastNewTenuredWeakReference) + = m->tenuredWeakReferences; m->tenuredWeakReferences = firstNewTenuredWeakReference; } } @@ -1095,6 +1088,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) methodParameterFootprint(t, method), methodFlags(t, method), virtualCount++, + 0, methodName(t, method), methodSpec(t, method), class_, @@ -1457,7 +1451,7 @@ removeMonitor(Thread* t, object o) object p = hashMapRemove(t, t->m->monitorMap, o, objectHash, objectEqual); - assert(t, p); + expect(t, p); if (DebugMonitors) { fprintf(stderr, "dispose monitor %p for object %x\n", @@ -1545,7 +1539,7 @@ class HeapClient: public Heap::Client { v->visit(&(m->monitorMap)); v->visit(&(m->stringMap)); v->visit(&(m->types)); - v->visit(&(m->jniInterfaceTable)); + v->visit(&(m->jniMethodTable)); for (Reference* r = m->jniReferences; r; r = r->next) { v->visit(&(r->target)); @@ -1665,7 +1659,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder, monitorMap(0), stringMap(0), types(0), - jniInterfaceTable(0), + jniMethodTable(0), finalizers(0), tenuredFinalizers(0), finalizeQueue(0), @@ -1826,14 +1820,14 @@ Thread::init() m->monitorMap = makeWeakHashMap(this, 0, 0); m->stringMap = makeWeakHashMap(this, 0, 0); - m->jniInterfaceTable = makeVector(this, 0, 0, false); + m->jniMethodTable = makeVector(this, 0, 0, false); m->localThread->set(this); { object bootCode = makeCode(t, 0, 0, 0, 0, 0, 1, false); codeBody(t, bootCode, 0) = impdep1; object bootMethod = makeMethod - (t, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode, 0); + (t, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode, 0); PROTECT(t, bootMethod); #include "type-java-initializations.cpp" diff --git a/src/machine.h b/src/machine.h index 9a8764a893..7e4f235979 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1174,7 +1174,7 @@ class Machine { object monitorMap; object stringMap; object types; - object jniInterfaceTable; + object jniMethodTable; object finalizers; object tenuredFinalizers; object finalizeQueue; diff --git a/src/util.cpp b/src/util.cpp index f1a47206c1..219695a536 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -340,9 +340,9 @@ void hashMapInsert(Thread* t, object map, object key, object value, uint32_t (*hash)(Thread*, object)) { - // note that we reinitialize the array and index variables whenever - // an allocation (and thus possibly a collection) occurs, in case - // the array changes due to a table resize. + // note that we reinitialize the array variable whenever an + // allocation (and thus possibly a collection) occurs, in case the + // array changes due to a table resize. PROTECT(t, map); @@ -378,13 +378,13 @@ hashMapInsert(Thread* t, object map, object key, object value, array = hashMapArray(t, map); } - unsigned index = h & (arrayLength(t, array) - 1); - - object n = makeTriple(t, k, value, arrayBody(t, array, index)); + object n = makeTriple(t, k, value, 0); array = hashMapArray(t, map); - index = h & (arrayLength(t, array) - 1); + unsigned index = h & (arrayLength(t, array) - 1); + + set(t, n, TripleThird, arrayBody(t, array, index)); set(t, array, ArrayBody + (index * BytesPerWord), n); } diff --git a/src/x86.cpp b/src/x86.cpp index 627242cbbd..e45cb97a05 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -1694,6 +1694,18 @@ compareRM(Context* c, unsigned size, Assembler::Register* a, encode(c, 0x39, a->low, b, true); } +void +compareAM(Context* c, unsigned size, Assembler::Address* a, + Assembler::Memory* b) +{ + assert(c, BytesPerWord == 8 or size == 4); + + Assembler::Register tmp(c->client->acquireTemporary()); + moveAR(c, size, a, &tmp); + compareRM(c, size, &tmp, b); + c->client->releaseTemporary(tmp.low); +} + void compareMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b) @@ -1984,6 +1996,7 @@ populateTables() BinaryOperations[INDEX2(Compare, Register, Constant)] = CAST2(compareRC); BinaryOperations[INDEX2(Compare, Register, Register)] = CAST2(compareRR); BinaryOperations[INDEX2(Compare, Address, Register)] = CAST2(compareAR); + BinaryOperations[INDEX2(Compare, Address, Memory)] = CAST2(compareAM); BinaryOperations[INDEX2(Compare, Register, Memory)] = CAST2(compareRM); BinaryOperations[INDEX2(Compare, Memory, Register)] = CAST2(compareMR); BinaryOperations[INDEX2(Compare, Constant, Memory)] = CAST2(compareCM);