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:06:29 GMT
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

Mime
View raw message