mirror of
https://github.com/corda/corda.git
synced 2025-03-03 21:00:56 +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)) {
|
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);
|
||||||
}
|
}
|
||||||
|
104
src/compile.cpp
104
src/compile.cpp
@ -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;
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user