On Mon, Jan 5, 2009 at 7:52 PM, Pavel Pervov <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> wrote:
>>>
>>>> Please try with EUT3.5 before committing... :)
>>>>
>>>> Thanks,
>>>> xiaofeng
>>>>
>>>> On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <[email protected]>
>>>> 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 <[email protected]> wrote:
>>>> >
>>>> >>
>>>> >>
>>>> >> Xiao-Feng Li wrote:
>>>> >>
>>>> >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <[email protected]>
>>>> >>> wrote:
>>>> >>>
>>>> >>>> 2009/1/4 Nathan Beyer <[email protected]>
>>>> >>>>
>>>> >>>> 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
>>>> >> ch...@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