mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19: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
|
||||
visitObjects(Thread* vmt, Heap::Visitor* v)
|
||||
{
|
||||
|
@ -26,8 +26,6 @@ const unsigned FrameMethodOffset = 2;
|
||||
const unsigned FrameIpOffset = 3;
|
||||
const unsigned FrameFootprint = 4;
|
||||
|
||||
class ClassInitList;
|
||||
|
||||
class Thread: public vm::Thread {
|
||||
public:
|
||||
Thread(Machine* m, object javaThread, vm::Thread* parent):
|
||||
@ -35,39 +33,16 @@ class Thread: public vm::Thread {
|
||||
ip(0),
|
||||
sp(0),
|
||||
frame(-1),
|
||||
code(0),
|
||||
classInitList(0)
|
||||
code(0)
|
||||
{ }
|
||||
|
||||
unsigned ip;
|
||||
unsigned sp;
|
||||
int frame;
|
||||
object code;
|
||||
ClassInitList* classInitList;
|
||||
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
|
||||
pushObject(Thread* t, object o)
|
||||
{
|
||||
@ -377,15 +352,6 @@ popFrame(Thread* t)
|
||||
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->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
|
||||
store(Thread* t, unsigned index)
|
||||
{
|
||||
@ -822,9 +762,7 @@ interpret3(Thread* t, const int base)
|
||||
goto throw_;
|
||||
}
|
||||
|
||||
if (UNLIKELY(classInit(t, methodClass(t, frameMethod(t, frame)), 0))) {
|
||||
goto invoke;
|
||||
}
|
||||
initClass(t, methodClass(t, frameMethod(t, frame)));
|
||||
|
||||
loop:
|
||||
instruction = codeBody(t, code, ip++);
|
||||
@ -1486,7 +1424,7 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
PROTECT(t, field);
|
||||
|
||||
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
|
||||
initClass(t, fieldClass(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));
|
||||
if (isSpecialMethod(t, method, 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_);
|
||||
} else {
|
||||
@ -1884,7 +1825,7 @@ interpret3(Thread* t, const int base)
|
||||
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||
PROTECT(t, method);
|
||||
|
||||
if (UNLIKELY(classInit(t, methodClass(t, method), 3))) goto invoke;
|
||||
initClass(t, methodClass(t, method));
|
||||
|
||||
code = method;
|
||||
} goto invoke;
|
||||
@ -1897,7 +1838,10 @@ interpret3(Thread* t, const int base)
|
||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||
if (LIKELY(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_);
|
||||
goto invoke;
|
||||
@ -2358,7 +2302,7 @@ interpret3(Thread* t, const int base)
|
||||
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||
PROTECT(t, class_);
|
||||
|
||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||
initClass(t, class_);
|
||||
|
||||
pushObject(t, make(t, class_));
|
||||
} goto loop;
|
||||
@ -2507,7 +2451,7 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
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));
|
||||
|
||||
@ -2991,26 +2935,6 @@ class MyProcessor: public Processor {
|
||||
// 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
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
for (ClassInitList* list = t->classInitList; list; list = list->next) {
|
||||
v->visit(reinterpret_cast<object*>(&(list->class_)));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
|
@ -2351,6 +2351,17 @@ invokeLoadClass(Thread* t, uintptr_t* arguments)
|
||||
(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 vm {
|
||||
@ -3187,7 +3198,7 @@ classInitializer(Thread* t, object class_)
|
||||
return o;
|
||||
}
|
||||
}
|
||||
abort(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -3334,7 +3345,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
|
||||
|
||||
classVmFlags(t, class_)
|
||||
|= (classVmFlags(t, sc)
|
||||
& (ReferenceFlag | WeakReferenceFlag | HasFinalizerFlag));
|
||||
& (ReferenceFlag | WeakReferenceFlag | HasFinalizerFlag
|
||||
| NeedInitFlag));
|
||||
}
|
||||
|
||||
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
|
||||
// which is initializing it, we should not try to initialize it
|
||||
// recursively.
|
||||
if (t->m->processor->isInitializing(t, c)) {
|
||||
if (isInitializing(t, c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3695,12 +3707,21 @@ initClass(Thread* t, object c)
|
||||
{
|
||||
PROTECT(t, c);
|
||||
|
||||
object super = classSuper(t, c);
|
||||
if (super) {
|
||||
initClass(t, super);
|
||||
}
|
||||
|
||||
if (preInitClass(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
|
||||
initVtable(Thread* t, object c) = 0;
|
||||
|
||||
virtual bool
|
||||
isInitializing(Thread* t, object c) = 0;
|
||||
|
||||
virtual void
|
||||
visitObjects(Thread* t, Heap::Visitor* v) = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user