fix static class initialization when using a boot image

This commit is contained in:
Joel Dice 2008-11-29 21:58:09 -07:00
parent e44f326377
commit eaf30eb909
4 changed files with 75 additions and 62 deletions

View File

@ -57,7 +57,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
if (classMethodTable(t, c)) { if (classMethodTable(t, c)) {
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object method = arrayBody(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->m->processor->compileMethod
(t, zone, code, &size, capacity, &constants, &calls, method); (t, zone, code, &size, capacity, &constants, &calls, method);
} }

View File

@ -1770,53 +1770,55 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target)
Compiler::Operand* result = 0; Compiler::Operand* result = 0;
if (not emptyMethod(t, target)) { if (not emptyMethod(t, target)) {
if (methodFlags(t, target) & ACC_NATIVE) { BootContext* bc = frame->context->bootContext;
result = c->call if (bc) {
(c->constant(nativeThunk(t)), if (methodClass(t, target) == methodClass(t, frame->context->method)
0, or (not classNeedsInit(t, methodClass(t, target))))
frame->trace(target, false), {
rSize, Promise* p = new (bc->zone->allocate(sizeof(ListenPromise)))
0); ListenPromise(t->m->system, bc->zone);
} 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);
PROTECT(t, target); PROTECT(t, target);
object pointer = makePointer(t, p); object pointer = makePointer(t, p);
bc->calls = makeTriple(t, target, pointer, bc->calls); bc->calls = makeTriple(t, target, pointer, bc->calls);
result = c->call result = c->call
(c->promiseConstant(p), (c->promiseConstant(p),
0, 0,
frame->trace(0, false), frame->trace(0, false),
rSize, rSize,
0); 0);
} else { } 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 result = c->call
(c->constant(defaultThunk(t)), (c->constant(defaultThunk(t)),
Compiler::Aligned, Compiler::Aligned,
frame->trace(target, false), frame->trace(target, false),
rSize, rSize,
0); 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; Compiler::Operand* table;
if (instruction == getstatic) { if (instruction == getstatic) {
if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) if (fieldClass(t, field) != methodClass(t, context->method)
and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) and classNeedsInit(t, fieldClass(t, field)));
{ {
c->call c->call
(c->constant(getThunk(t, tryInitClassThunk)), (c->constant(getThunk(t, tryInitClassThunk)),
@ -3337,8 +3339,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object staticTable = 0; object staticTable = 0;
if (instruction == putstatic) { if (instruction == putstatic) {
if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) if (fieldClass(t, field) != methodClass(t, context->method)
and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) and classNeedsInit(t, fieldClass(t, field)))
{ {
c->call c->call
(c->constant(getThunk(t, tryInitClassThunk)), (c->constant(getThunk(t, tryInitClassThunk)),
@ -4848,9 +4850,7 @@ class MyProcessor: public Processor {
PROTECT(t, c); PROTECT(t, c);
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
if (classVmFlags(t, c) & NeedInitFlag if (classNeedsInit(t, c)) {
and (classVmFlags(t, c) & InitFlag) == 0)
{
classVmFlags(t, c) |= InitFlag; classVmFlags(t, c) |= InitFlag;
invoke(t, classInitializer(t, c), 0); invoke(t, classInitializer(t, c), 0);
if (t->exception) { if (t->exception) {
@ -5388,19 +5388,19 @@ void
compile(MyThread* t, Allocator* allocator, BootContext* bootContext, compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
object method) object method)
{ {
PROTECT(t, method);
if (bootContext == 0) {
initClass(t, methodClass(t, method));
if (UNLIKELY(t->exception)) return;
}
MyProcessor* p = processor(t); MyProcessor* p = processor(t);
if (methodCompiled(t, method) == defaultThunk(t)) { if (methodCompiled(t, method) == defaultThunk(t)) {
PROTECT(t, method);
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
if (methodCompiled(t, method) == defaultThunk(t)) { 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)) { if (methodCompiled(t, method) == defaultThunk(t)) {
object node; object node;
uint8_t* compiled; uint8_t* compiled;

View File

@ -1560,7 +1560,7 @@ boot(Thread* t, BootImage* image)
if (classMethodTable(t, c)) { if (classMethodTable(t, c)) {
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object method = arrayBody(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) assert(t, (methodCompiled(t, method) - image->codeBase)
<= image->codeSize); <= image->codeSize);
@ -1568,13 +1568,17 @@ boot(Thread* t, BootImage* image)
= (methodCompiled(t, method) - image->codeBase) = (methodCompiled(t, method) - image->codeBase)
+ reinterpret_cast<uintptr_t>(code); + reinterpret_cast<uintptr_t>(code);
// fprintf(stderr, "%p %p %s.%s%s\n", if (false and (methodFlags(t, method) & ACC_NATIVE) == 0) {
// reinterpret_cast<uint8_t*>(methodCompiled(t, method)), fprintf(stderr, "%p %p %s.%s%s\n",
// reinterpret_cast<uint8_t*>(methodCompiled(t, method)) + reinterpret_cast<uint8_t*>(methodCompiled(t, method)),
// reinterpret_cast<uintptr_t*>(methodCompiled(t, method))[-1], reinterpret_cast<uint8_t*>(methodCompiled(t, method)) +
// &byteArrayBody(t, className(t, methodClass(t, method)), 0), reinterpret_cast<uintptr_t*>
// &byteArrayBody(t, methodName(t, method), 0), (methodCompiled(t, method))[-1],
// &byteArrayBody(t, methodSpec(t, method), 0)); &byteArrayBody
(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0),
&byteArrayBody(t, methodSpec(t, method), 0));
}
} }
} }
} }

View File

@ -2004,10 +2004,19 @@ resolveMethod(Thread* t, const char* className, const char* methodName,
object object
resolveObjectArrayClass(Thread* t, object elementSpec); 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 inline void
initClass(Thread* t, object c) initClass(Thread* t, object c)
{ {
t->m->processor->initClass(t, c); if (classNeedsInit(t, c)) {
t->m->processor->initClass(t, c);
}
} }
object object