harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Xiao-Feng Li" <xiaofeng...@gmail.com>
Subject Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?
Date Mon, 05 Jan 2009 09:31:48 GMT
Btw, should we add this test case(s) into our smoke tests?

On Mon, Jan 5, 2009 at 5: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