diff --git a/src/types.def b/src/types.def index 4a660da928..72ea4c346b 100644 --- a/src/types.def +++ b/src/types.def @@ -1,12 +1,12 @@ (type class - (uint32_t id) + (uint16_t flags) (uint16_t fixedSize) (uint16_t arrayElementSize) (object objectMask) - (uint16_t flags) (object name) (object super) (object interfaceTable) + (object virtualTable) (object fieldTable) (object methodTable) (object staticTable) @@ -72,6 +72,15 @@ (object second) (object third)) +(type hashMap + (object size) + (object array)) + +(type list + (object size) + (object front) + (object rear)) + (type trace (object method) (uint32_t ip) @@ -148,7 +157,7 @@ (type double (uint64_t value)) -(type rawArray +(type array (array object body)) (type objectArray diff --git a/src/vm.cpp b/src/vm.cpp index 111c3df1b1..f0920d3680 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -17,21 +17,23 @@ typedef unsigned Type; #include "constants.h" -enum ObjectType { - NullType, - CollectedType, - -#include "type-enums.h" - - OtherType -}; - class Thread; -Type typeOf(object); -object& objectClass(object); void assert(Thread* t, bool v); +template +inline T& +cast(object p, unsigned offset) +{ + return *reinterpret_cast(static_cast(p) + offset); +} + +object& +objectClass(object o) +{ + return cast(o, 0); +} + #include "type-header.h" class Machine { @@ -395,13 +397,6 @@ make(Thread* t, object class_) return instance; } -template -inline T& -cast(object p, unsigned offset) -{ - return *reinterpret_cast(static_cast(p) + offset); -} - object makeString(Thread* t, const char* format, ...) { @@ -493,15 +488,16 @@ makeNoSuchMethodError(Thread* t, object message) } inline bool -isLongOrDouble(object o) +isLongOrDouble(Thread* t, object o) { - return typeOf(o) == LongType or typeOf(o) == DoubleType; + return objectClass(o) == t->vm->longClass + or objectClass(o) == t->vm->doubleClass; } inline object getField(Thread* t, object instance, object field) { - switch (rawArrayBody(t, fieldSpec(t, field))[0]) { + switch (arrayBody(t, fieldSpec(t, field))[0]) { case 'B': return makeByte(t, cast(instance, fieldOffset(t, field))); case 'C': @@ -529,7 +525,7 @@ getField(Thread* t, object instance, object field) inline void setField(Thread* t, object o, object field, object value) { - switch (rawArrayBody(t, fieldSpec(t, field))[0]) { + switch (arrayBody(t, fieldSpec(t, field))[0]) { case 'B': cast(o, fieldOffset(t, field)) = byteValue(t, value); break; @@ -565,14 +561,14 @@ setField(Thread* t, object o, object field, object value) inline object getStatic(Thread* t, object field) { - return rawArrayBody(t, classStaticTable(t, fieldClass(t, field))) + return arrayBody(t, classStaticTable(t, fieldClass(t, field))) [fieldOffset(t, field)]; } inline void setStatic(Thread* t, object field, object value) { - set(t, rawArrayBody(t, classStaticTable(t, fieldClass(t, field))) + set(t, arrayBody(t, classStaticTable(t, fieldClass(t, field))) [fieldOffset(t, field)], value); } @@ -583,20 +579,18 @@ instanceOf(Thread* t, object class_, object o) return false; } - if (typeOf(class_) == InterfaceType) { - Type id = interfaceId(t, class_); + if (objectClass(class_) == t->vm->interfaceClass) { for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { object itable = classInterfaceTable(t, oc); - for (unsigned i = 0; i < rawArrayLength(t, itable); i += 2) { - if (interfaceId(t, rawArrayBody(t, itable)[i]) == id) { + for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { + if (arrayBody(t, itable)[i] == class_) { return true; } } } } else { - Type id = classId(t, class_); for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { - if (classId(t, oc) == id) { + if (oc == class_) { return true; } } @@ -608,11 +602,11 @@ instanceOf(Thread* t, object class_, object o) object findInterfaceMethod(Thread* t, object method, object o) { - Type id = interfaceId(t, methodClass(t, method)); + object interface = methodClass(t, method); object itable = classInterfaceTable(t, objectClass(o)); - for (unsigned i = 0; i < rawArrayLength(t, itable); i += 2) { - if (interfaceId(t, rawArrayBody(t, itable)[i]) == id) { - return rawArrayBody(t, rawArrayBody(t, itable)[i + 1]) + for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { + if (arrayBody(t, itable)[i] == interface) { + return arrayBody(t, arrayBody(t, itable)[i + 1]) [methodOffset(t, method)]; } } @@ -622,7 +616,7 @@ findInterfaceMethod(Thread* t, object method, object o) inline object findMethod(Thread* t, object method, object class_) { - return rawArrayBody(t, classMethodTable(t, class_)) + return arrayBody(t, classVirtualTable(t, class_)) [methodOffset(t, method)]; } @@ -635,9 +629,8 @@ findVirtualMethod(Thread* t, object method, object o) bool isSuperclass(Thread* t, object class_, object base) { - Type id = classId(t, class_); for (object oc = classSuper(t, base); oc; oc = classSuper(t, oc)) { - if (classId(t, oc) == id) { + if (oc == class_) { return true; } } @@ -668,8 +661,8 @@ find(Thread* t, object class_, object table, object reference, { object n = referenceName(t, reference); object s = referenceSpec(t, reference); - for (unsigned i = 0; i < rawArrayLength(t, table); ++i) { - object field = rawArrayBody(t, table)[i]; + for (unsigned i = 0; i < arrayLength(t, table); ++i) { + object field = arrayBody(t, table)[i]; if (strcmp(byteArrayBody(t, name(t, field)), byteArrayBody(t, n)) == 0 and strcmp(byteArrayBody(t, spec(t, field)), @@ -711,11 +704,18 @@ hash(const int8_t* s, unsigned length) } inline uint32_t -hashByteArray(Thread* t, object array) +byteArrayHash(Thread* t, object array) { return hash(byteArrayBody(t, array), byteArrayLength(t, array) - 1); } +inline uint32_t +methodHash(Thread* t, object method) +{ + return byteArrayHash(t, methodName(t, method)) + ^ byteArrayHash(t, methodSpec(t, method)); +} + bool byteArrayEqual(Thread* t, object a, object b) { @@ -725,32 +725,104 @@ byteArrayEqual(Thread* t, object a, object b) } object -hashMapFind(Thread* t, object map, uint32_t hash, object key, - bool (*equal)(Thread*, object, object)) +hashMapFindNode(Thread* t, object map, object key, + uint32_t (*hash)(Thread*, object), + bool (*equal)(Thread*, object, object)) { - unsigned index = hash & (rawArrayLength(t, map) - 1); - object n = rawArrayBody(t, map)[index]; - while (n) { - if (equal(t, tripleFirst(t, n), key)) { - return tripleSecond(t, n); + object array = hashMapArray(t, map); + if (array) { + unsigned index = hash(t, key) & (arrayLength(t, array) - 1); + object n = arrayBody(t, array)[index]; + while (n) { + if (equal(t, tripleFirst(t, n), key)) { + return n; + } + + n = tripleThird(t, n); } - - n = tripleThird(t, n); } return 0; } -object -hashMapInsert(Thread* t, object map, uint32_t hash, object key, object value) +inline object +hashMapFind(Thread* t, object map, object key, + uint32_t (*hash)(Thread*, object), + bool (*equal)(Thread*, object, object)) { - unsigned index = hash & (rawArrayLength(t, map) - 1); - object n = rawArrayBody(t, map)[index]; + object n = hashMapFindNode(t, map, key, hash, equal); + return (n ? tripleSecond(t, n) : 0); +} +void +hashMapGrow(Thread* t, object map, uint32_t (*hash)(Thread*, object)) +{ PROTECT(t, map); + object oldArray = hashMapArray(t, map); + unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0); + PROTECT(t, oldArray); + + unsigned newLength = (oldLength ? oldLength * 2 : 32); + object newArray = makeArray(t, newLength); + memset(arrayBody(t, newArray), o, newLength * sizeof(object)); + + if (oldArray) { + for (unsigned i = 0; i < length; ++i) { + object next; + for (object p = arrayBody(t, oldArray)[i]; p; p = next) { + next = tripleThird(t, p); + + object key = tripleFirst(t, p); + unsigned index = hash(t, key) & (newLength - 1); + object n = arrayBody(t, newArray)[index]; + + set(t, tripleThird(t, p), n); + set(t, arrayBody(t, newArray)[index], p); + } + } + } + + set(t, hashMapArray(t, map), newArray); +} + +void +hashMapInsert(Thread* t, object map, object key, object value, + uint32_t (*hash)(Thread*, object)) +{ + PROTECT(t, map); + + object array = hashMapArray(t, map); + PROTECT(t, array); + + ++ hashMapSize(t, map); + + if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) { + hashMapGrow(t, map, hash); + array = hashMapArray(t, map); + } + + unsigned index = hash & (arrayLength(t, array) - 1); + object n = arrayBody(t, array)[index]; + n = makeTriple(t, key, value, n); - set(t, rawArrayBody(t, map)[index], n); + set(t, arrayBody(t, array)[index], n); +} + +void +listAppend(Thread* t, object list, object value) +{ + PROTECT(t, list); + + ++ listSize(t, list); + + object p = makePair(t, value, 0); + if (listFront(t, list)) { + set(t, pairSecond(t, listRear(t, list)), p); + } else { + set(t, listFront(t, list), p); + } + set(t, listRear(t, list), p); } void @@ -765,23 +837,23 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool) object superInterfaces = classInterfaceTable(t, classSuper(t, class_)); PROTECT(t, superInterfaces); - for (unsigned i = 0; i < rawArrayLength(t, superInterfaces); i += 2) { - object name = interfaceName(t, rawArrayBody(t, superInterfaces)[i]); - hashMapInsert(t, map, hashByteArray(t, name), name, name); + for (unsigned i = 0; i < arrayLength(t, superInterfaces); i += 2) { + object name = interfaceName(t, arrayBody(t, superInterfaces)[i]); + hashMapInsert(t, map, name, name, byteArrayHash); } unsigned count = s.read2(); for (unsigned i = 0; i < count; ++i) { - object name = rawArrayBody(t, pool)[s.read2()]; - hashMapInsert(t, map, hashByteArray(t, name), name, name); + object name = arrayBody(t, pool)[s.read2()]; + hashMapInsert(t, map, name, name, byteArrayHash); } object interfaceTable = 0; if (hashMapSize(t, map)) { - interfaceTable = makeRawArray(t, hashMapSize(t, map)); + interfaceTable = makeArray(t, hashMapSize(t, map)); unsigned i = 0; for (object it = hmIterator(t, map); it; it = hmIteratorNext(t, it)) { - set(t, rawArrayBody(t, interfaceTable)[i], hmIteratorKey(t, it)); + set(t, arrayBody(t, interfaceTable)[i], hmIteratorKey(t, it)); i += 2; } } @@ -801,7 +873,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) = classFixedSize(t, classSuper(t, class_)) * sizeof(void*); unsigned staticOffset = 0; - object fieldTable = makeRawArray(t, count); + object fieldTable = makeArray(t, count); PROTECT(t, fieldTable); for (unsigned i = 0; i < count; ++i) { @@ -818,8 +890,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) object value = makeField(t, flags, 0, // offset - rawArrayBody(t, pool)[name], - rawArrayBody(t, pool)[spec], + arrayBody(t, pool)[name], + arrayBody(t, pool)[spec], class_); if (flags & ACC_STATIC) { @@ -833,14 +905,14 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) memberOffset += fieldSize(t, value); } - set(t, rawArrayBody(t, fieldTable)[i], value); + set(t, arrayBody(t, fieldTable)[i], value); } set(t, classFieldTable(t, class_), fieldTable); if (staticOffset) { - object staticTable = makeRawArray(t, staticOffset); - memset(rawArrayBody(t, staticTable), 0, staticOffset * sizeof(void*)); + object staticTable = makeArray(t, staticOffset); + memset(arrayBody(t, staticTable), 0, staticOffset * sizeof(void*)); set(t, classStaticTable(t, class_), staticTable); } @@ -864,14 +936,14 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool) unsigned virtualCount = 0; - object superVTable = classVTable(t, super); - PROTECT(t, superVTable); + object superVirtualTable = classVirtualTable(t, super); + PROTECT(t, superVirtualTable); - if (superVTable) { - virtualCount = rawArrayLength(t, superVTable); + if (superVirtualTable) { + virtualCount = arrayLength(t, superVirtualTable); for (unsigned i = 0; i < virtualCount; ++i) { - object method = rawArrayBody(t, superVTable)[i]; - hashMapInsert(t, map, hashMethod(t, method), method, method); + object method = arrayBody(t, superVirtualTable)[i]; + hashMapInsert(t, map, method, method, byteArrayHash); } } @@ -880,7 +952,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool) unsigned count = s.read2(); if (count) { - object methodTable = makeRawArray(t, count); + object methodTable = makeArray(t, count); PROTECT(t, methodTable); for (unsigned i = 0; i < count; ++i) { @@ -891,7 +963,7 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool) object code = 0; unsigned attributeCount = s.read2(); for (unsigned j = 0; j < attributeCount; ++j) { - object name = rawArrayBody(t, pool)[s.read2()]; + object name = arrayBody(t, pool)[s.read2()]; if (strcmp(reinterpret_cast("Code"), byteArrayBody(t, name)) == 0) { @@ -904,15 +976,14 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool) object value = makeMethod(t, flags, 0, // offset - parameterCount(rawArrayBody(t, pool)[spec]), - rawArrayBody(t, pool)[name], - rawArrayBody(t, pool)[spec], + parameterCount(arrayBody(t, pool)[spec]), + arrayBody(t, pool)[name], + arrayBody(t, pool)[spec], class_, code); if ((flags & ACC_STATIC) == 0) { - object p = hashMapFindNode - (t, map, hashMethod(t, method), method, methodEqual); + object p = hashMapFindNode(t, map, method, methodHash, methodEqual); if (p) { methodOffset(t, value) = methodOffset(t, tripleFirst(t, p)); @@ -926,31 +997,30 @@ parseMemberTable(Thread* t, Stream& s, object class_, object pool) } } - set(t, rawArrayBody(t, methodTable)[i], value); + set(t, arrayBody(t, methodTable)[i], value); } set(t, classMethodTable(t, class_), methodTable); } if (virtualCount) { - object vtable = makeRawArray(t, virtualCount); + object vtable = makeArray(t, virtualCount); unsigned i = 0; - if (superVTable) { - for (; i < rawArrayLength(t, superVTable); ++i) { - object method = rawArrayBody(t, superVTable)[i]; - method = hashMapFind - (t, map, hashMethod(t, method), method, methodEqual); + if (superVirtualTable) { + for (; i < arrayLength(t, superVirtualTable); ++i) { + object method = arrayBody(t, superVirtualTable)[i]; + method = hashMapFind(t, map, method, methodHash, methodEqual); - set(t, rawArrayBody(t, vtable)[i], method); + set(t, arrayBody(t, vtable)[i], method); } for (object p = listFront(t, newVirtuals); p; p = pairSecond(t, p)) { - set(t, rawArrayBody(t, vtable)[i++], pairFirst(t, p)); + set(t, arrayBody(t, vtable)[i++], pairFirst(t, p)); } } - set(t, classVTable(t, class_), vtable); + set(t, classVirtualTable(t, class_), vtable); } } @@ -977,63 +1047,63 @@ parseClass(Thread* t, const uint8_t* data, unsigned size) s.read2(); // major version unsigned poolCount = s.read2(); - object pool = makeRawArray(t, poolCount); + object pool = makeArray(t, poolCount); PROTECT(t, pool); for (unsigned i = 0; i < poolCount; ++i) { switch (s.read1()) { case CONSTANT_Class: { - set(t, rawArrayBody(t, pool)[i], rawArrayBody(t, pool)[s.read2()]); + set(t, arrayBody(t, pool)[i], arrayBody(t, pool)[s.read2()]); } break; case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { - object c = rawArrayBody(t, pool)[s.read2()]; - object nameAndType = rawArrayBody(t, pool)[s.read2()]; + object c = arrayBody(t, pool)[s.read2()]; + object nameAndType = arrayBody(t, pool)[s.read2()]; object value = makeReference (t, c, pairFirst(t, nameAndType), pairSecond(t, nameAndType)); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_String: { - object bytes = rawArrayBody(t, pool)[s.read2()]; + object bytes = arrayBody(t, pool)[s.read2()]; object value = makeString(t, bytes, 0, byteArrayLength(t, bytes), 0); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_Integer: { object value = makeInt(t, s.read4()); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_Float: { object value = makeFloat(t, s.readFloat()); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_Long: { object value = makeLong(t, s.read8()); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_Double: { object value = makeLong(t, s.readDouble()); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_NameAndType: { - object name = rawArrayBody(t, pool)[s.read2()]; - object type = rawArrayBody(t, pool)[s.read2()]; + object name = arrayBody(t, pool)[s.read2()]; + object type = arrayBody(t, pool)[s.read2()]; object value = makePair(t, name, type); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; case CONSTANT_Utf8: { unsigned length = s.read2(); object value = makeByteArray(t, length); s.read(reinterpret_cast(byteArrayBody(t, value)), length); - set(t, rawArrayBody(t, pool)[i], value); + set(t, arrayBody(t, pool)[i], value); } break; default: abort(t); @@ -1049,7 +1119,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size) 0, // array size 0, // object mask flags, - rawArrayBody(t, pool)[name], + arrayBody(t, pool)[name], 0, // super 0, // interfaces 0, // fields @@ -1058,7 +1128,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size) 0); // initializers PROTECT(t, class_); - object super = resolveClass(t, rawArrayBody(t, pool)[s.read2()]); + object super = resolveClass(t, arrayBody(t, pool)[s.read2()]); if (UNLIKELY(t->exception)) return 0; set(t, classSuper(t, class_), super); @@ -1078,8 +1148,8 @@ resolveClass(Thread* t, object spec) PROTECT(t, spec); ACQUIRE(t, t->vm->classLock); - uint32_t h = hashByteArray(t, spec); - object class_ = hashMapFind(t, t->vm->classMap, h, spec, byteArrayEqual); + object class_ = hashMapFind + (t, t->vm->classMap, spec, byteArrayHash, byteArrayEqual); if (class_ == 0) { unsigned size; const uint8_t* data = t->vm->classFinder->find @@ -1093,8 +1163,7 @@ resolveClass(Thread* t, object spec) PROTECT(t, class_); - // cache class - hashMapInsert(t, t->vm->classMap, h, spec, class_); + hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash); } else { object message = makeString(t, "%s", byteArrayBody(t, spec)); t->exception = makeClassNotFoundException(t, message); @@ -1106,14 +1175,14 @@ resolveClass(Thread* t, object spec) inline object resolveClass(Thread* t, object pool, unsigned index) { - object o = rawArrayBody(t, pool)[index]; - if (typeOf(o) == ByteArrayType) { + object o = arrayBody(t, pool)[index]; + if (objectClass(o) == t->vm->byteArrayClass) { PROTECT(t, pool); o = resolveClass(t, o); if (UNLIKELY(t->exception)) return 0; - set(t, rawArrayBody(t, pool)[index], o); + set(t, arrayBody(t, pool)[index], o); } return o; } @@ -1122,7 +1191,7 @@ inline object resolveClass(Thread* t, object container, object& (*class_)(Thread*, object)) { object o = class_(t, container); - if (typeOf(o) == ByteArrayType) { + if (objectClass(o) == t->vm->byteArrayClass) { PROTECT(t, container); o = resolveClass(t, o); @@ -1137,17 +1206,17 @@ inline object resolve(Thread* t, object pool, unsigned index, object (*find)(Thread*, object, object)) { - object o = rawArrayBody(t, pool)[index]; - if (typeOf(o) == ReferenceType) { + object o = arrayBody(t, pool)[index]; + if (objectClass(o) == t->vm->byteArrayClass) { PROTECT(t, pool); object class_ = resolveClass(t, o, referenceClass); if (UNLIKELY(t->exception)) return 0; - o = find(t, class_, rawArrayBody(t, pool)[index]); + o = find(t, class_, arrayBody(t, pool)[index]); if (UNLIKELY(t->exception)) return 0; - set(t, rawArrayBody(t, pool)[index], o); + set(t, arrayBody(t, pool)[index], o); } return o; } @@ -1297,7 +1366,7 @@ run(Thread* t) case arraylength: { object array = pop(t); if (LIKELY(array)) { - if (typeOf(array) == ObjectArrayType) { + if (objectClass(array) == t->vm->objectArrayClass) { push(t, makeInt(t, objectArrayLength(t, array))); } else { // for all other array types, the length follow the class pointer. @@ -1494,7 +1563,7 @@ run(Thread* t) case dup2: { object first = stack[sp - 1]; - if (isLongOrDouble(first)) { + if (isLongOrDouble(t, first)) { push(t, first); } else { object second = stack[sp - 2]; @@ -1507,7 +1576,7 @@ run(Thread* t) object first = pop(t); object second = pop(t); - if (isLongOrDouble(first)) { + if (isLongOrDouble(t, first)) { push(t, first); push(t, second); push(t, first); @@ -1525,8 +1594,8 @@ run(Thread* t) object first = pop(t); object second = pop(t); - if (isLongOrDouble(first)) { - if (isLongOrDouble(second)) { + if (isLongOrDouble(t, first)) { + if (isLongOrDouble(t, second)) { push(t, first); push(t, second); push(t, first); @@ -1539,7 +1608,7 @@ run(Thread* t) } } else { object third = pop(t); - if (isLongOrDouble(third)) { + if (isLongOrDouble(t, third)) { push(t, second); push(t, first); push(t, third); @@ -2188,7 +2257,7 @@ run(Thread* t) } goto loop; case ldc: { - push(t, rawArrayBody(t, codePool(t, code))[codeBody(t, code)[ip++]]); + push(t, arrayBody(t, codePool(t, code))[codeBody(t, code)[ip++]]); } goto loop; case ldc_w: @@ -2196,7 +2265,7 @@ run(Thread* t) uint8_t index1 = codeBody(t, code)[ip++]; uint8_t index2 = codeBody(t, code)[ip++]; - push(t, rawArrayBody(t, codePool(t, code))[(index1 << 8) | index2]); + push(t, arrayBody(t, codePool(t, code))[(index1 << 8) | index2]); } goto loop; case ldiv: { @@ -2362,7 +2431,7 @@ run(Thread* t) case pop2: { object top = stack[sp - 1]; - if (isLongOrDouble(top)) { + if (isLongOrDouble(t, top)) { -- sp; } else { sp -= 2; @@ -2558,7 +2627,7 @@ run(Thread* t) uint16_t catchType = exceptionHandlerCatchType(eh); if (catchType == 0 or instanceOf(t, - rawArrayBody(t, codePool(t, code))[catchType], + arrayBody(t, codePool(t, code))[catchType], exception)) { sp = frameStackBase(t, frame);