store frame data on the stack, not the heap

This commit is contained in:
Joel Dice 2007-07-05 19:06:06 -06:00
parent 56467e61d7
commit dc8232eddf
4 changed files with 194 additions and 119 deletions

View File

@ -8,6 +8,14 @@
#include "stdio.h" #include "stdio.h"
#include "types.h" #include "types.h"
#ifdef __i386__
# define LD "%d"
# define LLD "%lld"
#elif defined __x86_64__
# define LD "%ld"
# define LLD "%ld"
#endif
#define NO_RETURN __attribute__((noreturn)) #define NO_RETURN __attribute__((noreturn))
#define LIKELY(v) __builtin_expect((v) != 0, true) #define LIKELY(v) __builtin_expect((v) != 0, true)

View File

@ -16,7 +16,6 @@
using namespace vm; using namespace vm;
#ifdef __i386__ #ifdef __i386__
#define LD "%d"
extern "C" uint64_t extern "C" uint64_t
cdeclCall(void* function, void* stack, unsigned stackSize, cdeclCall(void* function, void* stack, unsigned stackSize,
@ -34,7 +33,6 @@ dynamicCall(void* function, uint32_t* arguments, uint8_t*,
} // namespace } // namespace
#elif defined __x86_64__ #elif defined __x86_64__
#define LD "%ld"
extern "C" uint64_t extern "C" uint64_t
amd64Call(void* function, void* stack, unsigned stackSize, amd64Call(void* function, void* stack, unsigned stackSize,

View File

@ -68,12 +68,6 @@
(uint16_t maxLocals) (uint16_t maxLocals)
(array uint8_t body)) (array uint8_t body))
(type frame
(object method)
(object next)
(uint32_t ip)
(uint32_t stackBase))
(type reference (type reference
(object class) (object class)
(object name) (object name)

View File

@ -20,7 +20,7 @@ using namespace vm;
namespace { namespace {
const bool Verbose = true; const bool Verbose = false;
const bool Debug = false; const bool Debug = false;
const bool DebugRun = false; const bool DebugRun = false;
const bool DebugStack = false; const bool DebugStack = false;
@ -28,6 +28,12 @@ const bool DebugStack = false;
const uintptr_t HashTakenMark = 1; const uintptr_t HashTakenMark = 1;
const uintptr_t ExtendedMark = 2; const uintptr_t ExtendedMark = 2;
const unsigned FrameBaseOffset = 0;
const unsigned FrameNextOffset = 1;
const unsigned FrameMethodOffset = 2;
const unsigned FrameIpOffset = 3;
const unsigned FrameFootprint = 4;
class Thread; class Thread;
void (*Initializer)(Thread*, object); void (*Initializer)(Thread*, object);
@ -165,11 +171,11 @@ class Thread : public JNIEnv {
Thread* child; Thread* child;
State state; State state;
object thread; object thread;
object frame;
object code; object code;
object exception; object exception;
unsigned ip; unsigned ip;
unsigned sp; unsigned sp;
int frame;
unsigned heapIndex; unsigned heapIndex;
Protector* protector; Protector* protector;
Chain* chain; Chain* chain;
@ -563,6 +569,7 @@ pushObject(Thread* t, object o)
fprintf(stderr, "push object %p at %d\n", o, t->sp); fprintf(stderr, "push object %p at %d\n", o, t->sp);
} }
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
t->stack[(t->sp * 2) ] = ObjectTag; t->stack[(t->sp * 2) ] = ObjectTag;
t->stack[(t->sp * 2) + 1] = reinterpret_cast<uintptr_t>(o); t->stack[(t->sp * 2) + 1] = reinterpret_cast<uintptr_t>(o);
++ t->sp; ++ t->sp;
@ -575,6 +582,7 @@ pushInt(Thread* t, uint32_t v)
fprintf(stderr, "push int %d at %d\n", v, t->sp); fprintf(stderr, "push int %d at %d\n", v, t->sp);
} }
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
t->stack[(t->sp * 2) ] = IntTag; t->stack[(t->sp * 2) ] = IntTag;
t->stack[(t->sp * 2) + 1] = v; t->stack[(t->sp * 2) + 1] = v;
++ t->sp; ++ t->sp;
@ -584,7 +592,7 @@ inline void
pushLong(Thread* t, uint64_t v) pushLong(Thread* t, uint64_t v)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "push long %lld at %d\n", v, t->sp); fprintf(stderr, "push long " LLD " at %d\n", v, t->sp);
} }
pushInt(t, v >> 32); pushInt(t, v >> 32);
@ -608,7 +616,7 @@ inline uint32_t
popInt(Thread* t) popInt(Thread* t)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "pop int %d at %d\n", fprintf(stderr, "pop int " LD " at %d\n",
t->stack[((t->sp - 1) * 2) + 1], t->stack[((t->sp - 1) * 2) + 1],
t->sp - 1); t->sp - 1);
} }
@ -621,7 +629,7 @@ inline uint64_t
popLong(Thread* t) popLong(Thread* t)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "pop long %lld at %d\n", fprintf(stderr, "pop long " LLD " at %d\n",
(static_cast<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32) (static_cast<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((t->sp - 1) * 2) + 1]), | static_cast<uint64_t>(t->stack[((t->sp - 1) * 2) + 1]),
t->sp - 2); t->sp - 2);
@ -641,6 +649,7 @@ peekObject(Thread* t, unsigned index)
index); index);
} }
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == ObjectTag); assert(t, t->stack[index * 2] == ObjectTag);
return *reinterpret_cast<object*>(t->stack + (index * 2) + 1); return *reinterpret_cast<object*>(t->stack + (index * 2) + 1);
} }
@ -649,11 +658,12 @@ inline uint32_t
peekInt(Thread* t, unsigned index) peekInt(Thread* t, unsigned index)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "peek int %d at %d\n", fprintf(stderr, "peek int " LD " at %d\n",
t->stack[(index * 2) + 1], t->stack[(index * 2) + 1],
index); index);
} }
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == IntTag); assert(t, t->stack[index * 2] == IntTag);
return t->stack[(index * 2) + 1]; return t->stack[(index * 2) + 1];
} }
@ -662,7 +672,7 @@ inline uint64_t
peekLong(Thread* t, unsigned index) peekLong(Thread* t, unsigned index)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "peek long %lld at %d\n", fprintf(stderr, "peek long " LLD " at %d\n",
(static_cast<uint64_t>(t->stack[(index * 2) + 1]) << 32) (static_cast<uint64_t>(t->stack[(index * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]), | static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]),
index); index);
@ -698,7 +708,7 @@ inline void
pokeLong(Thread* t, unsigned index, uint64_t value) pokeLong(Thread* t, unsigned index, uint64_t value)
{ {
if (DebugStack) { if (DebugStack) {
fprintf(stderr, "poke long %lld at %d\n", value, index); fprintf(stderr, "poke long " LLD " at %d\n", value, index);
} }
pokeInt(t, index, value >> 32); pokeInt(t, index, value >> 32);
@ -713,6 +723,75 @@ pushReference(Thread* t, object o)
return reinterpret_cast<object*>(t->stack + ((t->sp - 1) * 2) + 1); return reinterpret_cast<object*>(t->stack + ((t->sp - 1) * 2) + 1);
} }
inline int
frameNext(Thread* t, int frame)
{
return peekInt(t, frame + FrameNextOffset);
}
inline object
frameMethod(Thread* t, int frame)
{
return peekObject(t, frame + FrameMethodOffset);
}
inline unsigned
frameIp(Thread* t, int frame)
{
return peekInt(t, frame + FrameIpOffset);
}
inline unsigned
frameBase(Thread* t, int frame)
{
return peekInt(t, frame + FrameBaseOffset);
}
void
pushFrame(Thread* t, object method)
{
if (t->frame >= 0) {
pokeInt(t, t->frame + FrameIpOffset, t->ip);
}
t->ip = 0;
unsigned parameterFootprint = methodParameterFootprint(t, method);
unsigned base = t->sp - parameterFootprint;
unsigned locals = parameterFootprint;
if ((methodFlags(t, method) & ACC_NATIVE) == 0) {
t->code = methodCode(t, method);
locals = codeMaxLocals(t, t->code);
memset(t->stack + ((base + parameterFootprint) * 2), 0,
(locals - parameterFootprint) * BytesPerWord * 2);
}
unsigned frame = base + locals;
pokeInt(t, frame + FrameNextOffset, t->frame);
t->frame = frame;
t->sp = frame + FrameFootprint;
pokeInt(t, frame + FrameBaseOffset, base);
pokeObject(t, frame + FrameMethodOffset, method);
}
void
popFrame(Thread* t)
{
t->sp = frameBase(t, t->frame);
t->frame = frameNext(t, t->frame);
if (t->frame >= 0) {
t->code = methodCode(t, frameMethod(t, t->frame));
t->ip = frameIp(t, t->frame);
} else {
t->code = 0;
t->ip = 0;
}
}
void void
Thread::dispose() Thread::dispose()
{ {
@ -729,7 +808,6 @@ visitRoots(Thread* t, Heap::Visitor* v)
t->heapIndex = 0; t->heapIndex = 0;
v->visit(&(t->thread)); v->visit(&(t->thread));
v->visit(&(t->frame));
v->visit(&(t->code)); v->visit(&(t->code));
v->visit(&(t->exception)); v->visit(&(t->exception));
@ -1213,12 +1291,10 @@ makeString(Thread* t, const char* format, ...)
} }
object object
makeTrace(Thread* t, object frame) makeTrace(Thread* t, int frame)
{ {
PROTECT(t, frame);
unsigned count = 0; unsigned count = 0;
for (object f = frame; f; f = frameNext(t, f)) { for (int f = frame; f >= 0; f = frameNext(t, f)) {
++ count; ++ count;
} }
@ -1228,7 +1304,7 @@ makeTrace(Thread* t, object frame)
PROTECT(t, trace); PROTECT(t, trace);
unsigned index = 0; unsigned index = 0;
for (object f = frame; f; f = frameNext(t, f)) { for (int f = frame; f >= 0; f = frameNext(t, f)) {
object e = makeStackTraceElement(t, frameMethod(t, f), frameIp(t, f)); object e = makeStackTraceElement(t, frameMethod(t, f), frameIp(t, f));
set(t, objectArrayBody(t, trace, index++), e); set(t, objectArrayBody(t, trace, index++), e);
} }
@ -1239,7 +1315,7 @@ makeTrace(Thread* t, object frame)
object object
makeTrace(Thread* t) makeTrace(Thread* t)
{ {
frameIp(t, t->frame) = t->ip; pokeInt(t, t->frame + FrameIpOffset, t->ip);
return makeTrace(t, t->frame); return makeTrace(t, t->frame);
} }
@ -1904,6 +1980,16 @@ parameterFootprint(Thread* t, object spec)
case '[': case '[':
while (*s == '[') ++ s; while (*s == '[') ++ s;
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
break;
default:
++ s;
break;
}
break; break;
case 'J': case 'J':
@ -1938,6 +2024,16 @@ parameterCount(Thread* t, object spec)
case '[': case '[':
while (*s == '[') ++ s; while (*s == '[') ++ s;
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
break;
default:
++ s;
break;
}
break; break;
default: default:
@ -2608,7 +2704,8 @@ invokeNative(Thread* t, object method)
return; return;
} }
unsigned footprint = methodParameterFootprint(t, method); pushFrame(t, method);
unsigned count = methodParameterCount(t, method); unsigned count = methodParameterCount(t, method);
unsigned size = nativeMethodDataArgumentTableSize(t, data); unsigned size = nativeMethodDataArgumentTableSize(t, data);
@ -2617,7 +2714,7 @@ invokeNative(Thread* t, object method)
args[offset++] = reinterpret_cast<uintptr_t>(t); args[offset++] = reinterpret_cast<uintptr_t>(t);
unsigned sp = t->sp - footprint; unsigned sp = frameBase(t, t->frame);
for (unsigned i = 0; i < count; ++i) { for (unsigned i = 0; i < count; ++i) {
unsigned type = nativeMethodDataParameterTypes(t, data, i + 1); unsigned type = nativeMethodDataParameterTypes(t, data, i + 1);
@ -2667,12 +2764,12 @@ invokeNative(Thread* t, object method)
enter(t, Thread::ActiveState); enter(t, Thread::ActiveState);
} }
popFrame(t);
if (UNLIKELY(t->exception)) { if (UNLIKELY(t->exception)) {
return; return;
} }
t->sp = frameStackBase(t, t->frame);
switch (returnCode) { switch (returnCode) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
@ -2702,39 +2799,39 @@ invokeNative(Thread* t, object method)
} }
inline object inline object
localObject(Thread* t, object frame, unsigned index) localObject(Thread* t, unsigned index)
{ {
return peekObject(t, frameStackBase(t, frame) + index); return peekObject(t, frameBase(t, t->frame) + index);
} }
inline uint32_t inline uint32_t
localInt(Thread* t, object frame, unsigned index) localInt(Thread* t, unsigned index)
{ {
return peekInt(t, frameStackBase(t, frame) + index); return peekInt(t, frameBase(t, t->frame) + index);
} }
inline uint64_t inline uint64_t
localLong(Thread* t, object frame, unsigned index) localLong(Thread* t, unsigned index)
{ {
return peekLong(t, frameStackBase(t, frame) + index); return peekLong(t, frameBase(t, t->frame) + index);
} }
inline void inline void
setLocalObject(Thread* t, object frame, unsigned index, object value) setLocalObject(Thread* t, unsigned index, object value)
{ {
pokeObject(t, frameStackBase(t, frame) + index, value); pokeObject(t, frameBase(t, t->frame) + index, value);
} }
inline void inline void
setLocalInt(Thread* t, object frame, unsigned index, uint32_t value) setLocalInt(Thread* t, unsigned index, uint32_t value)
{ {
pokeInt(t, frameStackBase(t, frame) + index, value); pokeInt(t, frameBase(t, t->frame) + index, value);
} }
inline void inline void
setLocalLong(Thread* t, object frame, unsigned index, uint64_t value) setLocalLong(Thread* t, unsigned index, uint64_t value)
{ {
pokeLong(t, frameStackBase(t, frame) + index, value); pokeLong(t, frameBase(t, t->frame) + index, value);
} }
namespace builtin { namespace builtin {
@ -2784,8 +2881,10 @@ trace(JNIEnv* e, jint skipCount)
{ {
Thread* t = static_cast<Thread*>(e); Thread* t = static_cast<Thread*>(e);
object frame = t->frame; int frame = t->frame;
while (skipCount--) frame = frameNext(t, frame); while (skipCount-- and frame >= 0) {
frame = frameNext(t, frame);
}
if (methodClass(t, frameMethod(t, frame)) if (methodClass(t, frameMethod(t, frame))
== arrayBody(t, t->vm->types, Machine::ThrowableType)) == arrayBody(t, t->vm->types, Machine::ThrowableType))
@ -2918,11 +3017,11 @@ Thread::Thread(Machine* m):
child(0), child(0),
state(NoState), state(NoState),
thread(0), thread(0),
frame(0),
code(0), code(0),
exception(0), exception(0),
ip(0), ip(0),
sp(0), sp(0),
frame(-1),
heapIndex(0), heapIndex(0),
protector(0), protector(0),
chain(0) chain(0)
@ -2986,8 +3085,8 @@ run(Thread* t)
unsigned instruction = nop; unsigned instruction = nop;
unsigned& ip = t->ip; unsigned& ip = t->ip;
unsigned& sp = t->sp; unsigned& sp = t->sp;
int& frame = t->frame;
object& code = t->code; object& code = t->code;
object& frame = t->frame;
object& exception = t->exception; object& exception = t->exception;
uintptr_t* stack = t->stack; uintptr_t* stack = t->stack;
@ -3067,23 +3166,23 @@ run(Thread* t)
} goto loop; } goto loop;
case aload: { case aload: {
pushObject(t, localObject(t, frame, codeBody(t, code, ip++))); pushObject(t, localObject(t, codeBody(t, code, ip++)));
} goto loop; } goto loop;
case aload_0: { case aload_0: {
pushObject(t, localObject(t, frame, 0)); pushObject(t, localObject(t, 0));
} goto loop; } goto loop;
case aload_1: { case aload_1: {
pushObject(t, localObject(t, frame, 1)); pushObject(t, localObject(t, 1));
} goto loop; } goto loop;
case aload_2: { case aload_2: {
pushObject(t, localObject(t, frame, 2)); pushObject(t, localObject(t, 2));
} goto loop; } goto loop;
case aload_3: { case aload_3: {
pushObject(t, localObject(t, frame, 3)); pushObject(t, localObject(t, 3));
} goto loop; } goto loop;
case anewarray: { case anewarray: {
@ -3110,13 +3209,10 @@ run(Thread* t)
case areturn: case areturn:
case ireturn: case ireturn:
case lreturn: { case lreturn: {
frame = frameNext(t, frame); popFrame(t);
if (frame) { if (frame >= 0) {
code = methodCode(t, frameMethod(t, frame));
ip = frameIp(t, frame);
goto loop; goto loop;
} else { } else {
code = 0;
switch (instruction) { switch (instruction) {
case areturn: case areturn:
return popObject(t); return popObject(t);
@ -3148,23 +3244,23 @@ run(Thread* t)
} abort(t); } abort(t);
case astore: { case astore: {
setLocalObject(t, frame, codeBody(t, code, ip++), popObject(t)); setLocalObject(t, codeBody(t, code, ip++), popObject(t));
} goto loop; } goto loop;
case astore_0: { case astore_0: {
setLocalObject(t, frame, 0, popObject(t)); setLocalObject(t, 0, popObject(t));
} goto loop; } goto loop;
case astore_1: { case astore_1: {
setLocalObject(t, frame, 1, popObject(t)); setLocalObject(t, 1, popObject(t));
} goto loop; } goto loop;
case astore_2: { case astore_2: {
setLocalObject(t, frame, 2, popObject(t)); setLocalObject(t, 2, popObject(t));
} goto loop; } goto loop;
case astore_3: { case astore_3: {
setLocalObject(t, frame, 3, popObject(t)); setLocalObject(t, 3, popObject(t));
} goto loop; } goto loop;
case athrow: { case athrow: {
@ -3726,27 +3822,27 @@ run(Thread* t)
uint8_t index = codeBody(t, code, ip++); uint8_t index = codeBody(t, code, ip++);
int8_t c = codeBody(t, code, ip++); int8_t c = codeBody(t, code, ip++);
setLocalInt(t, frame, index, localInt(t, frame, index) + c); setLocalInt(t, index, localInt(t, index) + c);
} goto loop; } goto loop;
case iload: { case iload: {
pushInt(t, localInt(t, frame, codeBody(t, code, ip++))); pushInt(t, localInt(t, codeBody(t, code, ip++)));
} goto loop; } goto loop;
case iload_0: { case iload_0: {
pushInt(t, localInt(t, frame, 0)); pushInt(t, localInt(t, 0));
} goto loop; } goto loop;
case iload_1: { case iload_1: {
pushInt(t, localInt(t, frame, 1)); pushInt(t, localInt(t, 1));
} goto loop; } goto loop;
case iload_2: { case iload_2: {
pushInt(t, localInt(t, frame, 2)); pushInt(t, localInt(t, 2));
} goto loop; } goto loop;
case iload_3: { case iload_3: {
pushInt(t, localInt(t, frame, 3)); pushInt(t, localInt(t, 3));
} goto loop; } goto loop;
case imul: { case imul: {
@ -3813,7 +3909,7 @@ run(Thread* t)
unsigned parameterFootprint = methodParameterFootprint(t, method); unsigned parameterFootprint = methodParameterFootprint(t, method);
if (LIKELY(peekObject(t, sp - parameterFootprint))) { if (LIKELY(peekObject(t, sp - parameterFootprint))) {
object class_ = methodClass(t, frameMethod(t, t->frame)); object class_ = methodClass(t, frameMethod(t, frame));
if (isSpecialMethod(t, method, class_)) { if (isSpecialMethod(t, method, class_)) {
code = findMethod(t, method, classSuper(t, class_)); code = findMethod(t, method, classSuper(t, class_));
if (UNLIKELY(exception)) goto throw_; if (UNLIKELY(exception)) goto throw_;
@ -3897,23 +3993,23 @@ run(Thread* t)
} goto loop; } goto loop;
case istore: { case istore: {
setLocalInt(t, frame, codeBody(t, code, ip++), popInt(t)); setLocalInt(t, codeBody(t, code, ip++), popInt(t));
} goto loop; } goto loop;
case istore_0: { case istore_0: {
setLocalInt(t, frame, 0, popInt(t)); setLocalInt(t, 0, popInt(t));
} goto loop; } goto loop;
case istore_1: { case istore_1: {
setLocalInt(t, frame, 1, popInt(t)); setLocalInt(t, 1, popInt(t));
} goto loop; } goto loop;
case istore_2: { case istore_2: {
setLocalInt(t, frame, 2, popInt(t)); setLocalInt(t, 2, popInt(t));
} goto loop; } goto loop;
case istore_3: { case istore_3: {
setLocalInt(t, frame, 3, popInt(t)); setLocalInt(t, 3, popInt(t));
} goto loop; } goto loop;
case isub: { case isub: {
@ -4082,23 +4178,23 @@ run(Thread* t)
} goto loop; } goto loop;
case lload: { case lload: {
pushLong(t, localLong(t, frame, codeBody(t, code, ip++))); pushLong(t, localLong(t, codeBody(t, code, ip++)));
} goto loop; } goto loop;
case lload_0: { case lload_0: {
pushLong(t, localLong(t, frame, 0)); pushLong(t, localLong(t, 0));
} goto loop; } goto loop;
case lload_1: { case lload_1: {
pushLong(t, localLong(t, frame, 1)); pushLong(t, localLong(t, 1));
} goto loop; } goto loop;
case lload_2: { case lload_2: {
pushLong(t, localLong(t, frame, 2)); pushLong(t, localLong(t, 2));
} goto loop; } goto loop;
case lload_3: { case lload_3: {
pushLong(t, localLong(t, frame, 3)); pushLong(t, localLong(t, 3));
} goto loop; } goto loop;
case lmul: { case lmul: {
@ -4141,23 +4237,23 @@ run(Thread* t)
} goto loop; } goto loop;
case lstore: { case lstore: {
setLocalLong(t, frame, codeBody(t, code, ip++), popLong(t)); setLocalLong(t, codeBody(t, code, ip++), popLong(t));
} goto loop; } goto loop;
case lstore_0: { case lstore_0: {
setLocalLong(t, frame, 0, popLong(t)); setLocalLong(t, 0, popLong(t));
} goto loop; } goto loop;
case lstore_1: { case lstore_1: {
setLocalLong(t, frame, 1, popLong(t)); setLocalLong(t, 1, popLong(t));
} goto loop; } goto loop;
case lstore_2: { case lstore_2: {
setLocalLong(t, frame, 2, popLong(t)); setLocalLong(t, 2, popLong(t));
} goto loop; } goto loop;
case lstore_3: { case lstore_3: {
setLocalLong(t, frame, 3, popLong(t)); setLocalLong(t, 3, popLong(t));
} goto loop; } goto loop;
case lsub: { case lsub: {
@ -4396,17 +4492,14 @@ run(Thread* t)
} goto loop; } goto loop;
case ret: { case ret: {
ip = localInt(t, frame, codeBody(t, code, ip)); ip = localInt(t, codeBody(t, code, ip));
} goto loop; } goto loop;
case return_: { case return_: {
frame = frameNext(t, frame); popFrame(t);
if (frame) { if (frame >= 0) {
code = methodCode(t, frameMethod(t, frame));
ip = frameIp(t, frame);
goto loop; goto loop;
} else { } else {
code = 0;
return 0; return 0;
} }
} goto loop; } goto loop;
@ -4479,14 +4572,14 @@ 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++);
pushObject(t, localObject(t, frame, (index1 << 8) | index2)); pushObject(t, localObject(t, (index1 << 8) | index2));
} goto loop; } goto loop;
case astore: { case astore: {
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++);
setLocalObject(t, frame, (index1 << 8) | index2, popObject(t)); setLocalObject(t, (index1 << 8) | index2, popObject(t));
} goto loop; } goto loop;
case iinc: { case iinc: {
@ -4498,64 +4591,57 @@ run(Thread* t)
uint8_t count2 = codeBody(t, code, ip++); uint8_t count2 = codeBody(t, code, ip++);
uint16_t count = (count1 << 8) | count2; uint16_t count = (count1 << 8) | count2;
setLocalInt(t, frame, index, localInt(t, frame, index) + count); setLocalInt(t, index, localInt(t, index) + count);
} goto loop; } goto loop;
case iload: { case iload: {
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++);
pushInt(t, localInt(t, frame, (index1 << 8) | index2)); pushInt(t, localInt(t, (index1 << 8) | index2));
} goto loop; } goto loop;
case istore: { case istore: {
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++);
setLocalInt(t, frame, (index1 << 8) | index2, popInt(t)); setLocalInt(t, (index1 << 8) | index2, popInt(t));
} goto loop; } goto loop;
case lload: { case lload: {
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++);
pushLong(t, localLong(t, frame, (index1 << 8) | index2)); pushLong(t, localLong(t, (index1 << 8) | index2));
} goto loop; } goto loop;
case lstore: { case lstore: {
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++);
setLocalLong(t, frame, (index1 << 8) | index2, popLong(t)); setLocalLong(t, (index1 << 8) | index2, popLong(t));
} goto loop; } goto loop;
case ret: { case ret: {
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++);
ip = localInt(t, frame, (index1 << 8) | index2); ip = localInt(t, (index1 << 8) | index2);
} goto loop; } goto loop;
default: abort(t); default: abort(t);
} }
invoke: { invoke: {
unsigned parameterFootprint = methodParameterFootprint(t, code);
unsigned base = sp - parameterFootprint;
if (methodFlags(t, code) & ACC_NATIVE) { if (methodFlags(t, code) & ACC_NATIVE) {
frame = makeFrame(t, code, frame, 0, base);
invokeNative(t, code); invokeNative(t, code);
frame = frameNext(t, frame);
if (UNLIKELY(exception)) { if (UNLIKELY(exception)) {
goto throw_; goto throw_;
} }
code = methodCode(t, frameMethod(t, frame));
} else { } else {
unsigned parameterFootprint = methodParameterFootprint(t, code);
unsigned base = sp - parameterFootprint;
if (UNLIKELY(codeMaxStack(t, methodCode(t, code)) if (UNLIKELY(codeMaxStack(t, methodCode(t, code))
+ codeMaxLocals(t, methodCode(t, code)) + base + codeMaxLocals(t, methodCode(t, code)) + base
> Thread::StackSizeInWords / 2)) > Thread::StackSizeInWords / 2))
@ -4564,21 +4650,12 @@ run(Thread* t)
goto throw_; goto throw_;
} }
frameIp(t, frame) = ip; pushFrame(t, code);
ip = 0;
frame = makeFrame(t, code, frame, 0, base);
code = methodCode(t, code);
memset(stack + ((base + parameterFootprint) * 2), 0,
(codeMaxLocals(t, code) - parameterFootprint) * BytesPerWord * 2);
sp = base + codeMaxLocals(t, code);
} }
} goto loop; } goto loop;
throw_: throw_:
for (; frame; frame = frameNext(t, frame)) { for (; frame >= 0; frame = frameNext(t, frame)) {
code = methodCode(t, frameMethod(t, frame)); code = methodCode(t, frameMethod(t, frame));
object eht = codeExceptionHandlerTable(t, code); object eht = codeExceptionHandlerTable(t, code);
if (eht) { if (eht) {
@ -4598,7 +4675,7 @@ run(Thread* t)
== arrayBody(t, t->vm->types, Machine::ClassType) and == arrayBody(t, t->vm->types, Machine::ClassType) and
instanceOf(t, catchType, exception))) instanceOf(t, catchType, exception)))
{ {
sp = frameStackBase(t, frame); sp = frameBase(t, frame);
ip = exceptionHandlerIp(eh); ip = exceptionHandlerIp(eh);
pushObject(t, exception); pushObject(t, exception);
exception = 0; exception = 0;
@ -4676,9 +4753,6 @@ run(Thread* t, const char* className, int argc, const char** argv)
object method = findMethodInClass(t, class_, reference); object method = findMethodInClass(t, class_, reference);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
t->code = methodCode(t, method);
t->frame = makeFrame(t, method, 0, 0, 0);
object args = makeObjectArray object args = makeObjectArray
(t, arrayBody(t, t->vm->types, Machine::StringType), argc, true); (t, arrayBody(t, t->vm->types, Machine::StringType), argc, true);
@ -4690,6 +4764,7 @@ run(Thread* t, const char* className, int argc, const char** argv)
} }
pushObject(t, args); pushObject(t, args);
pushFrame(t, method);
} }
} }