add various bootstrap types; implement more helper functions; add LIKELY() and UNLIKELY() macro invocations where appropriate; add PROTECT() macro

This commit is contained in:
Joel Dice 2007-06-07 18:23:12 -06:00
parent 94338e15a8
commit 26bfa24c16
3 changed files with 253 additions and 128 deletions

View File

@ -7,7 +7,8 @@
#include "stdio.h" #include "stdio.h"
#define NO_RETURN __attribute__((noreturn)) #define NO_RETURN __attribute__((noreturn))
#define UNLIKELY(v) __builtin_expect(v, 0) #define LIKELY(v) __builtin_expect((v) != 0, true)
#define UNLIKELY(v) __builtin_expect((v) == 0, true)
#define MACRO_XY(X, Y) X##Y #define MACRO_XY(X, Y) X##Y
#define MACRO_MakeNameXY(FX, LINE) MACRO_XY(FX, LINE) #define MACRO_MakeNameXY(FX, LINE) MACRO_XY(FX, LINE)

View File

@ -48,14 +48,50 @@
(object name) (object name)
(object spec)) (object spec))
(type trace
(object method)
(uint32_t ip)
(object next))
(type string (type string
(array char value)) (object bytes)
(int32_t offset)
(int32_t length)
(int32_t hash))
(type throwable
(object message)
(object trace))
(type exception
(extends throwable))
(type runtimeException
(extends exception))
(type nullPointerException
(extends runtimeException))
(type arrayIndexOutOfBoundsException
(extends runtimeException))
(type negativeArrayStoreException
(extends runtimeException))
(type classCastException
(extends runtimeException))
(type error
(extends throwable))
(type StackOverflowError
(extends error))
(type byte (type byte
(int8_t value)) (int8_t value))
(type boolean (type boolean
(extends byte)) (int8_t byte))
(type short (type short
(int16_t value)) (int16_t value))
@ -86,7 +122,7 @@
(array int8_t body)) (array int8_t body))
(type booleanArray (type booleanArray
(extends byteArray)) (array int8_t body))
(type shortArray (type shortArray
(array int16_t body)) (array int16_t body))

View File

@ -2,9 +2,8 @@
#include "system.h" #include "system.h"
#include "heap.h" #include "heap.h"
#define PROTECTED(thread, name, value) \ #define PROTECT(thread, name) \
Protector MAKE_NAME(protector_) (thread, value); \ Thread::Protector MAKE_NAME(protector_) (thread, &name);
object& name(thread->stack[thread->sp - 1]);
namespace { namespace {
@ -54,6 +53,21 @@ class Thread {
ExitState ExitState
}; };
class Protector {
public:
Protector(Thread* t, object* p): t(t), p(p), next(t->protector) {
t->protector = this;
}
~Protector() {
t->protector = next;
}
Thread* t;
object* p;
Protector* next;
};
static const unsigned HeapSize = 64 * 1024; static const unsigned HeapSize = 64 * 1024;
static const unsigned StackSize = 64 * 1024; static const unsigned StackSize = 64 * 1024;
@ -68,6 +82,7 @@ class Thread {
unsigned heapIndex; unsigned heapIndex;
object stack[StackSize]; object stack[StackSize];
object heap[HeapSize]; object heap[HeapSize];
Protector* protector;
}; };
inline void NO_RETURN inline void NO_RETURN
@ -121,6 +136,10 @@ iterate(Thread* t, Heap::Visitor* v)
v->visit(t->stack + t->sp); v->visit(t->stack + t->sp);
} }
for (Thread::Protector* p = t->protector; p; p = p->next) {
v->visit(p->p);
}
for (Thread* t = t->child; t; t = t->next) { for (Thread* t = t->child; t; t = t->next) {
iterate(t, v); iterate(t, v);
} }
@ -295,21 +314,12 @@ pop(Thread* t)
return t->stack[--(t->sp)]; return t->stack[--(t->sp)];
} }
class Protector { inline object&
public: top(Thread* t)
Protector(Thread* t, object value): t(t) { {
if (t->sp >= Thread::StackSize) abort(t); return t->stack[t->sp - 1];
push(t, value);
} }
~Protector() {
pop(t);
}
private:
Thread* t;
};
inline object inline object
make(Thread* t, object class_) make(Thread* t, object class_)
{ {
@ -328,25 +338,75 @@ cast(object p, unsigned offset)
return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset); return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset);
} }
void
my_vsnprintf(char* buffer, unsigned size, const char* format, va_list a)
{
// todo
}
object object
makeJString(Thread* t, const char* format, ...) makeString(Thread* t, const char* format, ...)
{ {
static const unsigned Size = 256; static const unsigned Size = 256;
char buffer[Size]; char buffer[Size];
va_list a; va_list a;
va_start(a, format); va_start(a, format);
vsnprintf(buffer, Size - 1, format, a); my_vsnprintf(buffer, Size - 1, format, a);
va_end(a); va_end(a);
PROTECTED(t, s, makeString(t, strlen(buffer) + 1)); object s = makeByteArray(t, strlen(buffer) + 1);
memcpy(stringValue(t, s), buffer, stringLength(t, s)); memcpy(byteArrayBody(t, s), buffer, byteArrayLength(t, s));
object r = make(t, t->vm->jstringClass); return makeString(t, s, 0, byteArrayLength(t, s), 0);
cast<object>(r, sizeof(void*)) = s; }
cast<int32_t>(r, sizeof(void*) * 2) = 0;
cast<int32_t>(r, (sizeof(void*) * 2) + sizeof(int32_t)) = stringLength(t, s); object
return r; makeTrace(Thread* t)
{
object trace = 0;
PROTECT(t, trace);
for (; t->frame; t->frame = frameNext(t, t->frame)) {
trace = makeTrace
(t, frameMethod(t, t->frame), frameIp(t, t->frame), trace);
}
return trace;
}
object
makeArrayIndexOutOfBoundsException(Thread* t, object message)
{
PROTECT(t, message);
object trace = makeTrace(t);
return makeArrayIndexOutOfBoundsException(t, message, trace);
}
object
makeNegativeArrayStoreException(Thread* t, object message)
{
PROTECT(t, message);
object trace = makeTrace(t);
return makeNegativeArrayStoreException(t, message, trace);
}
object
makeClassCastException(Thread* t, object message)
{
PROTECT(t, message);
object trace = makeTrace(t);
return makeArrayIndexOutOfBoundsException(t, message, trace);
}
object
makeNullPointerException(Thread* t)
{
return makeNullPointerException(t, 0, makeTrace(t));
}
object
makeStackOverflowError(Thread* t)
{
return makeStackOverflowError(t, 0, makeTrace(t));
} }
object object
@ -361,18 +421,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < objectArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < objectArrayLength(t, array)))
{
push(t, objectArrayBody(t, array)[i]); push(t, objectArrayBody(t, array)[i]);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
objectArrayLength(t, array)); objectArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -383,17 +445,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < objectArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < objectArrayLength(t, array)))
{
set(t, objectArrayBody(t, array)[i], value); set(t, objectArrayBody(t, array)[i], value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
objectArrayLength(t, array)); objectArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -436,20 +500,20 @@ run(Thread* t)
object count = pop(t); object count = pop(t);
int32_t c = intValue(t, count); int32_t c = intValue(t, count);
if (c >= 0) { if (LIKELY(c >= 0)) {
uint8_t index1 = codeBody(t, t->code)[ip++]; uint8_t index1 = codeBody(t, t->code)[ip++];
uint8_t index2 = codeBody(t, t->code)[ip++]; uint8_t index2 = codeBody(t, t->code)[ip++];
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t, t->code), index); object class_ = resolveClass(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
object array = makeObjectArray(t, class_, c); object array = makeObjectArray(t, class_, c);
memset(objectArrayBody(t, array), 0, c * 4); memset(objectArrayBody(t, array), 0, c * 4);
push(t, array); push(t, array);
} else { } else {
object message = makeJString(t, "%d", c); object message = makeString(t, "%d", c);
t->exception = makeNegativeArrayStoreException(t, message); t->exception = makeNegativeArrayStoreException(t, message);
goto throw_; goto throw_;
} }
@ -472,7 +536,7 @@ run(Thread* t)
case arraylength: { case arraylength: {
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
if (typeOf(array) == ObjectArrayType) { if (typeOf(array) == ObjectArrayType) {
push(t, makeInt(t, objectArrayLength(t, array))); push(t, makeInt(t, objectArrayLength(t, array)));
} else { } else {
@ -480,7 +544,7 @@ run(Thread* t)
push(t, makeInt(t, cast<uint32_t>(array, sizeof(void*)))); push(t, makeInt(t, cast<uint32_t>(array, sizeof(void*))));
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} abort(t); } abort(t);
@ -522,8 +586,8 @@ run(Thread* t)
case athrow: { case athrow: {
t->exception = pop(t); t->exception = pop(t);
if (t->exception == 0) { if (UNLIKELY(t->exception == 0)) {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
} }
goto throw_; goto throw_;
} abort(t); } abort(t);
@ -532,18 +596,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < byteArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < byteArrayLength(t, array)))
{
push(t, makeByte(t, byteArrayBody(t, array)[i])); push(t, makeByte(t, byteArrayBody(t, array)[i]));
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
byteArrayLength(t, array)); byteArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -554,17 +620,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < byteArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < byteArrayLength(t, array)))
{
byteArrayBody(t, array)[i] = intValue(t, value); byteArrayBody(t, array)[i] = intValue(t, value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
byteArrayLength(t, array)); byteArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -577,18 +645,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < charArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < charArrayLength(t, array)))
{
push(t, makeInt(t, charArrayBody(t, array)[i])); push(t, makeInt(t, charArrayBody(t, array)[i]));
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
charArrayLength(t, array)); charArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -599,17 +669,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < charArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < charArrayLength(t, array)))
{
charArrayBody(t, array)[i] = intValue(t, value); charArrayBody(t, array)[i] = intValue(t, value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
charArrayLength(t, array)); charArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -622,10 +694,14 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t, t->code), index); object class_ = resolveClass(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (not instanceOf(t, class_, t->stack[t->sp - 1])) { if (not instanceOf(t, class_, t->stack[t->sp - 1])) {
t->exception = makeClassCastException(t, 0); object message = makeString
(t, "%S as %S",
className(t, objectClass(t->stack[t->sp - 1])),
className(t, class_));
t->exception = makeClassCastException(t, message);
goto throw_; goto throw_;
} }
} }
@ -723,17 +799,17 @@ run(Thread* t)
case getfield: { case getfield: {
object instance = pop(t); object instance = pop(t);
if (instance) { if (LIKELY(instance)) {
uint8_t index1 = codeBody(t, t->code)[ip++]; uint8_t index1 = codeBody(t, t->code)[ip++];
uint8_t index2 = codeBody(t, t->code)[ip++]; uint8_t index2 = codeBody(t, t->code)[ip++];
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object field = resolveField(t, codePool(t, t->code), index); object field = resolveField(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
push(t, getField(instance, field)); push(t, getField(instance, field));
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -744,7 +820,7 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object field = resolveField(t, codePool(t, t->code), index); object field = resolveField(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (not classInitialized(fieldClass(t, field))) { if (not classInitialized(fieldClass(t, field))) {
t->code = classInitializer(fieldClass(t, field)); t->code = classInitializer(fieldClass(t, field));
@ -808,18 +884,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < intArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < intArrayLength(t, array)))
{
push(t, makeInt(t, intArrayBody(t, array)[i])); push(t, makeInt(t, intArrayBody(t, array)[i]));
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
intArrayLength(t, array)); intArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -837,17 +915,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < intArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < intArrayLength(t, array)))
{
intArrayBody(t, array)[i] = intValue(t, value); intArrayBody(t, array)[i] = intValue(t, value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
intArrayLength(t, array)); intArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1096,7 +1176,7 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t, t->code), index); object class_ = resolveClass(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (instanceOf(t, class_, t->stack[t->sp - 1])) { if (instanceOf(t, class_, t->stack[t->sp - 1])) {
push(t, makeInt(t, 1)); push(t, makeInt(t, 1));
@ -1116,17 +1196,17 @@ run(Thread* t)
ip += 2; ip += 2;
object method = resolveMethod(t, codePool(t, t->code), index); object method = resolveMethod(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
parameterCount = methodParameterCount(method); parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) { if (LIKELY(t->stack[t->sp - parameterCount])) {
t->code = findInterfaceMethod t->code = findInterfaceMethod
(t, method, t->stack[t->sp - parameterCount]); (t, method, t->stack[t->sp - parameterCount]);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
goto invoke; goto invoke;
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1137,21 +1217,21 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t, t->code), index); object method = resolveMethod(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
parameterCount = methodParameterCount(method); parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) { if (LIKELY(t->stack[t->sp - parameterCount])) {
if (isSpecialMethod(method, t->stack[t->sp - parameterCount])) { if (isSpecialMethod(method, t->stack[t->sp - parameterCount])) {
t->code = findSpecialMethod t->code = findSpecialMethod
(t, method, t->stack[t->sp - parameterCount]); (t, method, t->stack[t->sp - parameterCount]);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
} else { } else {
t->code = method; t->code = method;
} }
goto invoke; goto invoke;
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1162,7 +1242,7 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t, t->code), index); object method = resolveMethod(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (not classInitialized(methodClass(t, method))) { if (not classInitialized(methodClass(t, method))) {
t->code = classInitializer(methodClass(t, method)); t->code = classInitializer(methodClass(t, method));
@ -1181,16 +1261,16 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t, t->code), index); object method = resolveMethod(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
parameterCount = methodParameterCount(method); parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) { if (LIKELY(t->stack[t->sp - parameterCount])) {
t->code = findVirtualMethod(t, method, t->stack[t->sp - parameterCount]); t->code = findVirtualMethod(t, method, t->stack[t->sp - parameterCount]);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
goto invoke; goto invoke;
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1280,18 +1360,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < longArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < longArrayLength(t, array)))
{
push(t, makeLong(t, longArrayBody(t, array)[i])); push(t, makeLong(t, longArrayBody(t, array)[i]));
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
longArrayLength(t, array)); longArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1309,17 +1391,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < longArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < longArrayLength(t, array)))
{
longArrayBody(t, array)[i] = longValue(t, value); longArrayBody(t, array)[i] = longValue(t, value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
longArrayLength(t, array)); longArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1428,7 +1512,7 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t, t->code), index); object class_ = resolveClass(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (not classInitialized(class_)) { if (not classInitialized(class_)) {
t->code = classInitializer(class_); t->code = classInitializer(class_);
@ -1444,7 +1528,7 @@ run(Thread* t)
object count = pop(t); object count = pop(t);
int32_t c = intValue(t, count); int32_t c = intValue(t, count);
if (c >= 0) { if (LIKELY(c >= 0)) {
uint8_t type = codeBody(t, t->code)[ip++]; uint8_t type = codeBody(t, t->code)[ip++];
object array; object array;
@ -1494,12 +1578,12 @@ run(Thread* t)
default: abort(t); default: abort(t);
} }
memset(static_cast<object*>(instance) + (sizeof(object) * 2), 0 memset(static_cast<object*>(instance) + (sizeof(object) * 2), 0,
c * factor); c * factor);
push(t, array); push(t, array);
} else { } else {
object message = makeJString(t, "%d", c); object message = makeString(t, "%d", c);
t->exception = makeNegativeArrayStoreException(t, message); t->exception = makeNegativeArrayStoreException(t, message);
goto throw_; goto throw_;
} }
@ -1522,18 +1606,18 @@ run(Thread* t)
case putfield: { case putfield: {
object instance = pop(t); object instance = pop(t);
if (instance) { if (LIKELY(instance)) {
uint8_t index1 = codeBody(t, t->code)[ip++]; uint8_t index1 = codeBody(t, t->code)[ip++];
uint8_t index2 = codeBody(t, t->code)[ip++]; uint8_t index2 = codeBody(t, t->code)[ip++];
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object field = resolveField(t, codePool(t, t->code), index); object field = resolveField(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
object value = pop(t); object value = pop(t);
setField(t, instance, field, value); setField(t, instance, field, value);
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1544,7 +1628,7 @@ run(Thread* t)
uint16_t index = (index1 << 8) | index2; uint16_t index = (index1 << 8) | index2;
object field = resolveField(t, codePool(t, t->code), index); object field = resolveField(t, codePool(t, t->code), index);
if (t->exception) goto throw_; if (UNLIKELY(t->exception)) goto throw_;
if (not classInitialized(fieldClass(t, field))) { if (not classInitialized(fieldClass(t, field))) {
t->code = classInitializer(fieldClass(t, field)); t->code = classInitializer(fieldClass(t, field));
@ -1577,18 +1661,20 @@ run(Thread* t)
object index = pop(t); object index = pop(t);
object array = pop(t); object array = pop(t);
if (array) { if (LIKELY(array)) {
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (i >= 0 and static_cast<uint32_t>(i) < shortArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < shortArrayLength(t, array)))
{
push(t, makeShort(t, shortArrayBody(t, array)[i])); push(t, makeShort(t, shortArrayBody(t, array)[i]));
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
shortArrayLength(t, array)); shortArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1599,17 +1685,19 @@ run(Thread* t)
object array = pop(t); object array = pop(t);
int32_t i = intValue(t, index); int32_t i = intValue(t, index);
if (array) { if (LIKELY(array)) {
if (i >= 0 and static_cast<uint32_t>(i) < shortArrayLength(t, array)) { if (LIKELY(i >= 0 and
static_cast<uint32_t>(i) < shortArrayLength(t, array)))
{
shortArrayBody(t, array)[i] = intValue(t, value); shortArrayBody(t, array)[i] = intValue(t, value);
} else { } else {
object message = makeJString(t, "%d not in [0,%d]", i, object message = makeString(t, "%d not in [0,%d]", i,
shortArrayLength(t, array)); shortArrayLength(t, array));
t->exception = makeArrayIndexOutOfBoundsException(t, message); t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_; goto throw_;
} }
} else { } else {
t->exception = makeNullPointerException(t, 0); t->exception = makeNullPointerException(t);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -1677,10 +1765,10 @@ run(Thread* t)
} }
invoke: invoke:
if (codeMaxStack(t, methodCode(t, t->code)) + t->sp - parameterCount if (UNLIKELY(codeMaxStack(t, methodCode(t, t->code)) + t->sp - parameterCount
> Thread::StackSize) > Thread::StackSize))
{ {
t->exception = makeStackOverflowException(t, 0); t->exception = makeStackOverflowError(t);
goto throw_; goto throw_;
} }