This commit is contained in:
Joel Dice 2007-06-17 16:03:27 -06:00
parent 1301a6a1c8
commit 4493fe824e
2 changed files with 210 additions and 132 deletions

View File

@ -1,12 +1,12 @@
(type class (type class
(uint32_t id) (uint16_t flags)
(uint16_t fixedSize) (uint16_t fixedSize)
(uint16_t arrayElementSize) (uint16_t arrayElementSize)
(object objectMask) (object objectMask)
(uint16_t flags)
(object name) (object name)
(object super) (object super)
(object interfaceTable) (object interfaceTable)
(object virtualTable)
(object fieldTable) (object fieldTable)
(object methodTable) (object methodTable)
(object staticTable) (object staticTable)
@ -72,6 +72,15 @@
(object second) (object second)
(object third)) (object third))
(type hashMap
(object size)
(object array))
(type list
(object size)
(object front)
(object rear))
(type trace (type trace
(object method) (object method)
(uint32_t ip) (uint32_t ip)
@ -148,7 +157,7 @@
(type double (type double
(uint64_t value)) (uint64_t value))
(type rawArray (type array
(array object body)) (array object body))
(type objectArray (type objectArray

View File

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