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:
Joel Dice 2011-03-31 19:43:49 -06:00
parent 1c7abe782d
commit ef86530080
4 changed files with 40 additions and 113 deletions

View File

@ -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)
{ {

View File

@ -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

View File

@ -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);
}
} }
} }

View File

@ -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;