diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 20abcc07d4..c4d68ac9ac 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -57,7 +57,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, if (classMethodTable(t, c)) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { object method = arrayBody(t, classMethodTable(t, c), i); - if (methodCode(t, method)) { + if (methodCode(t, method) or (methodFlags(t, method) & ACC_NATIVE)) { t->m->processor->compileMethod (t, zone, code, &size, capacity, &constants, &calls, method); } diff --git a/src/compile.cpp b/src/compile.cpp index 02ae365d45..44806d71a4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1770,53 +1770,55 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target) Compiler::Operand* result = 0; if (not emptyMethod(t, target)) { - if (methodFlags(t, target) & ACC_NATIVE) { - result = c->call - (c->constant(nativeThunk(t)), - 0, - frame->trace(target, false), - rSize, - 0); - } else { - BootContext* bc = frame->context->bootContext; - if (bc) { - if (objectClass(t, target) == objectClass(t, frame->context->method)) { - Promise* p = new (bc->zone->allocate(sizeof(ListenPromise))) - ListenPromise(t->m->system, bc->zone); + BootContext* bc = frame->context->bootContext; + if (bc) { + if (methodClass(t, target) == methodClass(t, frame->context->method) + or (not classNeedsInit(t, methodClass(t, target)))) + { + Promise* p = new (bc->zone->allocate(sizeof(ListenPromise))) + ListenPromise(t->m->system, bc->zone); - PROTECT(t, target); - object pointer = makePointer(t, p); - bc->calls = makeTriple(t, target, pointer, bc->calls); + PROTECT(t, target); + object pointer = makePointer(t, p); + bc->calls = makeTriple(t, target, pointer, bc->calls); - result = c->call - (c->promiseConstant(p), - 0, - frame->trace(0, false), - rSize, - 0); - } else { - result = c->call - (c->constant(defaultThunk(t)), - Compiler::Aligned, - frame->trace(target, false), - rSize, - 0); - } - } else if (methodCompiled(t, target) == defaultThunk(t)) { + result = c->call + (c->promiseConstant(p), + 0, + frame->trace(0, false), + rSize, + 0); + } else { result = c->call (c->constant(defaultThunk(t)), Compiler::Aligned, frame->trace(target, false), rSize, 0); - } else { - result = c->call - (c->constant(methodCompiled(t, target)), - 0, - frame->trace(0, false), - rSize, - 0); } + } else if (methodFlags(t, target) & ACC_NATIVE) { + result = c->call + (c->constant(nativeThunk(t)), + 0, + frame->trace(target, false), + rSize, + 0); + } else if (methodCompiled(t, target) == defaultThunk(t) + or classNeedsInit(t, methodClass(t, target))) + { + result = c->call + (c->constant(defaultThunk(t)), + Compiler::Aligned, + frame->trace(target, false), + rSize, + 0); + } else { + result = c->call + (c->constant(methodCompiled(t, target)), + 0, + frame->trace(0, false), + rSize, + 0); } } @@ -2457,8 +2459,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* table; if (instruction == getstatic) { - if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) - and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + if (fieldClass(t, field) != methodClass(t, context->method) + and classNeedsInit(t, fieldClass(t, field))); { c->call (c->constant(getThunk(t, tryInitClassThunk)), @@ -3337,8 +3339,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, object staticTable = 0; if (instruction == putstatic) { - if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) - and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + if (fieldClass(t, field) != methodClass(t, context->method) + and classNeedsInit(t, fieldClass(t, field))) { c->call (c->constant(getThunk(t, tryInitClassThunk)), @@ -4848,9 +4850,7 @@ class MyProcessor: public Processor { PROTECT(t, c); ACQUIRE(t, t->m->classLock); - if (classVmFlags(t, c) & NeedInitFlag - and (classVmFlags(t, c) & InitFlag) == 0) - { + if (classNeedsInit(t, c)) { classVmFlags(t, c) |= InitFlag; invoke(t, classInitializer(t, c), 0); if (t->exception) { @@ -5388,19 +5388,19 @@ void compile(MyThread* t, Allocator* allocator, BootContext* bootContext, object method) { + PROTECT(t, method); + + if (bootContext == 0) { + initClass(t, methodClass(t, method)); + if (UNLIKELY(t->exception)) return; + } + MyProcessor* p = processor(t); if (methodCompiled(t, method) == defaultThunk(t)) { - PROTECT(t, method); - ACQUIRE(t, t->m->classLock); if (methodCompiled(t, method) == defaultThunk(t)) { - if (bootContext == 0) { - initClass(t, methodClass(t, method)); - if (UNLIKELY(t->exception)) return; - } - if (methodCompiled(t, method) == defaultThunk(t)) { object node; uint8_t* compiled; diff --git a/src/machine.cpp b/src/machine.cpp index f57e070b33..ed9e6b8ec6 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1560,7 +1560,7 @@ boot(Thread* t, BootImage* image) if (classMethodTable(t, c)) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { object method = arrayBody(t, classMethodTable(t, c), i); - if (methodCode(t, method)) { + if (methodCode(t, method) or (methodFlags(t, method) & ACC_NATIVE)) { assert(t, (methodCompiled(t, method) - image->codeBase) <= image->codeSize); @@ -1568,13 +1568,17 @@ boot(Thread* t, BootImage* image) = (methodCompiled(t, method) - image->codeBase) + reinterpret_cast(code); -// fprintf(stderr, "%p %p %s.%s%s\n", -// reinterpret_cast(methodCompiled(t, method)), -// reinterpret_cast(methodCompiled(t, method)) + -// reinterpret_cast(methodCompiled(t, method))[-1], -// &byteArrayBody(t, className(t, methodClass(t, method)), 0), -// &byteArrayBody(t, methodName(t, method), 0), -// &byteArrayBody(t, methodSpec(t, method), 0)); + if (false and (methodFlags(t, method) & ACC_NATIVE) == 0) { + fprintf(stderr, "%p %p %s.%s%s\n", + reinterpret_cast(methodCompiled(t, method)), + reinterpret_cast(methodCompiled(t, method)) + + reinterpret_cast + (methodCompiled(t, method))[-1], + &byteArrayBody + (t, className(t, methodClass(t, method)), 0), + &byteArrayBody(t, methodName(t, method), 0), + &byteArrayBody(t, methodSpec(t, method), 0)); + } } } } diff --git a/src/machine.h b/src/machine.h index 0e84fae7dd..becfd81e5c 100644 --- a/src/machine.h +++ b/src/machine.h @@ -2004,10 +2004,19 @@ resolveMethod(Thread* t, const char* className, const char* methodName, object resolveObjectArrayClass(Thread* t, object elementSpec); +inline bool +classNeedsInit(Thread* t, object c) +{ + return classVmFlags(t, c) & NeedInitFlag + and (classVmFlags(t, c) & InitFlag) == 0; +} + inline void initClass(Thread* t, object c) { - t->m->processor->initClass(t, c); + if (classNeedsInit(t, c)) { + t->m->processor->initClass(t, c); + } } object