You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Xiao-Feng Li <xi...@gmail.com> on 2009/01/04 07:59:36 UTC

[class loading] what's the expected behavior when a static method is invoked before its class is initialized?

See https://issues.apache.org/jira/browse/HARMONY-6020

A static method is invoked when its owning class is under
initialization. Should we simply return without really executing any
code of the method?

In normal case, I think the calling thread will wait till the class
initialization is done, then continue the invocation. In this case,
the calling thread is the initializing thread, and this invocation
actually is part of the initialization sequence.

I personally would like to throw an exception since I regard the code
as problematic. But if RI can pass the test case, and more importantly
if EUT depends on it, we probably should find a solution.

Chunrong, do you know if EUT can pass (or continue) when this issue is resolved?

Thanks,
xiaofeng

On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org> wrote:
>
>    [ https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536 ]
>
> Xiao-Feng Li commented on HARMONY-6020:
> ---------------------------------------
>
> When we look at this class definition:
>
>  class Parent {
>    private static final Child[] childCache = new Child[5];
>
>    public static Child createChild(){
>        return childCache[0];
>    }
>  }
>
> It is clear that, the semantics expectation is, childCache should be assigned a value when class Parent is ready (i.e., initialized). And this value should be assigned to childCache before anybody can access any Parent's method, e.g., createChild(). This is the semantics expectation. I guess we need to ensure this semantics.
>
> Can we simply let this Child clinit() execute in this way: When it tries to call Parent.createChild() and finds Parent is under initialization, it simply returns null to ROOT without really invoking createChild().
>
> According to the JVM spec 2.17.4, it requires any static method invocation must happen after the class is "initialized." The problem is, how to deal with the situation when a static method is invoked when the owning class is under initialization.
>
> Thanks,
> xiaofeng
>
>
>> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>> -----------------------------------------------------------------
>>
>>                 Key: HARMONY-6020
>>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>>             Project: Harmony
>>          Issue Type: Bug
>>          Components: DRLVM
>>    Affects Versions: 5.0M8
>>         Environment: Win Vista 32-bit
>>            Reporter: Nathan Beyer
>>            Assignee: Chunrong Lai
>>         Attachments: cycle-project.zip
>>
>>
>> If two classes have a cyclical dependency, some unexpected results may occur, which are not seen on RI (Sun 6u10).
>
> --
> This message is automatically generated by JIRA.
> -
> You can reply to this email to add a comment to the issue online.
>
>



-- 
Xiao-Feng Li
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by chunrong lai <ch...@gmail.com>.
    Thanks.
    I wrote several simpler test cases (posted in HARMONY-6020) also with
the mentioned circularity. One with simple object access. The other with
array element access( the EUT35 source includes more complex source with
synchronized array element access, which does not incur in EUT33). Harmony
SVN HEAD can pass the object access case. With some quick enhancements for
array element loading the second got pass also.  Although I think that if we
ignore the synchronize section when the synchronized object is null in class
initialization we can get more progress in EUT35 enabling I think changing
the consuming place is not the correct way to do. I agree that we need a
better way to eliminate all of such non-inited value usages (if the
circularity happens).
   Unfortunately I am not aware how to exactly ignore the static method
invocation for the
class under initialization when the circularity happens. I thought several
implementation but they likely ignore some valid/needed initialization in
some other tests (no circularity happens actually).

Chunrong.
Managed Runtime Technology Center, Intel

On Mon, Jan 5, 2009 at 11:31 AM, Xiao-Feng Li <xi...@gmail.com> wrote:

> On Mon, Jan 5, 2009 at 1:20 AM, Nathan Beyer <nd...@apache.org> wrote:
> > On Sun, Jan 4, 2009 at 5:26 AM, Xiao-Feng Li <xi...@gmail.com>
> wrote:
> >> Thanks. Then it is an issue blocking EUT3.5.
> >>
> >> Can we simply do not invoke any static method of a class under
> initialization?
> >>
> >
> > I don't think that's going to work, as that would result in the same
> > error in Eclipse we see today, which is a NPE exception because a
> > field isn't populated. If the static method isn't invoked, then the
> > field will still be null and we'd still have the same error.
>
> As Chunrong said, it is ok to return NULL (i.e., it passes the test)
> when the static method of an initializing class is invoked? Need
> confirmation from Chunrong.
>
> In my understanding, an object (a class object here) is created with
> all the fields (including static data) initialized with default
> values. So if we simply skip all the static method invocations, we
> will read all the default values. Well yes, this is still incorrect
> according to the spec. But the spec doesn't permit the static method
> of an initializing method being called. I don't know if the code
> itself is compliant with the spec.
>
> Thanks,
> xiaofeng
>
> >> This needs to add a check in the prolog of the static method on the
> >> initialization status of the owning class. It should not incur serious
> >> performance issue since it is a memory load plus a check.
> >>
> >> Is this VM SPEC expected behavior?
> >
> > Could any of the IBM folks on the list get some advice from some class
> > loader experts?
> >
> > -Nathan
> >
> >>
> >> Thanks,
> >> xiaofeng
> >>
> >> On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com>
> wrote:
> >>> hi, xiaofeng:
> >>>    Observing similar class initializing trace in the logfile of EUT35,
> I
> >>> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
> >>>
> >>>    I did a quick test to modify some usings of the return non-inited
> value,
> >>> for example, processing of the bytecode of AALOAD. The test does make
> >>> Harmony pass some similar tests but still fail in other consuming
> cases. I
> >>> think that we just can not manually cover all of the consuming cases so
> we
> >>> need to fix the issue in the producing places. I am still trying this.
> >>> Lai, chunrong
> >>> Managed Runtime Technology Center, Intel
> >>> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com>
> wrote:
> >>>
> >>>> See https://issues.apache.org/jira/browse/HARMONY-6020
> >>>>
> >>>> A static method is invoked when its owning class is under
> >>>> initialization. Should we simply return without really executing any
> >>>> code of the method?
> >>>>
> >>>> In normal case, I think the calling thread will wait till the class
> >>>> initialization is done, then continue the invocation. In this case,
> >>>> the calling thread is the initializing thread, and this invocation
> >>>> actually is part of the initialization sequence.
> >>>>
> >>>> I personally would like to throw an exception since I regard the code
> >>>> as problematic. But if RI can pass the test case, and more importantly
> >>>> if EUT depends on it, we probably should find a solution.
> >>>>
> >>>> Chunrong, do you know if EUT can pass (or continue) when this issue is
> >>>> resolved?
> >>>>
> >>>> Thanks,
> >>>> xiaofeng
> >>>>
> >>>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
> >>>> wrote:
> >>>> >
> >>>> >    [
> >>>>
> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536
> ]
> >>>> >
> >>>> > Xiao-Feng Li commented on HARMONY-6020:
> >>>> > ---------------------------------------
> >>>> >
> >>>> > When we look at this class definition:
> >>>> >
> >>>> >  class Parent {
> >>>> >    private static final Child[] childCache = new Child[5];
> >>>> >
> >>>> >    public static Child createChild(){
> >>>> >        return childCache[0];
> >>>> >    }
> >>>> >  }
> >>>> >
> >>>> > It is clear that, the semantics expectation is, childCache should be
> >>>> assigned a value when class Parent is ready (i.e., initialized). And
> this
> >>>> value should be assigned to childCache before anybody can access any
> >>>> Parent's method, e.g., createChild(). This is the semantics
> expectation. I
> >>>> guess we need to ensure this semantics.
> >>>> >
> >>>> > Can we simply let this Child clinit() execute in this way: When it
> tries
> >>>> to call Parent.createChild() and finds Parent is under initialization,
> it
> >>>> simply returns null to ROOT without really invoking createChild().
> >>>> >
> >>>> > According to the JVM spec 2.17.4, it requires any static method
> >>>> invocation must happen after the class is "initialized." The problem
> is, how
> >>>> to deal with the situation when a static method is invoked when the
> owning
> >>>> class is under initialization.
> >>>> >
> >>>> > Thanks,
> >>>> > xiaofeng
> >>>> >
> >>>> >
> >>>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
> >>>> >> -----------------------------------------------------------------
> >>>> >>
> >>>> >>                 Key: HARMONY-6020
> >>>> >>                 URL:
> https://issues.apache.org/jira/browse/HARMONY-6020
> >>>> >>             Project: Harmony
> >>>> >>          Issue Type: Bug
> >>>> >>          Components: DRLVM
> >>>> >>    Affects Versions: 5.0M8
> >>>> >>         Environment: Win Vista 32-bit
> >>>> >>            Reporter: Nathan Beyer
> >>>> >>            Assignee: Chunrong Lai
> >>>> >>         Attachments: cycle-project.zip
> >>>> >>
> >>>> >>
> >>>> >> If two classes have a cyclical dependency, some unexpected results
> may
> >>>> occur, which are not seen on RI (Sun 6u10).
> >>>> >
> >>>> > --
> >>>> > This message is automatically generated by JIRA.
> >>>> > -
> >>>> > You can reply to this email to add a comment to the issue online.
> >>>> >
> >>>> >
> >>>>
> >>>>
> >>>>
> >>>> --
> >>>> Xiao-Feng Li
> >>>> Managed Runtime Technology Center, Intel
> >>>>
> >>>
> >>
> >>
> >>
> >> --
> >> Managed Runtime Technology Center, Intel
> >>
> >
>
>
>
> --
>  Managed Runtime Technology Center, Intel
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
On Mon, Jan 5, 2009 at 11:41 AM, Nathan Beyer <nd...@apache.org> wrote:
> On Sun, Jan 4, 2009 at 9:31 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>> On Mon, Jan 5, 2009 at 1:20 AM, Nathan Beyer <nd...@apache.org> wrote:
>>> On Sun, Jan 4, 2009 at 5:26 AM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>>> Thanks. Then it is an issue blocking EUT3.5.
>>>>
>>>> Can we simply do not invoke any static method of a class under initialization?
>>>>
>>>
>>> I don't think that's going to work, as that would result in the same
>>> error in Eclipse we see today, which is a NPE exception because a
>>> field isn't populated. If the static method isn't invoked, then the
>>> field will still be null and we'd still have the same error.
>>
>> As Chunrong said, it is ok to return NULL (i.e., it passes the test)
>> when the static method of an initializing class is invoked? Need
>> confirmation from Chunrong.
>>
>> In my understanding, an object (a class object here) is created with
>> all the fields (including static data) initialized with default
>> values. So if we simply skip all the static method invocations, we
>> will read all the default values. Well yes, this is still incorrect
>> according to the spec. But the spec doesn't permit the static method
>> of an initializing method being called. I don't know if the code
>> itself is compliant with the spec.
>
> I couldn't find anything in the spec to say it was not compliant. It
> just seems unexpected. I would say that it's undefined. It might be
> worth while to post a bug/enhancement to Eclipse to eliminate the
> circularity.

I found this in VM spec (2nd edition):
Section 2.17.4 "(Class) Initialization":

A class or interface type T will be initialized immediately before one
of the following occurs:

1. T is a class and an instance of T is created.
2. T is a class and a static method of T is invoked.
3. A nonconstant static field of T is used or assigned.


> However, even if it's not in the spec, all of the Eclipse standardized
> platforms (JREs) seem to accept it, so it would certainly be tough to
> not support it.

Agreed. We need find a solution.

> -Nathan
>
>>
>> Thanks,
>> xiaofeng
>>
>>>> This needs to add a check in the prolog of the static method on the
>>>> initialization status of the owning class. It should not incur serious
>>>> performance issue since it is a memory load plus a check.
>>>>
>>>> Is this VM SPEC expected behavior?
>>>
>>> Could any of the IBM folks on the list get some advice from some class
>>> loader experts?
>>>
>>> -Nathan
>>>
>>>>
>>>> Thanks,
>>>> xiaofeng
>>>>
>>>> On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com> wrote:
>>>>> hi, xiaofeng:
>>>>>    Observing similar class initializing trace in the logfile of EUT35, I
>>>>> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
>>>>>
>>>>>    I did a quick test to modify some usings of the return non-inited value,
>>>>> for example, processing of the bytecode of AALOAD. The test does make
>>>>> Harmony pass some similar tests but still fail in other consuming cases. I
>>>>> think that we just can not manually cover all of the consuming cases so we
>>>>> need to fix the issue in the producing places. I am still trying this.
>>>>> Lai, chunrong
>>>>> Managed Runtime Technology Center, Intel
>>>>> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>>>>
>>>>>> See https://issues.apache.org/jira/browse/HARMONY-6020
>>>>>>
>>>>>> A static method is invoked when its owning class is under
>>>>>> initialization. Should we simply return without really executing any
>>>>>> code of the method?
>>>>>>
>>>>>> In normal case, I think the calling thread will wait till the class
>>>>>> initialization is done, then continue the invocation. In this case,
>>>>>> the calling thread is the initializing thread, and this invocation
>>>>>> actually is part of the initialization sequence.
>>>>>>
>>>>>> I personally would like to throw an exception since I regard the code
>>>>>> as problematic. But if RI can pass the test case, and more importantly
>>>>>> if EUT depends on it, we probably should find a solution.
>>>>>>
>>>>>> Chunrong, do you know if EUT can pass (or continue) when this issue is
>>>>>> resolved?
>>>>>>
>>>>>> Thanks,
>>>>>> xiaofeng
>>>>>>
>>>>>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
>>>>>> wrote:
>>>>>> >
>>>>>> >    [
>>>>>> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
>>>>>> >
>>>>>> > Xiao-Feng Li commented on HARMONY-6020:
>>>>>> > ---------------------------------------
>>>>>> >
>>>>>> > When we look at this class definition:
>>>>>> >
>>>>>> >  class Parent {
>>>>>> >    private static final Child[] childCache = new Child[5];
>>>>>> >
>>>>>> >    public static Child createChild(){
>>>>>> >        return childCache[0];
>>>>>> >    }
>>>>>> >  }
>>>>>> >
>>>>>> > It is clear that, the semantics expectation is, childCache should be
>>>>>> assigned a value when class Parent is ready (i.e., initialized). And this
>>>>>> value should be assigned to childCache before anybody can access any
>>>>>> Parent's method, e.g., createChild(). This is the semantics expectation. I
>>>>>> guess we need to ensure this semantics.
>>>>>> >
>>>>>> > Can we simply let this Child clinit() execute in this way: When it tries
>>>>>> to call Parent.createChild() and finds Parent is under initialization, it
>>>>>> simply returns null to ROOT without really invoking createChild().
>>>>>> >
>>>>>> > According to the JVM spec 2.17.4, it requires any static method
>>>>>> invocation must happen after the class is "initialized." The problem is, how
>>>>>> to deal with the situation when a static method is invoked when the owning
>>>>>> class is under initialization.
>>>>>> >
>>>>>> > Thanks,
>>>>>> > xiaofeng
>>>>>> >
>>>>>> >
>>>>>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>>>>>> >> -----------------------------------------------------------------
>>>>>> >>
>>>>>> >>                 Key: HARMONY-6020
>>>>>> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>>>>>> >>             Project: Harmony
>>>>>> >>          Issue Type: Bug
>>>>>> >>          Components: DRLVM
>>>>>> >>    Affects Versions: 5.0M8
>>>>>> >>         Environment: Win Vista 32-bit
>>>>>> >>            Reporter: Nathan Beyer
>>>>>> >>            Assignee: Chunrong Lai
>>>>>> >>         Attachments: cycle-project.zip
>>>>>> >>
>>>>>> >>
>>>>>> >> If two classes have a cyclical dependency, some unexpected results may
>>>>>> occur, which are not seen on RI (Sun 6u10).
>>>>>> >
>>>>>> > --
>>>>>> > This message is automatically generated by JIRA.
>>>>>> > -
>>>>>> > You can reply to this email to add a comment to the issue online.
>>>>>> >
>>>>>> >
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Xiao-Feng Li
>>>>>> Managed Runtime Technology Center, Intel
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Managed Runtime Technology Center, Intel
>>>>
>>>
>>
>>
>>
>> --
>> Managed Runtime Technology Center, Intel
>>
>



-- 
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Nathan Beyer <nd...@apache.org>.
On Sun, Jan 4, 2009 at 9:31 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
> On Mon, Jan 5, 2009 at 1:20 AM, Nathan Beyer <nd...@apache.org> wrote:
>> On Sun, Jan 4, 2009 at 5:26 AM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>> Thanks. Then it is an issue blocking EUT3.5.
>>>
>>> Can we simply do not invoke any static method of a class under initialization?
>>>
>>
>> I don't think that's going to work, as that would result in the same
>> error in Eclipse we see today, which is a NPE exception because a
>> field isn't populated. If the static method isn't invoked, then the
>> field will still be null and we'd still have the same error.
>
> As Chunrong said, it is ok to return NULL (i.e., it passes the test)
> when the static method of an initializing class is invoked? Need
> confirmation from Chunrong.
>
> In my understanding, an object (a class object here) is created with
> all the fields (including static data) initialized with default
> values. So if we simply skip all the static method invocations, we
> will read all the default values. Well yes, this is still incorrect
> according to the spec. But the spec doesn't permit the static method
> of an initializing method being called. I don't know if the code
> itself is compliant with the spec.

I couldn't find anything in the spec to say it was not compliant. It
just seems unexpected. I would say that it's undefined. It might be
worth while to post a bug/enhancement to Eclipse to eliminate the
circularity.

However, even if it's not in the spec, all of the Eclipse standardized
platforms (JREs) seem to accept it, so it would certainly be tough to
not support it.

-Nathan

>
> Thanks,
> xiaofeng
>
>>> This needs to add a check in the prolog of the static method on the
>>> initialization status of the owning class. It should not incur serious
>>> performance issue since it is a memory load plus a check.
>>>
>>> Is this VM SPEC expected behavior?
>>
>> Could any of the IBM folks on the list get some advice from some class
>> loader experts?
>>
>> -Nathan
>>
>>>
>>> Thanks,
>>> xiaofeng
>>>
>>> On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com> wrote:
>>>> hi, xiaofeng:
>>>>    Observing similar class initializing trace in the logfile of EUT35, I
>>>> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
>>>>
>>>>    I did a quick test to modify some usings of the return non-inited value,
>>>> for example, processing of the bytecode of AALOAD. The test does make
>>>> Harmony pass some similar tests but still fail in other consuming cases. I
>>>> think that we just can not manually cover all of the consuming cases so we
>>>> need to fix the issue in the producing places. I am still trying this.
>>>> Lai, chunrong
>>>> Managed Runtime Technology Center, Intel
>>>> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>>>
>>>>> See https://issues.apache.org/jira/browse/HARMONY-6020
>>>>>
>>>>> A static method is invoked when its owning class is under
>>>>> initialization. Should we simply return without really executing any
>>>>> code of the method?
>>>>>
>>>>> In normal case, I think the calling thread will wait till the class
>>>>> initialization is done, then continue the invocation. In this case,
>>>>> the calling thread is the initializing thread, and this invocation
>>>>> actually is part of the initialization sequence.
>>>>>
>>>>> I personally would like to throw an exception since I regard the code
>>>>> as problematic. But if RI can pass the test case, and more importantly
>>>>> if EUT depends on it, we probably should find a solution.
>>>>>
>>>>> Chunrong, do you know if EUT can pass (or continue) when this issue is
>>>>> resolved?
>>>>>
>>>>> Thanks,
>>>>> xiaofeng
>>>>>
>>>>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
>>>>> wrote:
>>>>> >
>>>>> >    [
>>>>> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
>>>>> >
>>>>> > Xiao-Feng Li commented on HARMONY-6020:
>>>>> > ---------------------------------------
>>>>> >
>>>>> > When we look at this class definition:
>>>>> >
>>>>> >  class Parent {
>>>>> >    private static final Child[] childCache = new Child[5];
>>>>> >
>>>>> >    public static Child createChild(){
>>>>> >        return childCache[0];
>>>>> >    }
>>>>> >  }
>>>>> >
>>>>> > It is clear that, the semantics expectation is, childCache should be
>>>>> assigned a value when class Parent is ready (i.e., initialized). And this
>>>>> value should be assigned to childCache before anybody can access any
>>>>> Parent's method, e.g., createChild(). This is the semantics expectation. I
>>>>> guess we need to ensure this semantics.
>>>>> >
>>>>> > Can we simply let this Child clinit() execute in this way: When it tries
>>>>> to call Parent.createChild() and finds Parent is under initialization, it
>>>>> simply returns null to ROOT without really invoking createChild().
>>>>> >
>>>>> > According to the JVM spec 2.17.4, it requires any static method
>>>>> invocation must happen after the class is "initialized." The problem is, how
>>>>> to deal with the situation when a static method is invoked when the owning
>>>>> class is under initialization.
>>>>> >
>>>>> > Thanks,
>>>>> > xiaofeng
>>>>> >
>>>>> >
>>>>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>>>>> >> -----------------------------------------------------------------
>>>>> >>
>>>>> >>                 Key: HARMONY-6020
>>>>> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>>>>> >>             Project: Harmony
>>>>> >>          Issue Type: Bug
>>>>> >>          Components: DRLVM
>>>>> >>    Affects Versions: 5.0M8
>>>>> >>         Environment: Win Vista 32-bit
>>>>> >>            Reporter: Nathan Beyer
>>>>> >>            Assignee: Chunrong Lai
>>>>> >>         Attachments: cycle-project.zip
>>>>> >>
>>>>> >>
>>>>> >> If two classes have a cyclical dependency, some unexpected results may
>>>>> occur, which are not seen on RI (Sun 6u10).
>>>>> >
>>>>> > --
>>>>> > This message is automatically generated by JIRA.
>>>>> > -
>>>>> > You can reply to this email to add a comment to the issue online.
>>>>> >
>>>>> >
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Xiao-Feng Li
>>>>> Managed Runtime Technology Center, Intel
>>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Managed Runtime Technology Center, Intel
>>>
>>
>
>
>
> --
> Managed Runtime Technology Center, Intel
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
On Mon, Jan 5, 2009 at 1:20 AM, Nathan Beyer <nd...@apache.org> wrote:
> On Sun, Jan 4, 2009 at 5:26 AM, Xiao-Feng Li <xi...@gmail.com> wrote:
>> Thanks. Then it is an issue blocking EUT3.5.
>>
>> Can we simply do not invoke any static method of a class under initialization?
>>
>
> I don't think that's going to work, as that would result in the same
> error in Eclipse we see today, which is a NPE exception because a
> field isn't populated. If the static method isn't invoked, then the
> field will still be null and we'd still have the same error.

As Chunrong said, it is ok to return NULL (i.e., it passes the test)
when the static method of an initializing class is invoked? Need
confirmation from Chunrong.

In my understanding, an object (a class object here) is created with
all the fields (including static data) initialized with default
values. So if we simply skip all the static method invocations, we
will read all the default values. Well yes, this is still incorrect
according to the spec. But the spec doesn't permit the static method
of an initializing method being called. I don't know if the code
itself is compliant with the spec.

Thanks,
xiaofeng

>> This needs to add a check in the prolog of the static method on the
>> initialization status of the owning class. It should not incur serious
>> performance issue since it is a memory load plus a check.
>>
>> Is this VM SPEC expected behavior?
>
> Could any of the IBM folks on the list get some advice from some class
> loader experts?
>
> -Nathan
>
>>
>> Thanks,
>> xiaofeng
>>
>> On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com> wrote:
>>> hi, xiaofeng:
>>>    Observing similar class initializing trace in the logfile of EUT35, I
>>> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
>>>
>>>    I did a quick test to modify some usings of the return non-inited value,
>>> for example, processing of the bytecode of AALOAD. The test does make
>>> Harmony pass some similar tests but still fail in other consuming cases. I
>>> think that we just can not manually cover all of the consuming cases so we
>>> need to fix the issue in the producing places. I am still trying this.
>>> Lai, chunrong
>>> Managed Runtime Technology Center, Intel
>>> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>>
>>>> See https://issues.apache.org/jira/browse/HARMONY-6020
>>>>
>>>> A static method is invoked when its owning class is under
>>>> initialization. Should we simply return without really executing any
>>>> code of the method?
>>>>
>>>> In normal case, I think the calling thread will wait till the class
>>>> initialization is done, then continue the invocation. In this case,
>>>> the calling thread is the initializing thread, and this invocation
>>>> actually is part of the initialization sequence.
>>>>
>>>> I personally would like to throw an exception since I regard the code
>>>> as problematic. But if RI can pass the test case, and more importantly
>>>> if EUT depends on it, we probably should find a solution.
>>>>
>>>> Chunrong, do you know if EUT can pass (or continue) when this issue is
>>>> resolved?
>>>>
>>>> Thanks,
>>>> xiaofeng
>>>>
>>>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
>>>> wrote:
>>>> >
>>>> >    [
>>>> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
>>>> >
>>>> > Xiao-Feng Li commented on HARMONY-6020:
>>>> > ---------------------------------------
>>>> >
>>>> > When we look at this class definition:
>>>> >
>>>> >  class Parent {
>>>> >    private static final Child[] childCache = new Child[5];
>>>> >
>>>> >    public static Child createChild(){
>>>> >        return childCache[0];
>>>> >    }
>>>> >  }
>>>> >
>>>> > It is clear that, the semantics expectation is, childCache should be
>>>> assigned a value when class Parent is ready (i.e., initialized). And this
>>>> value should be assigned to childCache before anybody can access any
>>>> Parent's method, e.g., createChild(). This is the semantics expectation. I
>>>> guess we need to ensure this semantics.
>>>> >
>>>> > Can we simply let this Child clinit() execute in this way: When it tries
>>>> to call Parent.createChild() and finds Parent is under initialization, it
>>>> simply returns null to ROOT without really invoking createChild().
>>>> >
>>>> > According to the JVM spec 2.17.4, it requires any static method
>>>> invocation must happen after the class is "initialized." The problem is, how
>>>> to deal with the situation when a static method is invoked when the owning
>>>> class is under initialization.
>>>> >
>>>> > Thanks,
>>>> > xiaofeng
>>>> >
>>>> >
>>>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>>>> >> -----------------------------------------------------------------
>>>> >>
>>>> >>                 Key: HARMONY-6020
>>>> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>>>> >>             Project: Harmony
>>>> >>          Issue Type: Bug
>>>> >>          Components: DRLVM
>>>> >>    Affects Versions: 5.0M8
>>>> >>         Environment: Win Vista 32-bit
>>>> >>            Reporter: Nathan Beyer
>>>> >>            Assignee: Chunrong Lai
>>>> >>         Attachments: cycle-project.zip
>>>> >>
>>>> >>
>>>> >> If two classes have a cyclical dependency, some unexpected results may
>>>> occur, which are not seen on RI (Sun 6u10).
>>>> >
>>>> > --
>>>> > This message is automatically generated by JIRA.
>>>> > -
>>>> > You can reply to this email to add a comment to the issue online.
>>>> >
>>>> >
>>>>
>>>>
>>>>
>>>> --
>>>> Xiao-Feng Li
>>>> Managed Runtime Technology Center, Intel
>>>>
>>>
>>
>>
>>
>> --
>> Managed Runtime Technology Center, Intel
>>
>



-- 
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
Btw, should we add this test case(s) into our smoke tests?

On Mon, Jan 5, 2009 at 5:06 PM, Xiao-Feng Li <xi...@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 <ch...@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 <xi...@gmail.com> wrote:
>>
>>> Please try with EUT3.5 before committing... :)
>>>
>>> Thanks,
>>> xiaofeng
>>>
>>> On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <ch...@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...@gmail.com> wrote:
>>> >
>>> >>
>>> >>
>>> >> Xiao-Feng Li wrote:
>>> >>
>>> >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
>>> >>> wrote:
>>> >>>
>>> >>>> 2009/1/4 Nathan Beyer <nd...@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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Pavel Pervov <pm...@gmail.com>.
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.

WBR,
    Pavel.

On Mon, Jan 5, 2009 at 12:06 PM, Xiao-Feng Li <xi...@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 <ch...@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 <xi...@gmail.com> wrote:
>>
>>> Please try with EUT3.5 before committing... :)
>>>
>>> Thanks,
>>> xiaofeng
>>>
>>> On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <ch...@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...@gmail.com> wrote:
>>> >
>>> >>
>>> >>
>>> >> Xiao-Feng Li wrote:
>>> >>
>>> >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
>>> >>> wrote:
>>> >>>
>>> >>>> 2009/1/4 Nathan Beyer <nd...@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
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
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 <ch...@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 <xi...@gmail.com> wrote:
>
>> Please try with EUT3.5 before committing... :)
>>
>> Thanks,
>> xiaofeng
>>
>> On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <ch...@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...@gmail.com> wrote:
>> >
>> >>
>> >>
>> >> Xiao-Feng Li wrote:
>> >>
>> >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
>> >>> wrote:
>> >>>
>> >>>> 2009/1/4 Nathan Beyer <nd...@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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by chunrong lai <ch...@gmail.com>.
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 <xi...@gmail.com> wrote:

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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
Please try with EUT3.5 before committing... :)

Thanks,
xiaofeng

On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <ch...@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...@gmail.com> wrote:
>
>>
>>
>> Xiao-Feng Li wrote:
>>
>>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
>>> wrote:
>>>
>>>> 2009/1/4 Nathan Beyer <nd...@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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by chunrong lai <ch...@gmail.com>.
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...@gmail.com> wrote:

>
>
> Xiao-Feng Li wrote:
>
>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
>> wrote:
>>
>>> 2009/1/4 Nathan Beyer <nd...@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.
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Regis <xu...@gmail.com>.

Xiao-Feng Li wrote:
> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com> wrote:
>> 2009/1/4 Nathan Beyer <nd...@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.

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
On Mon, Jan 5, 2009 at 1:10 PM, Nathan Beyer <nd...@apache.org> wrote:
> On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com> wrote:
>>> 2009/1/4 Nathan Beyer <nd...@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.
>
> Is this the problem? The initialization bit in the spec only says that
> a non-constant field [1] that references a type T, should cause the
> initialization of type T. This brings up two questions for me. One,
> does that implicitly include arrays of a type T? Two, why is Child
> getting loaded in the example, since it is a constant (static and
> final)?

For your questions:
1. It has two operations: a) to create an array of Child, and b) to
assign it to an array reference. Both a) and b) might not require the
class initialization. It can be verified by using:

   private static final Object childCache = new Child[5];


2. This is not a constant, because it is not compile-time value.

>
> The second bit seems to be violating the spec. Am I reading it wrong?
>
> [1] http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075
>
>>
>> 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.
>
> Since you put "should not" in this statement, I presume this is just
> an opinion and their isn't any source that supports this, correct?

As the spec says:

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.


Thanks,
xiaofeng

> -Nathan
>
>>
>> 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
>>>
>>
>>
>>
>> --
>> Managed Runtime Technology Center, Intel
>>
>



-- 
Xiao-Feng Li
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Jack Cai <gr...@gmail.com>.
En, so lazy load for the static field does not work because it breaks the
semantics. But Nathan gave a good point: a reference of Array T does not
require the initialization of type T. So if the array version of the test
case is run, the type Child shall not get initialized until Child.ROOT is
referenced.

-Jack

2009/1/5 chunrong lai <ch...@gmail.com>

> It is also noted that the simple test case
>
> public class Main {
>    public static void main(String[] args) {
>        Child c = Parent.createChild();
>        System.err.println(c);
>         System.err.println(Child.ROOT); //actually return null
>    }
> }
> class Parent {
>    private static final Child childCache = new Child();
>
>    public static Child createChild(){
>        return childCache;
>     }
> }
> class Child {
>    public static final Child ROOT = Parent.createChild();
> }
>
> actually print null for Child.ROOT , both in RI or Harmony HEAD.
> The return value is different with my original semantics understanding.
>
> I guess that lazy load will assign a non-null for Child.ROOT (in
> semantics),
> is it correct?
>
> On Mon, Jan 5, 2009 at 1:58 PM, Jack Cai <gr...@gmail.com> wrote:
>
> > I guess we can use lazy load to eliminate the problem. In Chunrong's test
> > case, the assignation of Child.ROOT field can be held until its value is
> > used (like in the line "System.err.println(Child.ROOT);"). I'm not sure
> how
> > the SPEC says about lazy load, but lazy load just works here.
> >
> > -Jack
> >
> > 2009/1/5 Nathan Beyer <nd...@apache.org>
> >
> > > On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xi...@gmail.com>
> > > wrote:
> > > > On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
> > > wrote:
> > > >> 2009/1/4 Nathan Beyer <nd...@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.
> > >
> > > Is this the problem? The initialization bit in the spec only says that
> > > a non-constant field [1] that references a type T, should cause the
> > > initialization of type T. This brings up two questions for me. One,
> > > does that implicitly include arrays of a type T? Two, why is Child
> > > getting loaded in the example, since it is a constant (static and
> > > final)?
> > >
> > > The second bit seems to be violating the spec. Am I reading it wrong?
> > >
> > > [1]
> > >
> >
> http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075
> > >
> > > >
> > > > 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.
> > >
> > > Since you put "should not" in this statement, I presume this is just
> > > an opinion and their isn't any source that supports this, correct?
> > >
> > > -Nathan
> > >
> > > >
> > > > 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
> > > >>
> > > >
> > > >
> > > >
> > > > --
> > > > Managed Runtime Technology Center, Intel
> > > >
> > >
> >
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by chunrong lai <ch...@gmail.com>.
It is also noted that the simple test case

public class Main {
    public static void main(String[] args) {
        Child c = Parent.createChild();
        System.err.println(c);
        System.err.println(Child.ROOT); //actually return null
    }
}
class Parent {
    private static final Child childCache = new Child();

    public static Child createChild(){
        return childCache;
    }
}
class Child {
    public static final Child ROOT = Parent.createChild();
}

actually print null for Child.ROOT , both in RI or Harmony HEAD.
The return value is different with my original semantics understanding.

I guess that lazy load will assign a non-null for Child.ROOT (in semantics),
is it correct?

On Mon, Jan 5, 2009 at 1:58 PM, Jack Cai <gr...@gmail.com> wrote:

> I guess we can use lazy load to eliminate the problem. In Chunrong's test
> case, the assignation of Child.ROOT field can be held until its value is
> used (like in the line "System.err.println(Child.ROOT);"). I'm not sure how
> the SPEC says about lazy load, but lazy load just works here.
>
> -Jack
>
> 2009/1/5 Nathan Beyer <nd...@apache.org>
>
> > On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xi...@gmail.com>
> > wrote:
> > > On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
> > wrote:
> > >> 2009/1/4 Nathan Beyer <nd...@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.
> >
> > Is this the problem? The initialization bit in the spec only says that
> > a non-constant field [1] that references a type T, should cause the
> > initialization of type T. This brings up two questions for me. One,
> > does that implicitly include arrays of a type T? Two, why is Child
> > getting loaded in the example, since it is a constant (static and
> > final)?
> >
> > The second bit seems to be violating the spec. Am I reading it wrong?
> >
> > [1]
> >
> http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075
> >
> > >
> > > 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.
> >
> > Since you put "should not" in this statement, I presume this is just
> > an opinion and their isn't any source that supports this, correct?
> >
> > -Nathan
> >
> > >
> > > 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
> > >>
> > >
> > >
> > >
> > > --
> > > Managed Runtime Technology Center, Intel
> > >
> >
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Jack Cai <gr...@gmail.com>.
I guess we can use lazy load to eliminate the problem. In Chunrong's test
case, the assignation of Child.ROOT field can be held until its value is
used (like in the line "System.err.println(Child.ROOT);"). I'm not sure how
the SPEC says about lazy load, but lazy load just works here.

-Jack

2009/1/5 Nathan Beyer <nd...@apache.org>

> On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xi...@gmail.com>
> wrote:
> > On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com>
> wrote:
> >> 2009/1/4 Nathan Beyer <nd...@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.
>
> Is this the problem? The initialization bit in the spec only says that
> a non-constant field [1] that references a type T, should cause the
> initialization of type T. This brings up two questions for me. One,
> does that implicitly include arrays of a type T? Two, why is Child
> getting loaded in the example, since it is a constant (static and
> final)?
>
> The second bit seems to be violating the spec. Am I reading it wrong?
>
> [1]
> http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075
>
> >
> > 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.
>
> Since you put "should not" in this statement, I presume this is just
> an opinion and their isn't any source that supports this, correct?
>
> -Nathan
>
> >
> > 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
> >>
> >
> >
> >
> > --
> > Managed Runtime Technology Center, Intel
> >
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Nathan Beyer <nd...@apache.org>.
On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com> wrote:
>> 2009/1/4 Nathan Beyer <nd...@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.

Is this the problem? The initialization bit in the spec only says that
a non-constant field [1] that references a type T, should cause the
initialization of type T. This brings up two questions for me. One,
does that implicitly include arrays of a type T? Two, why is Child
getting loaded in the example, since it is a constant (static and
final)?

The second bit seems to be violating the spec. Am I reading it wrong?

[1] http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075

>
> 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.

Since you put "should not" in this statement, I presume this is just
an opinion and their isn't any source that supports this, correct?

-Nathan

>
> 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
>>
>
>
>
> --
> Managed Runtime Technology Center, Intel
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <ro...@gmail.com> wrote:
> 2009/1/4 Nathan Beyer <nd...@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.

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
>



-- 
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Ian Rogers <ro...@gmail.com>.
2009/1/4 Nathan Beyer <nd...@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).

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

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Nathan Beyer <nd...@apache.org>.
On Sun, Jan 4, 2009 at 5:26 AM, Xiao-Feng Li <xi...@gmail.com> wrote:
> Thanks. Then it is an issue blocking EUT3.5.
>
> Can we simply do not invoke any static method of a class under initialization?
>

I don't think that's going to work, as that would result in the same
error in Eclipse we see today, which is a NPE exception because a
field isn't populated. If the static method isn't invoked, then the
field will still be null and we'd still have the same error.

> This needs to add a check in the prolog of the static method on the
> initialization status of the owning class. It should not incur serious
> performance issue since it is a memory load plus a check.
>
> Is this VM SPEC expected behavior?

Could any of the IBM folks on the list get some advice from some class
loader experts?

-Nathan

>
> Thanks,
> xiaofeng
>
> On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com> wrote:
>> hi, xiaofeng:
>>    Observing similar class initializing trace in the logfile of EUT35, I
>> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
>>
>>    I did a quick test to modify some usings of the return non-inited value,
>> for example, processing of the bytecode of AALOAD. The test does make
>> Harmony pass some similar tests but still fail in other consuming cases. I
>> think that we just can not manually cover all of the consuming cases so we
>> need to fix the issue in the producing places. I am still trying this.
>> Lai, chunrong
>> Managed Runtime Technology Center, Intel
>> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>>
>>> See https://issues.apache.org/jira/browse/HARMONY-6020
>>>
>>> A static method is invoked when its owning class is under
>>> initialization. Should we simply return without really executing any
>>> code of the method?
>>>
>>> In normal case, I think the calling thread will wait till the class
>>> initialization is done, then continue the invocation. In this case,
>>> the calling thread is the initializing thread, and this invocation
>>> actually is part of the initialization sequence.
>>>
>>> I personally would like to throw an exception since I regard the code
>>> as problematic. But if RI can pass the test case, and more importantly
>>> if EUT depends on it, we probably should find a solution.
>>>
>>> Chunrong, do you know if EUT can pass (or continue) when this issue is
>>> resolved?
>>>
>>> Thanks,
>>> xiaofeng
>>>
>>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
>>> wrote:
>>> >
>>> >    [
>>> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
>>> >
>>> > Xiao-Feng Li commented on HARMONY-6020:
>>> > ---------------------------------------
>>> >
>>> > When we look at this class definition:
>>> >
>>> >  class Parent {
>>> >    private static final Child[] childCache = new Child[5];
>>> >
>>> >    public static Child createChild(){
>>> >        return childCache[0];
>>> >    }
>>> >  }
>>> >
>>> > It is clear that, the semantics expectation is, childCache should be
>>> assigned a value when class Parent is ready (i.e., initialized). And this
>>> value should be assigned to childCache before anybody can access any
>>> Parent's method, e.g., createChild(). This is the semantics expectation. I
>>> guess we need to ensure this semantics.
>>> >
>>> > Can we simply let this Child clinit() execute in this way: When it tries
>>> to call Parent.createChild() and finds Parent is under initialization, it
>>> simply returns null to ROOT without really invoking createChild().
>>> >
>>> > According to the JVM spec 2.17.4, it requires any static method
>>> invocation must happen after the class is "initialized." The problem is, how
>>> to deal with the situation when a static method is invoked when the owning
>>> class is under initialization.
>>> >
>>> > Thanks,
>>> > xiaofeng
>>> >
>>> >
>>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>>> >> -----------------------------------------------------------------
>>> >>
>>> >>                 Key: HARMONY-6020
>>> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>>> >>             Project: Harmony
>>> >>          Issue Type: Bug
>>> >>          Components: DRLVM
>>> >>    Affects Versions: 5.0M8
>>> >>         Environment: Win Vista 32-bit
>>> >>            Reporter: Nathan Beyer
>>> >>            Assignee: Chunrong Lai
>>> >>         Attachments: cycle-project.zip
>>> >>
>>> >>
>>> >> If two classes have a cyclical dependency, some unexpected results may
>>> occur, which are not seen on RI (Sun 6u10).
>>> >
>>> > --
>>> > This message is automatically generated by JIRA.
>>> > -
>>> > You can reply to this email to add a comment to the issue online.
>>> >
>>> >
>>>
>>>
>>>
>>> --
>>> Xiao-Feng Li
>>> Managed Runtime Technology Center, Intel
>>>
>>
>
>
>
> --
> Managed Runtime Technology Center, Intel
>

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by Xiao-Feng Li <xi...@gmail.com>.
Thanks. Then it is an issue blocking EUT3.5.

Can we simply do not invoke any static method of a class under initialization?

This needs to add a check in the prolog of the static method on the
initialization status of the owning class. It should not incur serious
performance issue since it is a memory load plus a check.

Is this VM SPEC expected behavior?

Thanks,
xiaofeng

On Sun, Jan 4, 2009 at 6:29 PM, chunrong lai <ch...@gmail.com> wrote:
> hi, xiaofeng:
>    Observing similar class initializing trace in the logfile of EUT35, I
> see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.
>
>    I did a quick test to modify some usings of the return non-inited value,
> for example, processing of the bytecode of AALOAD. The test does make
> Harmony pass some similar tests but still fail in other consuming cases. I
> think that we just can not manually cover all of the consuming cases so we
> need to fix the issue in the producing places. I am still trying this.
> Lai, chunrong
> Managed Runtime Technology Center, Intel
> On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:
>
>> See https://issues.apache.org/jira/browse/HARMONY-6020
>>
>> A static method is invoked when its owning class is under
>> initialization. Should we simply return without really executing any
>> code of the method?
>>
>> In normal case, I think the calling thread will wait till the class
>> initialization is done, then continue the invocation. In this case,
>> the calling thread is the initializing thread, and this invocation
>> actually is part of the initialization sequence.
>>
>> I personally would like to throw an exception since I regard the code
>> as problematic. But if RI can pass the test case, and more importantly
>> if EUT depends on it, we probably should find a solution.
>>
>> Chunrong, do you know if EUT can pass (or continue) when this issue is
>> resolved?
>>
>> Thanks,
>> xiaofeng
>>
>> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
>> wrote:
>> >
>> >    [
>> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
>> >
>> > Xiao-Feng Li commented on HARMONY-6020:
>> > ---------------------------------------
>> >
>> > When we look at this class definition:
>> >
>> >  class Parent {
>> >    private static final Child[] childCache = new Child[5];
>> >
>> >    public static Child createChild(){
>> >        return childCache[0];
>> >    }
>> >  }
>> >
>> > It is clear that, the semantics expectation is, childCache should be
>> assigned a value when class Parent is ready (i.e., initialized). And this
>> value should be assigned to childCache before anybody can access any
>> Parent's method, e.g., createChild(). This is the semantics expectation. I
>> guess we need to ensure this semantics.
>> >
>> > Can we simply let this Child clinit() execute in this way: When it tries
>> to call Parent.createChild() and finds Parent is under initialization, it
>> simply returns null to ROOT without really invoking createChild().
>> >
>> > According to the JVM spec 2.17.4, it requires any static method
>> invocation must happen after the class is "initialized." The problem is, how
>> to deal with the situation when a static method is invoked when the owning
>> class is under initialization.
>> >
>> > Thanks,
>> > xiaofeng
>> >
>> >
>> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
>> >> -----------------------------------------------------------------
>> >>
>> >>                 Key: HARMONY-6020
>> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
>> >>             Project: Harmony
>> >>          Issue Type: Bug
>> >>          Components: DRLVM
>> >>    Affects Versions: 5.0M8
>> >>         Environment: Win Vista 32-bit
>> >>            Reporter: Nathan Beyer
>> >>            Assignee: Chunrong Lai
>> >>         Attachments: cycle-project.zip
>> >>
>> >>
>> >> If two classes have a cyclical dependency, some unexpected results may
>> occur, which are not seen on RI (Sun 6u10).
>> >
>> > --
>> > This message is automatically generated by JIRA.
>> > -
>> > You can reply to this email to add a comment to the issue online.
>> >
>> >
>>
>>
>>
>> --
>> Xiao-Feng Li
>> Managed Runtime Technology Center, Intel
>>
>



-- 
Managed Runtime Technology Center, Intel

Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?

Posted by chunrong lai <ch...@gmail.com>.
hi, xiaofeng:
    Observing similar class initializing trace in the logfile of EUT35, I
see HARMONY can not pass EUT35 if we do not fix HARMONY-6020.

    I did a quick test to modify some usings of the return non-inited value,
for example, processing of the bytecode of AALOAD. The test does make
Harmony pass some similar tests but still fail in other consuming cases. I
think that we just can not manually cover all of the consuming cases so we
need to fix the issue in the producing places. I am still trying this.
Lai, chunrong
Managed Runtime Technology Center, Intel
On Sun, Jan 4, 2009 at 2:59 PM, Xiao-Feng Li <xi...@gmail.com> wrote:

> See https://issues.apache.org/jira/browse/HARMONY-6020
>
> A static method is invoked when its owning class is under
> initialization. Should we simply return without really executing any
> code of the method?
>
> In normal case, I think the calling thread will wait till the class
> initialization is done, then continue the invocation. In this case,
> the calling thread is the initializing thread, and this invocation
> actually is part of the initialization sequence.
>
> I personally would like to throw an exception since I regard the code
> as problematic. But if RI can pass the test case, and more importantly
> if EUT depends on it, we probably should find a solution.
>
> Chunrong, do you know if EUT can pass (or continue) when this issue is
> resolved?
>
> Thanks,
> xiaofeng
>
> On Sun, Jan 4, 2009 at 2:46 PM, Xiao-Feng Li (JIRA) <ji...@apache.org>
> wrote:
> >
> >    [
> https://issues.apache.org/jira/browse/HARMONY-6020?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12660536#action_12660536]
> >
> > Xiao-Feng Li commented on HARMONY-6020:
> > ---------------------------------------
> >
> > When we look at this class definition:
> >
> >  class Parent {
> >    private static final Child[] childCache = new Child[5];
> >
> >    public static Child createChild(){
> >        return childCache[0];
> >    }
> >  }
> >
> > It is clear that, the semantics expectation is, childCache should be
> assigned a value when class Parent is ready (i.e., initialized). And this
> value should be assigned to childCache before anybody can access any
> Parent's method, e.g., createChild(). This is the semantics expectation. I
> guess we need to ensure this semantics.
> >
> > Can we simply let this Child clinit() execute in this way: When it tries
> to call Parent.createChild() and finds Parent is under initialization, it
> simply returns null to ROOT without really invoking createChild().
> >
> > According to the JVM spec 2.17.4, it requires any static method
> invocation must happen after the class is "initialized." The problem is, how
> to deal with the situation when a static method is invoked when the owning
> class is under initialization.
> >
> > Thanks,
> > xiaofeng
> >
> >
> >> [DRLVM] Cyclical class dependency causes a failure not seen in RI
> >> -----------------------------------------------------------------
> >>
> >>                 Key: HARMONY-6020
> >>                 URL: https://issues.apache.org/jira/browse/HARMONY-6020
> >>             Project: Harmony
> >>          Issue Type: Bug
> >>          Components: DRLVM
> >>    Affects Versions: 5.0M8
> >>         Environment: Win Vista 32-bit
> >>            Reporter: Nathan Beyer
> >>            Assignee: Chunrong Lai
> >>         Attachments: cycle-project.zip
> >>
> >>
> >> If two classes have a cyclical dependency, some unexpected results may
> occur, which are not seen on RI (Sun 6u10).
> >
> > --
> > This message is automatically generated by JIRA.
> > -
> > You can reply to this email to add a comment to the issue online.
> >
> >
>
>
>
> --
> Xiao-Feng Li
> Managed Runtime Technology Center, Intel
>