mirror of
https://github.com/corda/corda.git
synced 2025-03-03 12:57:29 +00:00
fix static class initialization when using a boot image
This commit is contained in:
parent
e44f326377
commit
eaf30eb909
@ -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);
|
||||
}
|
||||
|
104
src/compile.cpp
104
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;
|
||||
|
@ -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<uintptr_t>(code);
|
||||
|
||||
// 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],
|
||||
// &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<uint8_t*>(methodCompiled(t, method)),
|
||||
reinterpret_cast<uint8_t*>(methodCompiled(t, method)) +
|
||||
reinterpret_cast<uintptr_t*>
|
||||
(methodCompiled(t, method))[-1],
|
||||
&byteArrayBody
|
||||
(t, className(t, methodClass(t, method)), 0),
|
||||
&byteArrayBody(t, methodName(t, method), 0),
|
||||
&byteArrayBody(t, methodSpec(t, method), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user