add interpret.cpp changes

This commit is contained in:
Joshua Warner 2014-06-28 23:40:16 -06:00 committed by Joshua Warner
parent 9f0327bb9e
commit b5a1d97bd1

View File

@ -47,7 +47,7 @@ class Thread: public vm::Thread {
unsigned ip; unsigned ip;
unsigned sp; unsigned sp;
int frame; int frame;
object code; GcCode* code;
List<unsigned>* stackPointers; List<unsigned>* stackPointers;
uintptr_t stack[0]; uintptr_t stack[0];
}; };
@ -330,9 +330,9 @@ pushFrame(Thread* t, GcMethod* method)
t->ip = 0; t->ip = 0;
if ((method->flags() & ACC_NATIVE) == 0) { if ((method->flags() & ACC_NATIVE) == 0) {
t->code = reinterpret_cast<object>(method->code()); t->code = method->code();
locals = codeMaxLocals(t, t->code); locals = t->code->maxLocals();
memset(t->stack + ((base + parameterFootprint) * 2), 0, memset(t->stack + ((base + parameterFootprint) * 2), 0,
(locals - parameterFootprint) * BytesPerWord * 2); (locals - parameterFootprint) * BytesPerWord * 2);
@ -365,7 +365,7 @@ popFrame(Thread* t)
t->sp = frameBase(t, t->frame); t->sp = frameBase(t, t->frame);
t->frame = frameNext(t, t->frame); t->frame = frameNext(t, t->frame);
if (t->frame >= 0) { if (t->frame >= 0) {
t->code = reinterpret_cast<object>(frameMethod(t, t->frame)->code()); t->code = frameMethod(t, t->frame)->code();
t->ip = frameIp(t, t->frame); t->ip = frameIp(t, t->frame);
} else { } else {
t->code = 0; t->code = 0;
@ -632,8 +632,8 @@ invokeNative(Thread* t, GcMethod* method)
resolveNative(t, method); resolveNative(t, method);
object native = reinterpret_cast<object>(getMethodRuntimeData(t, method)->native()); GcNative* native = getMethodRuntimeData(t, method)->native();
if (nativeFast(t, native)) { if (native->fast()) {
pushFrame(t, method); pushFrame(t, method);
uint64_t result; uint64_t result;
@ -652,14 +652,14 @@ invokeNative(Thread* t, GcMethod* method)
(t, RUNTIME_ARRAY_BODY(args) + argOffset, 0, sp, method, true); (t, RUNTIME_ARRAY_BODY(args) + argOffset, 0, sp, method, true);
result = reinterpret_cast<FastNativeFunction> result = reinterpret_cast<FastNativeFunction>
(nativeFunction(t, native))(t, method, RUNTIME_ARRAY_BODY(args)); (native->function())(t, method, RUNTIME_ARRAY_BODY(args));
} }
pushResult(t, method->returnCode(), result, false); pushResult(t, method->returnCode(), result, false);
return method->returnCode(); return method->returnCode();
} else { } else {
return invokeNativeSlow(t, method, nativeFunction(t, native)); return invokeNativeSlow(t, method, native->function());
} }
} }
@ -688,11 +688,11 @@ findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
{ {
PROTECT(t, method); PROTECT(t, method);
object eht = method->code()->exceptionHandlerTable(); GcExceptionHandlerTable* eht = cast<GcExceptionHandlerTable>(t, method->code()->exceptionHandlerTable());
if (eht) { if (eht) {
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { for (unsigned i = 0; i < eht->length(); ++i) {
uint64_t eh = exceptionHandlerTableBody(t, eht, i); uint64_t eh = eht->body()[i];
if (ip - 1 >= exceptionHandlerStart(eh) if (ip - 1 >= exceptionHandlerStart(eh)
and ip - 1 < exceptionHandlerEnd(eh)) and ip - 1 < exceptionHandlerEnd(eh))
@ -708,7 +708,7 @@ findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
(t, method, exceptionHandlerCatchType(eh) - 1); (t, method, exceptionHandlerCatchType(eh) - 1);
if (catchType) { if (catchType) {
eh = exceptionHandlerTableBody(t, eht, i); eh = eht->body()[i];
t->exception = e; t->exception = e;
} else { } else {
// can't find what we're supposed to catch - move on. // can't find what we're supposed to catch - move on.
@ -733,31 +733,31 @@ findExceptionHandler(Thread* t, int frame)
} }
void void
pushField(Thread* t, object target, object field) pushField(Thread* t, object target, GcField* field)
{ {
switch (fieldCode(t, field)) { switch (field->code()) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
pushInt(t, fieldAtOffset<int8_t>(target, fieldOffset(t, field))); pushInt(t, fieldAtOffset<int8_t>(target, field->offset()));
break; break;
case CharField: case CharField:
case ShortField: case ShortField:
pushInt(t, fieldAtOffset<int16_t>(target, fieldOffset(t, field))); pushInt(t, fieldAtOffset<int16_t>(target, field->offset()));
break; break;
case FloatField: case FloatField:
case IntField: case IntField:
pushInt(t, fieldAtOffset<int32_t>(target, fieldOffset(t, field))); pushInt(t, fieldAtOffset<int32_t>(target, field->offset()));
break; break;
case DoubleField: case DoubleField:
case LongField: case LongField:
pushLong(t, fieldAtOffset<int64_t>(target, fieldOffset(t, field))); pushLong(t, fieldAtOffset<int64_t>(target, field->offset()));
break; break;
case ObjectField: case ObjectField:
pushObject(t, fieldAtOffset<object>(target, fieldOffset(t, field))); pushObject(t, fieldAtOffset<object>(target, field->offset()));
break; break;
default: default:
@ -778,18 +778,20 @@ interpret3(Thread* t, const int base)
unsigned& ip = t->ip; unsigned& ip = t->ip;
unsigned& sp = t->sp; unsigned& sp = t->sp;
int& frame = t->frame; int& frame = t->frame;
object& code = t->code; GcCode*& code = t->code;
GcMethod* method = 0;
PROTECT(t, method);
GcThrowable*& exception = t->exception; GcThrowable*& exception = t->exception;
uintptr_t* stack = t->stack; uintptr_t* stack = t->stack;
code = reinterpret_cast<object>(frameMethod(t, frame)->code()); code = frameMethod(t, frame)->code();
if (UNLIKELY(exception)) { if (UNLIKELY(exception)) {
goto throw_; goto throw_;
} }
loop: loop:
instruction = codeBody(t, code, ip++); instruction = code->body()[ip++];
if (DebugRun) { if (DebugRun) {
fprintf(stderr, "ip: %d; instruction: 0x%x in %s.%s ", fprintf(stderr, "ip: %d; instruction: 0x%x in %s.%s ",
@ -860,7 +862,7 @@ interpret3(Thread* t, const int base)
} goto loop; } goto loop;
case aload: { case aload: {
pushObject(t, localObject(t, codeBody(t, code, ip++))); pushObject(t, localObject(t, code->body()[ip++]));
} goto loop; } goto loop;
case aload_0: { case aload_0: {
@ -887,7 +889,7 @@ interpret3(Thread* t, const int base)
GcClass* class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1); GcClass* class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
pushObject(t, makeObjectArray(t, class_, count)); pushObject(t, reinterpret_cast<object>(makeObjectArray(t, class_, count)));
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcNegativeArraySizeException::Type, "%d", count); (t, GcNegativeArraySizeException::Type, "%d", count);
@ -917,7 +919,7 @@ interpret3(Thread* t, const int base)
} goto loop; } goto loop;
case astore: { case astore: {
store(t, codeBody(t, code, ip++)); store(t, code->body()[ip++]);
} goto loop; } goto loop;
case astore_0: { case astore_0: {
@ -949,27 +951,29 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) { if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
GcBooleanArray* a = cast<GcBooleanArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) static_cast<uintptr_t>(index)
< booleanArrayLength(t, array))) < a->length()))
{ {
pushInt(t, booleanArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, (t, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, booleanArrayLength(t, array)); "%d not in [0,%d)", index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
GcByteArray* a = cast<GcByteArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) static_cast<uintptr_t>(index)
< byteArrayLength(t, array))) < a->length()))
{ {
pushInt(t, byteArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, (t, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, byteArrayLength(t, array)); "%d not in [0,%d)", index, a->length());
goto throw_; goto throw_;
} }
} }
@ -986,26 +990,28 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) { if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
GcBooleanArray* a = cast<GcBooleanArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) static_cast<uintptr_t>(index)
< booleanArrayLength(t, array))) < a->length()))
{ {
booleanArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, (t, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, booleanArrayLength(t, array)); "%d not in [0,%d)", index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
GcByteArray* a = cast<GcByteArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < byteArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
byteArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, (t, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, byteArrayLength(t, array)); "%d not in [0,%d)", index, a->length());
goto throw_; goto throw_;
} }
} }
@ -1016,7 +1022,7 @@ interpret3(Thread* t, const int base)
} goto loop; } goto loop;
case bipush: { case bipush: {
pushInt(t, static_cast<int8_t>(codeBody(t, code, ip++))); pushInt(t, static_cast<int8_t>(code->body()[ip++]));
} goto loop; } goto loop;
case caload: { case caload: {
@ -1024,14 +1030,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcCharArray* a = cast<GcCharArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < charArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushInt(t, charArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, charArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1046,14 +1053,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcCharArray* a = cast<GcCharArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < charArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
charArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, charArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1119,14 +1127,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcDoubleArray* a = cast<GcDoubleArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < doubleArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushLong(t, doubleArrayBody(t, array, index)); pushLong(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, doubleArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1141,14 +1150,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcDoubleArray* a = cast<GcDoubleArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < doubleArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
memcpy(&doubleArrayBody(t, array, index), &value, sizeof(uint64_t)); memcpy(&a->body()[index], &value, sizeof(uint64_t));
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, doubleArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1336,14 +1346,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcFloatArray* a = cast<GcFloatArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < floatArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushInt(t, floatArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, floatArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1358,14 +1369,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcFloatArray* a = cast<GcFloatArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < floatArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
memcpy(&floatArrayBody(t, array, index), &value, sizeof(uint32_t)); memcpy(&a->body()[index], &value, sizeof(uint32_t));
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, floatArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1458,13 +1470,13 @@ interpret3(Thread* t, const int base)
if (LIKELY(peekObject(t, sp - 1))) { if (LIKELY(peekObject(t, sp - 1))) {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
object field = reinterpret_cast<object>(resolveField(t, frameMethod(t, frame), index - 1)); GcField* field = resolveField(t, frameMethod(t, frame), index - 1);
assertT(t, (fieldFlags(t, field) & ACC_STATIC) == 0); assertT(t, (field->flags() & ACC_STATIC) == 0);
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, cast<GcField>(t, field)); ACQUIRE_FIELD_FOR_READ(t, field);
pushField(t, popObject(t), field); pushField(t, popObject(t), field);
} else { } else {
@ -1476,17 +1488,17 @@ interpret3(Thread* t, const int base)
case getstatic: { case getstatic: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
object field = reinterpret_cast<object>(resolveField(t, frameMethod(t, frame), index - 1)); GcField* field = resolveField(t, frameMethod(t, frame), index - 1);
assertT(t, fieldFlags(t, field) & ACC_STATIC); assertT(t, field->flags() & ACC_STATIC);
PROTECT(t, field); PROTECT(t, field);
initClass(t, cast<GcClass>(t, fieldClass(t, field))); initClass(t, field->class_());
ACQUIRE_FIELD_FOR_READ(t, cast<GcField>(t, field)); ACQUIRE_FIELD_FOR_READ(t, field);
pushField(t, classStaticTable(t, fieldClass(t, field)), field); pushField(t, reinterpret_cast<object>(field->class_()->staticTable()), field);
} goto loop; } goto loop;
case goto_: { case goto_: {
@ -1535,14 +1547,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcIntArray* a = cast<GcIntArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < intArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushInt(t, intArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, intArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1564,14 +1577,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcIntArray* a = cast<GcIntArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < intArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
intArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, intArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1773,15 +1787,15 @@ interpret3(Thread* t, const int base)
} goto back_branch; } goto back_branch;
case iinc: { case iinc: {
uint8_t index = codeBody(t, code, ip++); uint8_t index = code->body()[ip++];
int8_t c = codeBody(t, code, ip++); int8_t c = code->body()[ip++];
setLocalInt(t, index, localInt(t, index) + c); setLocalInt(t, index, localInt(t, index) + c);
} goto loop; } goto loop;
case iload: case iload:
case fload: { case fload: {
pushInt(t, localInt(t, codeBody(t, code, ip++))); pushInt(t, localInt(t, code->body()[ip++]));
} goto loop; } goto loop;
case iload_0: case iload_0:
@ -1837,12 +1851,12 @@ interpret3(Thread* t, const int base)
ip += 2; ip += 2;
GcMethod* method = resolveMethod(t, frameMethod(t, frame), index - 1); GcMethod* m = resolveMethod(t, frameMethod(t, frame), index - 1);
unsigned parameterFootprint = method->parameterFootprint(); unsigned parameterFootprint = m->parameterFootprint();
if (LIKELY(peekObject(t, sp - parameterFootprint))) { if (LIKELY(peekObject(t, sp - parameterFootprint))) {
code = reinterpret_cast<object>(findInterfaceMethod method = findInterfaceMethod
(t, method, objectClass(t, peekObject(t, sp - parameterFootprint)))); (t, m, objectClass(t, peekObject(t, sp - parameterFootprint)));
goto invoke; goto invoke;
} else { } else {
exception = makeThrowable(t, GcNullPointerException::Type); exception = makeThrowable(t, GcNullPointerException::Type);
@ -1853,21 +1867,21 @@ interpret3(Thread* t, const int base)
case invokespecial: { case invokespecial: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
GcMethod* method = resolveMethod(t, frameMethod(t, frame), index - 1); GcMethod* m = resolveMethod(t, frameMethod(t, frame), index - 1);
unsigned parameterFootprint = method->parameterFootprint(); unsigned parameterFootprint = m->parameterFootprint();
if (LIKELY(peekObject(t, sp - parameterFootprint))) { if (LIKELY(peekObject(t, sp - parameterFootprint))) {
GcClass* class_ = frameMethod(t, frame)->class_(); GcClass* class_ = frameMethod(t, frame)->class_();
if (isSpecialMethod(t, method, class_)) { if (isSpecialMethod(t, m, class_)) {
class_ = class_->super(); class_ = class_->super();
PROTECT(t, method); PROTECT(t, m);
PROTECT(t, class_); PROTECT(t, class_);
initClass(t, class_); initClass(t, class_);
code = reinterpret_cast<object>(findVirtualMethod(t, method, class_)); method = findVirtualMethod(t, m, class_);
} else { } else {
code = reinterpret_cast<object>(method); method = m;
} }
goto invoke; goto invoke;
@ -1880,26 +1894,26 @@ interpret3(Thread* t, const int base)
case invokestatic: { case invokestatic: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
GcMethod* method = resolveMethod(t, frameMethod(t, frame), index - 1); GcMethod* m = resolveMethod(t, frameMethod(t, frame), index - 1);
PROTECT(t, method); PROTECT(t, m);
initClass(t, method->class_()); initClass(t, m->class_());
code = reinterpret_cast<object>(method); method = m;
} goto invoke; } goto invoke;
case invokevirtual: { case invokevirtual: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
GcMethod* method = resolveMethod(t, frameMethod(t, frame), index - 1); GcMethod* m = resolveMethod(t, frameMethod(t, frame), index - 1);
unsigned parameterFootprint = method->parameterFootprint(); unsigned parameterFootprint = m->parameterFootprint();
if (LIKELY(peekObject(t, sp - parameterFootprint))) { if (LIKELY(peekObject(t, sp - parameterFootprint))) {
GcClass* class_ = objectClass(t, peekObject(t, sp - parameterFootprint)); GcClass* class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
PROTECT(t, method); PROTECT(t, m);
PROTECT(t, class_); PROTECT(t, class_);
code = reinterpret_cast<object>(findVirtualMethod(t, method, class_)); method = findVirtualMethod(t, m, class_);
goto invoke; goto invoke;
} else { } else {
exception = makeThrowable(t, GcNullPointerException::Type); exception = makeThrowable(t, GcNullPointerException::Type);
@ -1954,7 +1968,7 @@ interpret3(Thread* t, const int base)
case istore: case istore:
case fstore: { case fstore: {
setLocalInt(t, codeBody(t, code, ip++), popInt(t)); setLocalInt(t, code->body()[ip++], popInt(t));
} goto loop; } goto loop;
case istore_0: case istore_0:
@ -2036,14 +2050,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcLongArray* a = cast<GcLongArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < longArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushLong(t, longArrayBody(t, array, index)); pushLong(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, longArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2065,14 +2080,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcLongArray* a = cast<GcLongArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < longArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
longArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, longArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2101,12 +2117,12 @@ interpret3(Thread* t, const int base)
uint16_t index; uint16_t index;
if (instruction == ldc) { if (instruction == ldc) {
index = codeBody(t, code, ip++); index = code->body()[ip++];
} else { } else {
index = codeReadInt16(t, code, ip); index = codeReadInt16(t, code, ip);
} }
GcSingleton* pool = codePool(t, code); GcSingleton* pool = code->pool();
if (singletonIsObject(t, pool, index - 1)) { if (singletonIsObject(t, pool, index - 1)) {
object v = singletonObject(t, pool, index - 1); object v = singletonObject(t, pool, index - 1);
@ -2128,7 +2144,7 @@ interpret3(Thread* t, const int base)
case ldc2_w: { case ldc2_w: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
GcSingleton* pool = codePool(t, code); GcSingleton* pool = code->pool();
uint64_t v; uint64_t v;
memcpy(&v, &singletonValue(t, pool, index - 1), 8); memcpy(&v, &singletonValue(t, pool, index - 1), 8);
@ -2149,7 +2165,7 @@ interpret3(Thread* t, const int base)
case lload: case lload:
case dload: { case dload: {
pushLong(t, localLong(t, codeBody(t, code, ip++))); pushLong(t, localLong(t, code->body()[ip++]));
} goto loop; } goto loop;
case lload_0: case lload_0:
@ -2262,7 +2278,7 @@ interpret3(Thread* t, const int base)
case lstore: case lstore:
case dstore: { case dstore: {
setLocalLong(t, codeBody(t, code, ip++), popLong(t)); setLocalLong(t, code->body()[ip++], popLong(t));
} goto loop; } goto loop;
case lstore_0: case lstore_0:
@ -2328,7 +2344,7 @@ interpret3(Thread* t, const int base)
case multianewarray: { case multianewarray: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
uint8_t dimensions = codeBody(t, code, ip++); uint8_t dimensions = code->body()[ip++];
GcClass* class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1); GcClass* class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
PROTECT(t, class_); PROTECT(t, class_);
@ -2368,7 +2384,7 @@ interpret3(Thread* t, const int base)
int32_t count = popInt(t); int32_t count = popInt(t);
if (LIKELY(count >= 0)) { if (LIKELY(count >= 0)) {
uint8_t type = codeBody(t, code, ip++); uint8_t type = code->body()[ip++];
object array; object array;
@ -2429,14 +2445,14 @@ interpret3(Thread* t, const int base)
case putfield: { case putfield: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
object field = reinterpret_cast<object>(resolveField(t, frameMethod(t, frame), index - 1)); GcField* field = resolveField(t, frameMethod(t, frame), index - 1);
assertT(t, (fieldFlags(t, field) & ACC_STATIC) == 0); assertT(t, (field->flags() & ACC_STATIC) == 0);
PROTECT(t, field); PROTECT(t, field);
{ ACQUIRE_FIELD_FOR_WRITE(t, cast<GcField>(t, field)); { ACQUIRE_FIELD_FOR_WRITE(t, field);
switch (fieldCode(t, field)) { switch (field->code()) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
case CharField: case CharField:
@ -2446,20 +2462,20 @@ interpret3(Thread* t, const int base)
int32_t value = popInt(t); int32_t value = popInt(t);
object o = popObject(t); object o = popObject(t);
if (LIKELY(o)) { if (LIKELY(o)) {
switch (fieldCode(t, field)) { switch (field->code()) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
fieldAtOffset<int8_t>(o, fieldOffset(t, field)) = value; fieldAtOffset<int8_t>(o, field->offset()) = value;
break; break;
case CharField: case CharField:
case ShortField: case ShortField:
fieldAtOffset<int16_t>(o, fieldOffset(t, field)) = value; fieldAtOffset<int16_t>(o, field->offset()) = value;
break; break;
case FloatField: case FloatField:
case IntField: case IntField:
fieldAtOffset<int32_t>(o, fieldOffset(t, field)) = value; fieldAtOffset<int32_t>(o, field->offset()) = value;
break; break;
} }
} else { } else {
@ -2472,7 +2488,7 @@ interpret3(Thread* t, const int base)
int64_t value = popLong(t); int64_t value = popLong(t);
object o = popObject(t); object o = popObject(t);
if (LIKELY(o)) { if (LIKELY(o)) {
fieldAtOffset<int64_t>(o, fieldOffset(t, field)) = value; fieldAtOffset<int64_t>(o, field->offset()) = value;
} else { } else {
exception = makeThrowable(t, GcNullPointerException::Type); exception = makeThrowable(t, GcNullPointerException::Type);
} }
@ -2482,7 +2498,7 @@ interpret3(Thread* t, const int base)
object value = popObject(t); object value = popObject(t);
object o = popObject(t); object o = popObject(t);
if (LIKELY(o)) { if (LIKELY(o)) {
set(t, o, fieldOffset(t, field), value); set(t, o, field->offset(), value);
} else { } else {
exception = makeThrowable(t, GcNullPointerException::Type); exception = makeThrowable(t, GcNullPointerException::Type);
} }
@ -2500,19 +2516,19 @@ interpret3(Thread* t, const int base)
case putstatic: { case putstatic: {
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
object field = reinterpret_cast<object>(resolveField(t, frameMethod(t, frame), index - 1)); GcField* field = resolveField(t, frameMethod(t, frame), index - 1);
assertT(t, fieldFlags(t, field) & ACC_STATIC); assertT(t, field->flags() & ACC_STATIC);
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, cast<GcField>(t, field)); ACQUIRE_FIELD_FOR_WRITE(t, field);
initClass(t, cast<GcClass>(t, fieldClass(t, field))); initClass(t, field->class_());
object table = classStaticTable(t, fieldClass(t, field)); GcSingleton* table = field->class_()->staticTable();
switch (fieldCode(t, field)) { switch (field->code()) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
case CharField: case CharField:
@ -2520,31 +2536,31 @@ interpret3(Thread* t, const int base)
case FloatField: case FloatField:
case IntField: { case IntField: {
int32_t value = popInt(t); int32_t value = popInt(t);
switch (fieldCode(t, field)) { switch (field->code()) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
fieldAtOffset<int8_t>(table, fieldOffset(t, field)) = value; fieldAtOffset<int8_t>(table, field->offset()) = value;
break; break;
case CharField: case CharField:
case ShortField: case ShortField:
fieldAtOffset<int16_t>(table, fieldOffset(t, field)) = value; fieldAtOffset<int16_t>(table, field->offset()) = value;
break; break;
case FloatField: case FloatField:
case IntField: case IntField:
fieldAtOffset<int32_t>(table, fieldOffset(t, field)) = value; fieldAtOffset<int32_t>(table, field->offset()) = value;
break; break;
} }
} break; } break;
case DoubleField: case DoubleField:
case LongField: { case LongField: {
fieldAtOffset<int64_t>(table, fieldOffset(t, field)) = popLong(t); fieldAtOffset<int64_t>(table, field->offset()) = popLong(t);
} break; } break;
case ObjectField: { case ObjectField: {
set(t, table, fieldOffset(t, field), popObject(t)); set(t, reinterpret_cast<object>(table), field->offset(), popObject(t));
} break; } break;
default: abort(t); default: abort(t);
@ -2552,7 +2568,7 @@ interpret3(Thread* t, const int base)
} goto loop; } goto loop;
case ret: { case ret: {
ip = localInt(t, codeBody(t, code, ip)); ip = localInt(t, code->body()[ip]);
} goto loop; } goto loop;
case return_: { case return_: {
@ -2576,14 +2592,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcShortArray* a = cast<GcShortArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < shortArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
pushInt(t, shortArrayBody(t, array, index)); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, shortArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2598,14 +2615,15 @@ interpret3(Thread* t, const int base)
object array = popObject(t); object array = popObject(t);
if (LIKELY(array)) { if (LIKELY(array)) {
GcShortArray* a = cast<GcShortArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < shortArrayLength(t, array))) static_cast<uintptr_t>(index) < a->length()))
{ {
shortArrayBody(t, array, index) = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", (t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
index, shortArrayLength(t, array)); index, a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2655,7 +2673,7 @@ interpret3(Thread* t, const int base)
assertT(t, frameNext(t, frame) >= base); assertT(t, frameNext(t, frame) >= base);
popFrame(t); popFrame(t);
assertT(t, codeBody(t, code, ip - 3) == invokevirtual); assertT(t, code->body()[ip - 3] == invokevirtual);
ip -= 2; ip -= 2;
uint16_t index = codeReadInt16(t, code, ip); uint16_t index = codeReadInt16(t, code, ip);
@ -2675,7 +2693,7 @@ interpret3(Thread* t, const int base)
} }
wide: wide:
switch (codeBody(t, code, ip++)) { switch (code->body()[ip++]) {
case aload: { case aload: {
pushObject(t, localObject(t, codeReadInt16(t, code, ip))); pushObject(t, localObject(t, codeReadInt16(t, code, ip)));
} goto loop; } goto loop;
@ -2719,11 +2737,11 @@ interpret3(Thread* t, const int base)
goto loop; goto loop;
invoke: { invoke: {
if (methodFlags(t, code) & ACC_NATIVE) { if (method->flags() & ACC_NATIVE) {
invokeNative(t, cast<GcMethod>(t, code)); invokeNative(t, method);
} else { } else {
checkStack(t, cast<GcMethod>(t, code)); checkStack(t, method);
pushFrame(t, cast<GcMethod>(t, code)); pushFrame(t, method);
} }
} goto loop; } goto loop;