mirror of
https://github.com/corda/corda.git
synced 2025-01-08 14:03:06 +00:00
only initialize class when necessary to avoid deadlock
Previously, we would attempt to initialize a class (e.g. call its static initializer) whenever a method in that class was called, as well as in any of the cases listed in http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4. However, the above approach may lead to deadlock in an app which relies on being able to call non-static methods in parallel with a static initializer invocation in the same class. Thus, this commit ensures that we initialize classes only in the cases defined by the standard.
This commit is contained in:
parent
ed96693166
commit
bbc5d7fb50
@ -4790,9 +4790,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
|
|||||||
|
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
if (fieldClass(t, field) != methodClass(t, context->method)
|
if (classNeedsInit(t, fieldClass(t, field))) {
|
||||||
and classNeedsInit(t, fieldClass(t, field)))
|
|
||||||
{
|
|
||||||
c->call
|
c->call
|
||||||
(c->constant
|
(c->constant
|
||||||
(getThunk(t, tryInitClassThunk), Compiler::AddressType),
|
(getThunk(t, tryInitClassThunk), Compiler::AddressType),
|
||||||
@ -5970,9 +5968,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
|
|||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
checkField(t, field, true);
|
checkField(t, field, true);
|
||||||
|
|
||||||
if (fieldClass(t, field) != methodClass(t, context->method)
|
if (classNeedsInit(t, fieldClass(t, field))) {
|
||||||
and classNeedsInit(t, fieldClass(t, field)))
|
|
||||||
{
|
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
c->call
|
c->call
|
||||||
@ -10440,7 +10436,7 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext,
|
|||||||
{
|
{
|
||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
if (bootContext == 0) {
|
if (bootContext == 0 and methodFlags(t, method) & ACC_STATIC) {
|
||||||
initClass(t, methodClass(t, method));
|
initClass(t, methodClass(t, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,8 +791,6 @@ interpret3(Thread* t, const int base)
|
|||||||
goto throw_;
|
goto throw_;
|
||||||
}
|
}
|
||||||
|
|
||||||
initClass(t, methodClass(t, frameMethod(t, frame)));
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
instruction = codeBody(t, code, ip++);
|
instruction = codeBody(t, code, ip++);
|
||||||
|
|
||||||
@ -1907,8 +1905,6 @@ interpret3(Thread* t, const int base)
|
|||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
initClass(t, class_);
|
|
||||||
|
|
||||||
code = findVirtualMethod(t, method, class_);
|
code = findVirtualMethod(t, method, class_);
|
||||||
goto invoke;
|
goto invoke;
|
||||||
} else {
|
} else {
|
||||||
@ -2909,7 +2905,9 @@ invoke(Thread* t, object method)
|
|||||||
class_ = methodClass(t, method);
|
class_ = methodClass(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (methodFlags(t, method) & ACC_STATIC) {
|
||||||
initClass(t, class_);
|
initClass(t, class_);
|
||||||
|
}
|
||||||
|
|
||||||
object result = 0;
|
object result = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user