mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
store frame data on the stack, not the heap
This commit is contained in:
parent
56467e61d7
commit
dc8232eddf
@ -8,6 +8,14 @@
|
||||
#include "stdio.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 LIKELY(v) __builtin_expect((v) != 0, true)
|
||||
|
@ -16,7 +16,6 @@
|
||||
using namespace vm;
|
||||
|
||||
#ifdef __i386__
|
||||
#define LD "%d"
|
||||
|
||||
extern "C" uint64_t
|
||||
cdeclCall(void* function, void* stack, unsigned stackSize,
|
||||
@ -34,7 +33,6 @@ dynamicCall(void* function, uint32_t* arguments, uint8_t*,
|
||||
} // namespace
|
||||
|
||||
#elif defined __x86_64__
|
||||
#define LD "%ld"
|
||||
|
||||
extern "C" uint64_t
|
||||
amd64Call(void* function, void* stack, unsigned stackSize,
|
||||
|
@ -68,12 +68,6 @@
|
||||
(uint16_t maxLocals)
|
||||
(array uint8_t body))
|
||||
|
||||
(type frame
|
||||
(object method)
|
||||
(object next)
|
||||
(uint32_t ip)
|
||||
(uint32_t stackBase))
|
||||
|
||||
(type reference
|
||||
(object class)
|
||||
(object name)
|
||||
|
297
src/vm.cpp
297
src/vm.cpp
@ -20,7 +20,7 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
const bool Verbose = true;
|
||||
const bool Verbose = false;
|
||||
const bool Debug = false;
|
||||
const bool DebugRun = false;
|
||||
const bool DebugStack = false;
|
||||
@ -28,6 +28,12 @@ const bool DebugStack = false;
|
||||
const uintptr_t HashTakenMark = 1;
|
||||
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;
|
||||
|
||||
void (*Initializer)(Thread*, object);
|
||||
@ -165,11 +171,11 @@ class Thread : public JNIEnv {
|
||||
Thread* child;
|
||||
State state;
|
||||
object thread;
|
||||
object frame;
|
||||
object code;
|
||||
object exception;
|
||||
unsigned ip;
|
||||
unsigned sp;
|
||||
int frame;
|
||||
unsigned heapIndex;
|
||||
Protector* protector;
|
||||
Chain* chain;
|
||||
@ -563,6 +569,7 @@ pushObject(Thread* t, object o)
|
||||
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) + 1] = reinterpret_cast<uintptr_t>(o);
|
||||
++ t->sp;
|
||||
@ -575,6 +582,7 @@ pushInt(Thread* t, uint32_t v)
|
||||
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) + 1] = v;
|
||||
++ t->sp;
|
||||
@ -584,7 +592,7 @@ inline void
|
||||
pushLong(Thread* t, uint64_t v)
|
||||
{
|
||||
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);
|
||||
@ -608,7 +616,7 @@ inline uint32_t
|
||||
popInt(Thread* t)
|
||||
{
|
||||
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->sp - 1);
|
||||
}
|
||||
@ -621,7 +629,7 @@ inline uint64_t
|
||||
popLong(Thread* t)
|
||||
{
|
||||
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 - 1) * 2) + 1]),
|
||||
t->sp - 2);
|
||||
@ -641,6 +649,7 @@ peekObject(Thread* t, unsigned index)
|
||||
index);
|
||||
}
|
||||
|
||||
assert(t, index < Thread::StackSizeInWords / 2);
|
||||
assert(t, t->stack[index * 2] == ObjectTag);
|
||||
return *reinterpret_cast<object*>(t->stack + (index * 2) + 1);
|
||||
}
|
||||
@ -649,11 +658,12 @@ inline uint32_t
|
||||
peekInt(Thread* t, unsigned index)
|
||||
{
|
||||
if (DebugStack) {
|
||||
fprintf(stderr, "peek int %d at %d\n",
|
||||
fprintf(stderr, "peek int " LD " at %d\n",
|
||||
t->stack[(index * 2) + 1],
|
||||
index);
|
||||
}
|
||||
|
||||
assert(t, index < Thread::StackSizeInWords / 2);
|
||||
assert(t, t->stack[index * 2] == IntTag);
|
||||
return t->stack[(index * 2) + 1];
|
||||
}
|
||||
@ -662,7 +672,7 @@ inline uint64_t
|
||||
peekLong(Thread* t, unsigned index)
|
||||
{
|
||||
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 + 1) * 2) + 1]),
|
||||
index);
|
||||
@ -698,7 +708,7 @@ inline void
|
||||
pokeLong(Thread* t, unsigned index, uint64_t value)
|
||||
{
|
||||
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);
|
||||
@ -713,6 +723,75 @@ pushReference(Thread* t, object o)
|
||||
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
|
||||
Thread::dispose()
|
||||
{
|
||||
@ -729,7 +808,6 @@ visitRoots(Thread* t, Heap::Visitor* v)
|
||||
t->heapIndex = 0;
|
||||
|
||||
v->visit(&(t->thread));
|
||||
v->visit(&(t->frame));
|
||||
v->visit(&(t->code));
|
||||
v->visit(&(t->exception));
|
||||
|
||||
@ -1213,12 +1291,10 @@ makeString(Thread* t, const char* format, ...)
|
||||
}
|
||||
|
||||
object
|
||||
makeTrace(Thread* t, object frame)
|
||||
makeTrace(Thread* t, int frame)
|
||||
{
|
||||
PROTECT(t, frame);
|
||||
|
||||
unsigned count = 0;
|
||||
for (object f = frame; f; f = frameNext(t, f)) {
|
||||
for (int f = frame; f >= 0; f = frameNext(t, f)) {
|
||||
++ count;
|
||||
}
|
||||
|
||||
@ -1228,7 +1304,7 @@ makeTrace(Thread* t, object frame)
|
||||
PROTECT(t, trace);
|
||||
|
||||
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));
|
||||
set(t, objectArrayBody(t, trace, index++), e);
|
||||
}
|
||||
@ -1239,7 +1315,7 @@ makeTrace(Thread* t, object frame)
|
||||
object
|
||||
makeTrace(Thread* t)
|
||||
{
|
||||
frameIp(t, t->frame) = t->ip;
|
||||
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
||||
return makeTrace(t, t->frame);
|
||||
}
|
||||
|
||||
@ -1904,6 +1980,16 @@ parameterFootprint(Thread* t, object spec)
|
||||
|
||||
case '[':
|
||||
while (*s == '[') ++ s;
|
||||
switch (*s) {
|
||||
case 'L':
|
||||
while (*s and *s != ';') ++ s;
|
||||
++ s;
|
||||
break;
|
||||
|
||||
default:
|
||||
++ s;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
@ -1938,6 +2024,16 @@ parameterCount(Thread* t, object spec)
|
||||
|
||||
case '[':
|
||||
while (*s == '[') ++ s;
|
||||
switch (*s) {
|
||||
case 'L':
|
||||
while (*s and *s != ';') ++ s;
|
||||
++ s;
|
||||
break;
|
||||
|
||||
default:
|
||||
++ s;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2608,7 +2704,8 @@ invokeNative(Thread* t, object method)
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned footprint = methodParameterFootprint(t, method);
|
||||
pushFrame(t, method);
|
||||
|
||||
unsigned count = methodParameterCount(t, method);
|
||||
|
||||
unsigned size = nativeMethodDataArgumentTableSize(t, data);
|
||||
@ -2617,7 +2714,7 @@ invokeNative(Thread* t, object method)
|
||||
|
||||
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) {
|
||||
unsigned type = nativeMethodDataParameterTypes(t, data, i + 1);
|
||||
|
||||
@ -2667,12 +2764,12 @@ invokeNative(Thread* t, object method)
|
||||
enter(t, Thread::ActiveState);
|
||||
}
|
||||
|
||||
popFrame(t);
|
||||
|
||||
if (UNLIKELY(t->exception)) {
|
||||
return;
|
||||
}
|
||||
|
||||
t->sp = frameStackBase(t, t->frame);
|
||||
|
||||
switch (returnCode) {
|
||||
case ByteField:
|
||||
case BooleanField:
|
||||
@ -2702,39 +2799,39 @@ invokeNative(Thread* t, object method)
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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 {
|
||||
@ -2784,8 +2881,10 @@ trace(JNIEnv* e, jint skipCount)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(e);
|
||||
|
||||
object frame = t->frame;
|
||||
while (skipCount--) frame = frameNext(t, frame);
|
||||
int frame = t->frame;
|
||||
while (skipCount-- and frame >= 0) {
|
||||
frame = frameNext(t, frame);
|
||||
}
|
||||
|
||||
if (methodClass(t, frameMethod(t, frame))
|
||||
== arrayBody(t, t->vm->types, Machine::ThrowableType))
|
||||
@ -2918,11 +3017,11 @@ Thread::Thread(Machine* m):
|
||||
child(0),
|
||||
state(NoState),
|
||||
thread(0),
|
||||
frame(0),
|
||||
code(0),
|
||||
exception(0),
|
||||
ip(0),
|
||||
sp(0),
|
||||
frame(-1),
|
||||
heapIndex(0),
|
||||
protector(0),
|
||||
chain(0)
|
||||
@ -2986,8 +3085,8 @@ run(Thread* t)
|
||||
unsigned instruction = nop;
|
||||
unsigned& ip = t->ip;
|
||||
unsigned& sp = t->sp;
|
||||
int& frame = t->frame;
|
||||
object& code = t->code;
|
||||
object& frame = t->frame;
|
||||
object& exception = t->exception;
|
||||
uintptr_t* stack = t->stack;
|
||||
|
||||
@ -3067,23 +3166,23 @@ run(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case aload: {
|
||||
pushObject(t, localObject(t, frame, codeBody(t, code, ip++)));
|
||||
pushObject(t, localObject(t, codeBody(t, code, ip++)));
|
||||
} goto loop;
|
||||
|
||||
case aload_0: {
|
||||
pushObject(t, localObject(t, frame, 0));
|
||||
pushObject(t, localObject(t, 0));
|
||||
} goto loop;
|
||||
|
||||
case aload_1: {
|
||||
pushObject(t, localObject(t, frame, 1));
|
||||
pushObject(t, localObject(t, 1));
|
||||
} goto loop;
|
||||
|
||||
case aload_2: {
|
||||
pushObject(t, localObject(t, frame, 2));
|
||||
pushObject(t, localObject(t, 2));
|
||||
} goto loop;
|
||||
|
||||
case aload_3: {
|
||||
pushObject(t, localObject(t, frame, 3));
|
||||
pushObject(t, localObject(t, 3));
|
||||
} goto loop;
|
||||
|
||||
case anewarray: {
|
||||
@ -3110,13 +3209,10 @@ run(Thread* t)
|
||||
case areturn:
|
||||
case ireturn:
|
||||
case lreturn: {
|
||||
frame = frameNext(t, frame);
|
||||
if (frame) {
|
||||
code = methodCode(t, frameMethod(t, frame));
|
||||
ip = frameIp(t, frame);
|
||||
popFrame(t);
|
||||
if (frame >= 0) {
|
||||
goto loop;
|
||||
} else {
|
||||
code = 0;
|
||||
switch (instruction) {
|
||||
case areturn:
|
||||
return popObject(t);
|
||||
@ -3148,23 +3244,23 @@ run(Thread* t)
|
||||
} abort(t);
|
||||
|
||||
case astore: {
|
||||
setLocalObject(t, frame, codeBody(t, code, ip++), popObject(t));
|
||||
setLocalObject(t, codeBody(t, code, ip++), popObject(t));
|
||||
} goto loop;
|
||||
|
||||
case astore_0: {
|
||||
setLocalObject(t, frame, 0, popObject(t));
|
||||
setLocalObject(t, 0, popObject(t));
|
||||
} goto loop;
|
||||
|
||||
case astore_1: {
|
||||
setLocalObject(t, frame, 1, popObject(t));
|
||||
setLocalObject(t, 1, popObject(t));
|
||||
} goto loop;
|
||||
|
||||
case astore_2: {
|
||||
setLocalObject(t, frame, 2, popObject(t));
|
||||
setLocalObject(t, 2, popObject(t));
|
||||
} goto loop;
|
||||
|
||||
case astore_3: {
|
||||
setLocalObject(t, frame, 3, popObject(t));
|
||||
setLocalObject(t, 3, popObject(t));
|
||||
} goto loop;
|
||||
|
||||
case athrow: {
|
||||
@ -3726,27 +3822,27 @@ run(Thread* t)
|
||||
uint8_t index = 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;
|
||||
|
||||
case iload: {
|
||||
pushInt(t, localInt(t, frame, codeBody(t, code, ip++)));
|
||||
pushInt(t, localInt(t, codeBody(t, code, ip++)));
|
||||
} goto loop;
|
||||
|
||||
case iload_0: {
|
||||
pushInt(t, localInt(t, frame, 0));
|
||||
pushInt(t, localInt(t, 0));
|
||||
} goto loop;
|
||||
|
||||
case iload_1: {
|
||||
pushInt(t, localInt(t, frame, 1));
|
||||
pushInt(t, localInt(t, 1));
|
||||
} goto loop;
|
||||
|
||||
case iload_2: {
|
||||
pushInt(t, localInt(t, frame, 2));
|
||||
pushInt(t, localInt(t, 2));
|
||||
} goto loop;
|
||||
|
||||
case iload_3: {
|
||||
pushInt(t, localInt(t, frame, 3));
|
||||
pushInt(t, localInt(t, 3));
|
||||
} goto loop;
|
||||
|
||||
case imul: {
|
||||
@ -3813,7 +3909,7 @@ run(Thread* t)
|
||||
|
||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||
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_)) {
|
||||
code = findMethod(t, method, classSuper(t, class_));
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
@ -3897,23 +3993,23 @@ run(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case istore: {
|
||||
setLocalInt(t, frame, codeBody(t, code, ip++), popInt(t));
|
||||
setLocalInt(t, codeBody(t, code, ip++), popInt(t));
|
||||
} goto loop;
|
||||
|
||||
case istore_0: {
|
||||
setLocalInt(t, frame, 0, popInt(t));
|
||||
setLocalInt(t, 0, popInt(t));
|
||||
} goto loop;
|
||||
|
||||
case istore_1: {
|
||||
setLocalInt(t, frame, 1, popInt(t));
|
||||
setLocalInt(t, 1, popInt(t));
|
||||
} goto loop;
|
||||
|
||||
case istore_2: {
|
||||
setLocalInt(t, frame, 2, popInt(t));
|
||||
setLocalInt(t, 2, popInt(t));
|
||||
} goto loop;
|
||||
|
||||
case istore_3: {
|
||||
setLocalInt(t, frame, 3, popInt(t));
|
||||
setLocalInt(t, 3, popInt(t));
|
||||
} goto loop;
|
||||
|
||||
case isub: {
|
||||
@ -4082,23 +4178,23 @@ run(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case lload: {
|
||||
pushLong(t, localLong(t, frame, codeBody(t, code, ip++)));
|
||||
pushLong(t, localLong(t, codeBody(t, code, ip++)));
|
||||
} goto loop;
|
||||
|
||||
case lload_0: {
|
||||
pushLong(t, localLong(t, frame, 0));
|
||||
pushLong(t, localLong(t, 0));
|
||||
} goto loop;
|
||||
|
||||
case lload_1: {
|
||||
pushLong(t, localLong(t, frame, 1));
|
||||
pushLong(t, localLong(t, 1));
|
||||
} goto loop;
|
||||
|
||||
case lload_2: {
|
||||
pushLong(t, localLong(t, frame, 2));
|
||||
pushLong(t, localLong(t, 2));
|
||||
} goto loop;
|
||||
|
||||
case lload_3: {
|
||||
pushLong(t, localLong(t, frame, 3));
|
||||
pushLong(t, localLong(t, 3));
|
||||
} goto loop;
|
||||
|
||||
case lmul: {
|
||||
@ -4141,23 +4237,23 @@ run(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case lstore: {
|
||||
setLocalLong(t, frame, codeBody(t, code, ip++), popLong(t));
|
||||
setLocalLong(t, codeBody(t, code, ip++), popLong(t));
|
||||
} goto loop;
|
||||
|
||||
case lstore_0: {
|
||||
setLocalLong(t, frame, 0, popLong(t));
|
||||
setLocalLong(t, 0, popLong(t));
|
||||
} goto loop;
|
||||
|
||||
case lstore_1: {
|
||||
setLocalLong(t, frame, 1, popLong(t));
|
||||
setLocalLong(t, 1, popLong(t));
|
||||
} goto loop;
|
||||
|
||||
case lstore_2: {
|
||||
setLocalLong(t, frame, 2, popLong(t));
|
||||
setLocalLong(t, 2, popLong(t));
|
||||
} goto loop;
|
||||
|
||||
case lstore_3: {
|
||||
setLocalLong(t, frame, 3, popLong(t));
|
||||
setLocalLong(t, 3, popLong(t));
|
||||
} goto loop;
|
||||
|
||||
case lsub: {
|
||||
@ -4396,17 +4492,14 @@ run(Thread* t)
|
||||
} goto loop;
|
||||
|
||||
case ret: {
|
||||
ip = localInt(t, frame, codeBody(t, code, ip));
|
||||
ip = localInt(t, codeBody(t, code, ip));
|
||||
} goto loop;
|
||||
|
||||
case return_: {
|
||||
frame = frameNext(t, frame);
|
||||
if (frame) {
|
||||
code = methodCode(t, frameMethod(t, frame));
|
||||
ip = frameIp(t, frame);
|
||||
popFrame(t);
|
||||
if (frame >= 0) {
|
||||
goto loop;
|
||||
} else {
|
||||
code = 0;
|
||||
return 0;
|
||||
}
|
||||
} goto loop;
|
||||
@ -4479,14 +4572,14 @@ run(Thread* t)
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case astore: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case iinc: {
|
||||
@ -4498,64 +4591,57 @@ run(Thread* t)
|
||||
uint8_t count2 = codeBody(t, code, ip++);
|
||||
uint16_t count = (count1 << 8) | count2;
|
||||
|
||||
setLocalInt(t, frame, index, localInt(t, frame, index) + count);
|
||||
setLocalInt(t, index, localInt(t, index) + count);
|
||||
} goto loop;
|
||||
|
||||
case iload: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case istore: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case lload: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case lstore: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
case ret: {
|
||||
uint8_t index1 = 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;
|
||||
|
||||
default: abort(t);
|
||||
}
|
||||
|
||||
invoke: {
|
||||
unsigned parameterFootprint = methodParameterFootprint(t, code);
|
||||
unsigned base = sp - parameterFootprint;
|
||||
|
||||
invoke: {
|
||||
if (methodFlags(t, code) & ACC_NATIVE) {
|
||||
frame = makeFrame(t, code, frame, 0, base);
|
||||
|
||||
invokeNative(t, code);
|
||||
|
||||
frame = frameNext(t, frame);
|
||||
|
||||
if (UNLIKELY(exception)) {
|
||||
goto throw_;
|
||||
}
|
||||
|
||||
code = methodCode(t, frameMethod(t, frame));
|
||||
} else {
|
||||
unsigned parameterFootprint = methodParameterFootprint(t, code);
|
||||
unsigned base = sp - parameterFootprint;
|
||||
if (UNLIKELY(codeMaxStack(t, methodCode(t, code))
|
||||
+ codeMaxLocals(t, methodCode(t, code)) + base
|
||||
> Thread::StackSizeInWords / 2))
|
||||
@ -4564,21 +4650,12 @@ run(Thread* t)
|
||||
goto throw_;
|
||||
}
|
||||
|
||||
frameIp(t, frame) = ip;
|
||||
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);
|
||||
pushFrame(t, code);
|
||||
}
|
||||
} goto loop;
|
||||
|
||||
throw_:
|
||||
for (; frame; frame = frameNext(t, frame)) {
|
||||
for (; frame >= 0; frame = frameNext(t, frame)) {
|
||||
code = methodCode(t, frameMethod(t, frame));
|
||||
object eht = codeExceptionHandlerTable(t, code);
|
||||
if (eht) {
|
||||
@ -4598,7 +4675,7 @@ run(Thread* t)
|
||||
== arrayBody(t, t->vm->types, Machine::ClassType) and
|
||||
instanceOf(t, catchType, exception)))
|
||||
{
|
||||
sp = frameStackBase(t, frame);
|
||||
sp = frameBase(t, frame);
|
||||
ip = exceptionHandlerIp(eh);
|
||||
pushObject(t, exception);
|
||||
exception = 0;
|
||||
@ -4676,9 +4753,6 @@ run(Thread* t, const char* className, int argc, const char** argv)
|
||||
|
||||
object method = findMethodInClass(t, class_, reference);
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
t->code = methodCode(t, method);
|
||||
t->frame = makeFrame(t, method, 0, 0, 0);
|
||||
|
||||
object args = makeObjectArray
|
||||
(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);
|
||||
pushFrame(t, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user