harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pavel Pervov" <pmcfi...@gmail.com>
Subject Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?
Date Fri, 09 Jan 2009 23:01:17 GMT
Xiao-Feng,

1. I don't see actually what needs clarification in this statement. :)
If the program needs to invoke a static method of a class, this class'
<clinit> must be invoked by the VM prior to invocation of that static
method.

2. That is simple conclusion from the specificaiton. Look at
initializtion sequence: first class is attempted to be initialized,
then if the class is already is being initialized th sequence checks
if this thread initializes the class and if it is it simply returns.
Our example clearly demonstrates that.

3. Class' static fields are all initialized to zero values on class
preparation. So, any uninitialized fields have the value of 0 (NULL).
Considering (2) we have uninitialized reference to array of Child, so
NPE is produced on invocation of 'return childCache[0];'.

Class initialization is indeed atomic in terms of multithreaded
invocation, but if initialization is requested recursively in the
scope of one thread, all attemps to reenter to <clinit> are aborted. I
do not have the specification at hand but, please, carefully read
through 11-step class initialization procedure to answer your
quesiton.

WBR,
    Pavel.

On Mon, Jan 5, 2009 at 4:04 PM, Xiao-Feng Li <xiaofeng.li@gmail.com> wrote:
> On Mon, Jan 5, 2009 at 7:52 PM, Pavel Pervov <pmcfirst@gmail.com> wrote:
>> Xiao-Feng,
>>
>> The spec does not prohibit (and thus just allows) methods (either
>> class or object) to be invoked when circular class initializaiton
>> occurs. The behaviour of such methods is as such that static and
>> object fields are initially initialized to default (zero) values and
>> then assigned other values during class initialization up to the point
>> when circular initialization occurs, and then class or object methods
>> execute without some fields be initialized to "correct" values. It is
>> rather programmatic error or expected program behaviour than some spec
>> inconsistency.
>
>
> Thanks, Pavel.
>
> I have some questions:
>
> 1. How do you explain this statement in VM spec?
> " A class or interface type T will be initialized immediately before
> one of the following occurs:
>    * T is a class and a static method of T is invoked."
>
> 2. As to the semantics you described above, is that defined in any
> spec or that's your understanding?
>
> 3. If to have a NULL value is expected for Child.ROOT in the test
> case, can we simply leave it to be NULL without having: "ROOT =
> Parent.createChild()"?
>
> If the program can not get the expected result with
> Parent.createChild(), I don't understand why we know a NULL is
> expected. :)  I would say it is a program bug because it behaves not
> as the program dictates.
>
> In my understanding, class initialization process is virtually atomic
> semantically. User should not see the intermediate values of a class
> under initialization...
>
> Thanks,
> xiaofeng
>
>> WBR,
>>    Pavel.
>>
>> On Mon, Jan 5, 2009 at 12:06 PM, Xiao-Feng Li <xiaofeng.li@gmail.com> wrote:
>>> Yes, we should commit if it passes the pre-commit tests and it makes
>>> EUT3.5 proceed.
>>>
>>> Btw, we still don't know the expected behavior when a static method is
>>> invoked before its class is initialized. It looks like all the JVMs
>>> just invoke it as usual.
>>>
>>> Thanks,
>>> xiaofeng
>>>
>>> On Mon, Jan 5, 2009 at 4:54 PM, chunrong lai <chunronglai@gmail.com> wrote:
>>>> Thanks.
>>>>
>>>> We still can not make EUT3.5 work. But we have different log/stackTrace this
>>>> time. I will post the new log to HARMONY-6062.
>>>>
>>>> I think the code needs to be committed, if it does not break the precommit
>>>> tests, since it fixes the issue in HARMONY-6020. Opinions?
>>>>
>>>> chunrong
>>>> Managed Runtime Technology Center, Intel
>>>> On Mon, Jan 5, 2009 at 4:48 PM, Xiao-Feng Li <xiaofeng.li@gmail.com>
wrote:
>>>>
>>>>> Please try with EUT3.5 before committing... :)
>>>>>
>>>>> Thanks,
>>>>> xiaofeng
>>>>>
>>>>> On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <chunronglai@gmail.com>
>>>>> wrote:
>>>>> > Thanks for the discussion.
>>>>> > Now it makes sense to me that the initializeClass from newarray
operation
>>>>> >
>>>>> > //OPCODE_ANEWARRAY
>>>>> > static void *rth_newarray_withresolve(Class_Handle klass, unsigned
>>>>> cp_idx,
>>>>> > unsigned arraySize) {
>>>>> >    ASSERT_THROW_AREA;
>>>>> >    //resolve and init object class
>>>>> >    Class* objClass = resolveClass(klass, cp_idx, false);
>>>>> >    initializeClass(objClass);    //should be removed
>>>>> >    assert(!objClass->is_primitive());
>>>>> >
>>>>> > can be removed.
>>>>> > After removing it I see the HARMONY-6020 and other test cases I
built can
>>>>> > pass with same behavior with RI. I am going to commit it. For you
have
>>>>> more
>>>>> > feedbacks please let me know.
>>>>> >
>>>>> > chunrong
>>>>> > Managed Runtime Technology Center, Intel
>>>>> > On Mon, Jan 5, 2009 at 2:19 PM, Regis <xu.regis@gmail.com>
wrote:
>>>>> >
>>>>> >>
>>>>> >>
>>>>> >> Xiao-Feng Li wrote:
>>>>> >>
>>>>> >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <rogers.email@gmail.com>
>>>>> >>> wrote:
>>>>> >>>
>>>>> >>>> 2009/1/4 Nathan Beyer <ndbeyer@apache.org>
>>>>> >>>>
>>>>> >>>> Could any of the IBM folks on the list get some advice
from some class
>>>>> >>>>> loader experts?
>>>>> >>>>>
>>>>> >>>>> -Nathan
>>>>> >>>>>
>>>>> >>>>>  Hi Nathan,
>>>>> >>>>
>>>>> >>>> from reading the description I can describe how Jikes
RVM avoids this
>>>>> >>>> problem (I'm not an IBM VME expert and I've not run
the test case to
>>>>> >>>> check
>>>>> >>>> that Jikes RVM passes it). In Jikes RVM we have two
variants of all
>>>>> >>>> calls,
>>>>> >>>> ones to unresolved methods and ones to resolved methods.
Unresolved
>>>>> calls
>>>>> >>>> are to classes whose initializer hasn't yet been run.
If two threads
>>>>> are
>>>>> >>>> calling a static method the first will resolve it and
in the process
>>>>> >>>> acquire
>>>>> >>>> a lock, the second thread must wait for the lock before
it can attempt
>>>>> to
>>>>> >>>> resolve the method (at which point it will discover
the method was
>>>>> >>>> resolved
>>>>> >>>> by the other thread and leave early). Checking for classes
being
>>>>> resolved
>>>>> >>>> litters all of the class loader code, and we're slightly
proactive in
>>>>> >>>> resolving in the case of reflected methods so that we
needn't check
>>>>> for
>>>>> >>>> resolution when performing reflected method invocation
(which is now
>>>>> >>>> pretty
>>>>> >>>> much unnecessary since [1] where we generate bytecodes
at runtime to
>>>>> >>>> perform
>>>>> >>>> reflection). An aside, I wrote a paper where I use the
class loader as
>>>>> a
>>>>> >>>> test case for optimizations based on stationary/immutable
fields
>>>>> >>>> specified
>>>>> >>>> via constraints [2], this work specialized the class
loader to handle
>>>>> the
>>>>> >>>> resolved case as a class is normally accessed when it
is resolved
>>>>> >>>> (figures
>>>>> >>>> in the paper).
>>>>> >>>>
>>>>> >>>
>>>>> >>> Thanks for the explanation.
>>>>> >>>
>>>>> >>> Let me try to explain the problem we are meeting:
>>>>> >>>
>>>>> >>> 1. A thread invokes a static method createChild of a class
Parent. It
>>>>> >>> causes class Parent be initialized.
>>>>> >>>
>>>>> >>> 2. In Parent's initialization, it creates an array of class
Child. It
>>>>> >>> leads to class Child be initialized.
>>>>> >>>
>>>>> >> if add following code to Child
>>>>> >>    static {
>>>>> >>        System.err.println("init Child");
>>>>> >>    }
>>>>> >> the output on RI is:
>>>>> >> null
>>>>> >> init Child
>>>>> >> null
>>>>> >>
>>>>> >> It seems create array of class Child doesn't lead to class Child
be
>>>>> >> initialized
>>>>> >>
>>>>> >> if change childCache from array to instance:
>>>>> >>
>>>>> >>    private static final Child childCache = new Child();
>>>>> >>
>>>>> >>    public static Child createChild(){
>>>>> >>        return childCache;
>>>>> >>    }
>>>>> >> the output on RI is:
>>>>> >> init Child
>>>>> >> Child@affc70
>>>>> >> null
>>>>> >>
>>>>> >> It seems when initialize Child, Parent.createChild() is called,
and read
>>>>> >> the value of childCache, it's not initialized, so null is returned
(it's
>>>>> >> already in initialize process, so just return null?).
>>>>> >>
>>>>> >>
>>>>> >>> 3. In Child's initialization, it invokes Parent.createChild()
to
>>>>> >>> initialize a static field ROOT. This leads to re-entrance
of Parent
>>>>> >>> initialization.
>>>>> >>>
>>>>> >>> 4. The thread finds Parent is under initialization by itself,
it quits
>>>>> >>> the initialization process and invokes Parent.createChild().
>>>>> >>>
>>>>> >>> 5. This invocation should not be permitted by the VM spec,
and we
>>>>> >>> don't know how to deal with it. It can't wait for the initialization
>>>>> >>> process finished, because it is in the path of the initialization.
It
>>>>> >>> has to do something to proceed with the initialization.
>>>>> >>>
>>>>> >>> Below is the code of the micro test. Chunrong, please correct
me if my
>>>>> >>> understanding is inaccurate.
>>>>> >>>
>>>>> >>> So my suggestion is to ignore the static method invocation
for the
>>>>> >>> class under initialization...
>>>>> >>>
>>>>> >>>
>>>>> >>> public class Main {
>>>>> >>>    public static void main(String[] args) {
>>>>> >>>        Child c = Parent.createChild();
>>>>> >>>        System.err.println(c);
>>>>> >>>        System.err.println(Child.ROOT);
>>>>> >>>    }
>>>>> >>> }
>>>>> >>>
>>>>> >>> class Parent {
>>>>> >>>    private static final Child[] childCache = new Child[5];
>>>>> >>>
>>>>> >>>    public static Child createChild(){
>>>>> >>>        return childCache[0];
>>>>> >>>    }
>>>>> >>> }
>>>>> >>>
>>>>> >>> class Child {
>>>>> >>>    public static final Child ROOT = Parent.createChild();
>>>>> >>> }
>>>>> >>>
>>>>> >>> Thanks,
>>>>> >>> xiaofeng
>>>>> >>>
>>>>> >>> Regards,
>>>>> >>>> Ian Rogers
>>>>> >>>>
>>>>> >>>> [1]
>>>>> >>>>
>>>>> >>>>
>>>>> http://icooolps.loria.fr/icooolps2008/Papers/ICOOOLPS2008_paper08_Rogers_Zhao_Watson_final.pdf
>>>>> >>>> [2] http://portal.acm.org/citation.cfm?id=1411746
>>>>> >>>>
>>>>> >>>>
>>>>> >>>
>>>>> >>>
>>>>> >>>
>>>>> >> --
>>>>> >> Best Regards,
>>>>> >> Regis.
>>>>> >>
>>>>> >
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>>  Managed Runtime Technology Center, Intel
>>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Xiao-Feng Li
>>> Managed Runtime Technology Center, Intel
>>>
>>
>
>
>
> --
> Managed Runtime Technology Center, Intel
>

Mime
View raw message