mirror of
https://github.com/corda/corda.git
synced 2025-01-05 20:54:13 +00:00
call static initializer of superclass before that of class itself
Also, assume any class which has an ancestor class which has a static initializer needs initialization even if it doesn't have one itself, per the Java Language Spec.
This commit is contained in:
parent
1c7abe782d
commit
ef86530080
@ -8250,17 +8250,6 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool
|
|
||||||
isInitializing(Thread* t, object c)
|
|
||||||
{
|
|
||||||
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
|
|
||||||
if (s->class_ == c) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
visitObjects(Thread* vmt, Heap::Visitor* v)
|
visitObjects(Thread* vmt, Heap::Visitor* v)
|
||||||
{
|
{
|
||||||
|
@ -26,8 +26,6 @@ const unsigned FrameMethodOffset = 2;
|
|||||||
const unsigned FrameIpOffset = 3;
|
const unsigned FrameIpOffset = 3;
|
||||||
const unsigned FrameFootprint = 4;
|
const unsigned FrameFootprint = 4;
|
||||||
|
|
||||||
class ClassInitList;
|
|
||||||
|
|
||||||
class Thread: public vm::Thread {
|
class Thread: public vm::Thread {
|
||||||
public:
|
public:
|
||||||
Thread(Machine* m, object javaThread, vm::Thread* parent):
|
Thread(Machine* m, object javaThread, vm::Thread* parent):
|
||||||
@ -35,39 +33,16 @@ class Thread: public vm::Thread {
|
|||||||
ip(0),
|
ip(0),
|
||||||
sp(0),
|
sp(0),
|
||||||
frame(-1),
|
frame(-1),
|
||||||
code(0),
|
code(0)
|
||||||
classInitList(0)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
unsigned ip;
|
unsigned ip;
|
||||||
unsigned sp;
|
unsigned sp;
|
||||||
int frame;
|
int frame;
|
||||||
object code;
|
object code;
|
||||||
ClassInitList* classInitList;
|
|
||||||
uintptr_t stack[StackSizeInWords];
|
uintptr_t stack[StackSizeInWords];
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClassInitList {
|
|
||||||
public:
|
|
||||||
ClassInitList(Thread* t, object class_, ClassInitList* next):
|
|
||||||
t(t), class_(class_), next(next)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
static void push(Thread* t, object class_) {
|
|
||||||
t->classInitList = new (t->m->heap->allocate(sizeof(ClassInitList)))
|
|
||||||
ClassInitList(t, class_, t->classInitList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
|
||||||
t->classInitList = next;
|
|
||||||
t->m->heap->free(this, sizeof(ClassInitList));
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread* t;
|
|
||||||
object class_;
|
|
||||||
ClassInitList* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
pushObject(Thread* t, object o)
|
pushObject(Thread* t, object o)
|
||||||
{
|
{
|
||||||
@ -377,15 +352,6 @@ popFrame(Thread* t)
|
|||||||
release(t, peekObject(t, frameBase(t, t->frame)));
|
release(t, peekObject(t, frameBase(t, t->frame)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(methodVmFlags(t, method) & ClassInitFlag)
|
|
||||||
and t->classInitList
|
|
||||||
and t->classInitList->class_ == methodClass(t, method))
|
|
||||||
{
|
|
||||||
t->classInitList->pop();
|
|
||||||
|
|
||||||
postInitClass(t, methodClass(t, method));
|
|
||||||
}
|
|
||||||
|
|
||||||
t->sp = frameBase(t, t->frame);
|
t->sp = frameBase(t, t->frame);
|
||||||
t->frame = frameNext(t, t->frame);
|
t->frame = frameNext(t, t->frame);
|
||||||
@ -691,32 +657,6 @@ invokeNative(Thread* t, object method)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
classInit2(Thread* t, object class_, unsigned ipOffset)
|
|
||||||
{
|
|
||||||
PROTECT(t, class_);
|
|
||||||
|
|
||||||
if (preInitClass(t, class_)) {
|
|
||||||
ClassInitList::push(t, class_);
|
|
||||||
|
|
||||||
t->code = classInitializer(t, class_);
|
|
||||||
t->ip -= ipOffset;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
classInit(Thread* t, object class_, unsigned ipOffset)
|
|
||||||
{
|
|
||||||
if (UNLIKELY(classVmFlags(t, class_) & NeedInitFlag)) {
|
|
||||||
return classInit2(t, class_, ipOffset);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
store(Thread* t, unsigned index)
|
store(Thread* t, unsigned index)
|
||||||
{
|
{
|
||||||
@ -822,9 +762,7 @@ interpret3(Thread* t, const int base)
|
|||||||
goto throw_;
|
goto throw_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, methodClass(t, frameMethod(t, frame)), 0))) {
|
initClass(t, methodClass(t, frameMethod(t, frame)));
|
||||||
goto invoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
instruction = codeBody(t, code, ip++);
|
instruction = codeBody(t, code, ip++);
|
||||||
@ -1486,7 +1424,7 @@ interpret3(Thread* t, const int base)
|
|||||||
|
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
|
initClass(t, fieldClass(t, field));
|
||||||
|
|
||||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||||
|
|
||||||
@ -1864,7 +1802,10 @@ interpret3(Thread* t, const int base)
|
|||||||
object class_ = methodClass(t, frameMethod(t, frame));
|
object class_ = methodClass(t, frameMethod(t, frame));
|
||||||
if (isSpecialMethod(t, method, class_)) {
|
if (isSpecialMethod(t, method, class_)) {
|
||||||
class_ = classSuper(t, class_);
|
class_ = classSuper(t, class_);
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
PROTECT(t, method);
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
initClass(t, class_);
|
||||||
|
|
||||||
code = findVirtualMethod(t, method, class_);
|
code = findVirtualMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
@ -1884,7 +1825,7 @@ interpret3(Thread* t, const int base)
|
|||||||
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, methodClass(t, method), 3))) goto invoke;
|
initClass(t, methodClass(t, method));
|
||||||
|
|
||||||
code = method;
|
code = method;
|
||||||
} goto invoke;
|
} goto invoke;
|
||||||
@ -1897,7 +1838,10 @@ interpret3(Thread* t, const int base)
|
|||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
||||||
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
PROTECT(t, method);
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
initClass(t, class_);
|
||||||
|
|
||||||
code = findVirtualMethod(t, method, class_);
|
code = findVirtualMethod(t, method, class_);
|
||||||
goto invoke;
|
goto invoke;
|
||||||
@ -2358,7 +2302,7 @@ interpret3(Thread* t, const int base)
|
|||||||
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
initClass(t, class_);
|
||||||
|
|
||||||
pushObject(t, make(t, class_));
|
pushObject(t, make(t, class_));
|
||||||
} goto loop;
|
} goto loop;
|
||||||
@ -2507,7 +2451,7 @@ interpret3(Thread* t, const int base)
|
|||||||
|
|
||||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
|
initClass(t, fieldClass(t, field));
|
||||||
|
|
||||||
object table = classStaticTable(t, fieldClass(t, field));
|
object table = classStaticTable(t, fieldClass(t, field));
|
||||||
|
|
||||||
@ -2991,26 +2935,6 @@ class MyProcessor: public Processor {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool
|
|
||||||
isInitializing(vm::Thread* vmt, object c)
|
|
||||||
{
|
|
||||||
Thread* t = static_cast<Thread*>(vmt);
|
|
||||||
|
|
||||||
for (ClassInitList* list = t->classInitList; list; list = list->next) {
|
|
||||||
if (list->class_ == c) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
|
|
||||||
if (s->class_ == c) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
visitObjects(vm::Thread* vmt, Heap::Visitor* v)
|
visitObjects(vm::Thread* vmt, Heap::Visitor* v)
|
||||||
{
|
{
|
||||||
@ -3023,10 +2947,6 @@ class MyProcessor: public Processor {
|
|||||||
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
|
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClassInitList* list = t->classInitList; list; list = list->next) {
|
|
||||||
v->visit(reinterpret_cast<object*>(&(list->class_)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
|
@ -2351,6 +2351,17 @@ invokeLoadClass(Thread* t, uintptr_t* arguments)
|
|||||||
(t->m->processor->invoke(t, method, loader, specString));
|
(t->m->processor->invoke(t, method, loader, specString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isInitializing(Thread* t, object c)
|
||||||
|
{
|
||||||
|
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
|
||||||
|
if (s->class_ == c) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
@ -3187,7 +3198,7 @@ classInitializer(Thread* t, object class_)
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
abort(t);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -3334,7 +3345,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
|
|||||||
|
|
||||||
classVmFlags(t, class_)
|
classVmFlags(t, class_)
|
||||||
|= (classVmFlags(t, sc)
|
|= (classVmFlags(t, sc)
|
||||||
& (ReferenceFlag | WeakReferenceFlag | HasFinalizerFlag));
|
& (ReferenceFlag | WeakReferenceFlag | HasFinalizerFlag
|
||||||
|
| NeedInitFlag));
|
||||||
}
|
}
|
||||||
|
|
||||||
parseInterfaceTable(t, s, class_, pool, throwType);
|
parseInterfaceTable(t, s, class_, pool, throwType);
|
||||||
@ -3648,7 +3660,7 @@ preInitClass(Thread* t, object c)
|
|||||||
// If the class is currently being initialized and this the thread
|
// If the class is currently being initialized and this the thread
|
||||||
// which is initializing it, we should not try to initialize it
|
// which is initializing it, we should not try to initialize it
|
||||||
// recursively.
|
// recursively.
|
||||||
if (t->m->processor->isInitializing(t, c)) {
|
if (isInitializing(t, c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3695,12 +3707,21 @@ initClass(Thread* t, object c)
|
|||||||
{
|
{
|
||||||
PROTECT(t, c);
|
PROTECT(t, c);
|
||||||
|
|
||||||
|
object super = classSuper(t, c);
|
||||||
|
if (super) {
|
||||||
|
initClass(t, super);
|
||||||
|
}
|
||||||
|
|
||||||
if (preInitClass(t, c)) {
|
if (preInitClass(t, c)) {
|
||||||
OBJECT_RESOURCE(t, c, postInitClass(t, c));
|
OBJECT_RESOURCE(t, c, postInitClass(t, c));
|
||||||
|
|
||||||
Thread::ClassInitStack stack(t, c);
|
object initializer = classInitializer(t, c);
|
||||||
|
|
||||||
t->m->processor->invoke(t, classInitializer(t, c), 0);
|
if (initializer) {
|
||||||
|
Thread::ClassInitStack stack(t, c);
|
||||||
|
|
||||||
|
t->m->processor->invoke(t, initializer, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,6 @@ class Processor {
|
|||||||
virtual void
|
virtual void
|
||||||
initVtable(Thread* t, object c) = 0;
|
initVtable(Thread* t, object c) = 0;
|
||||||
|
|
||||||
virtual bool
|
|
||||||
isInitializing(Thread* t, object c) = 0;
|
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
visitObjects(Thread* t, Heap::Visitor* v) = 0;
|
visitObjects(Thread* t, Heap::Visitor* v) = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user