From bbc5d7fb50a1ed7c549ba7735dac81c21d4c80a6 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 30 Apr 2013 22:48:43 -0600 Subject: [PATCH] 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. --- src/compile.cpp | 10 +++------- src/interpret.cpp | 8 +++----- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index d218048f40..24737d8344 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4790,9 +4790,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, PROTECT(t, field); - if (fieldClass(t, field) != methodClass(t, context->method) - and classNeedsInit(t, fieldClass(t, field))) - { + if (classNeedsInit(t, fieldClass(t, field))) { c->call (c->constant (getThunk(t, tryInitClassThunk), Compiler::AddressType), @@ -5970,9 +5968,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, if (instruction == putstatic) { checkField(t, field, true); - if (fieldClass(t, field) != methodClass(t, context->method) - and classNeedsInit(t, fieldClass(t, field))) - { + if (classNeedsInit(t, fieldClass(t, field))) { PROTECT(t, field); c->call @@ -10440,7 +10436,7 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext, { PROTECT(t, method); - if (bootContext == 0) { + if (bootContext == 0 and methodFlags(t, method) & ACC_STATIC) { initClass(t, methodClass(t, method)); } diff --git a/src/interpret.cpp b/src/interpret.cpp index d222d4c1b5..01192867ee 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -791,8 +791,6 @@ interpret3(Thread* t, const int base) goto throw_; } - initClass(t, methodClass(t, frameMethod(t, frame))); - loop: instruction = codeBody(t, code, ip++); @@ -1907,8 +1905,6 @@ interpret3(Thread* t, const int base) PROTECT(t, method); PROTECT(t, class_); - initClass(t, class_); - code = findVirtualMethod(t, method, class_); goto invoke; } else { @@ -2909,7 +2905,9 @@ invoke(Thread* t, object method) class_ = methodClass(t, method); } - initClass(t, class_); + if (methodFlags(t, method) & ACC_STATIC) { + initClass(t, class_); + } object result = 0;