harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jack Cai" <greensi...@gmail.com>
Subject Re: [class loading] what's the expected behavior when a static method is invoked before its class is initialized?
Date Mon, 05 Jan 2009 06:30:23 GMT
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 <chunronglai@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 <greensight@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 <ndbeyer@apache.org>
> >
> > > On Sun, Jan 4, 2009 at 10:08 PM, Xiao-Feng Li <xiaofeng.li@gmail.com>
> > > wrote:
> > > > On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <rogers.email@gmail.com>
> > > wrote:
> > > >> 2009/1/4 Nathan Beyer <ndbeyer@apache.org>
> > > >>
> > > >>> Could any of the IBM folks on the list get some advice from some
> > class
> > > >>> loader experts?
> > > >>>
> > > >>> -Nathan
> > > >>>
> > > >>
> > > >>  Hi Nathan,
> > > >>
> > > >> from reading the description I can describe how Jikes RVM avoids
> this
> > > >> problem (I'm not an IBM VME expert and I've not run the test case
to
> > > check
> > > >> that Jikes RVM passes it). In Jikes RVM we have two variants of all
> > > calls,
> > > >> ones to unresolved methods and ones to resolved methods. Unresolved
> > > calls
> > > >> are to classes whose initializer hasn't yet been run. If two threads
> > are
> > > >> calling a static method the first will resolve it and in the process
> > > acquire
> > > >> a lock, the second thread must wait for the lock before it can
> attempt
> > > to
> > > >> resolve the method (at which point it will discover the method was
> > > resolved
> > > >> by the other thread and leave early). Checking for classes being
> > > resolved
> > > >> litters all of the class loader code, and we're slightly proactive
> in
> > > >> resolving in the case of reflected methods so that we needn't check
> > for
> > > >> resolution when performing reflected method invocation (which is now
> > > pretty
> > > >> much unnecessary since [1] where we generate bytecodes at runtime
to
> > > perform
> > > >> reflection). An aside, I wrote a paper where I use the class loader
> as
> > a
> > > >> test case for optimizations based on stationary/immutable fields
> > > specified
> > > >> via constraints [2], this work specialized the class loader to
> handle
> > > the
> > > >> resolved case as a class is normally accessed when it is resolved
> > > (figures
> > > >> in the paper).
> > > >
> > > > Thanks for the explanation.
> > > >
> > > > Let me try to explain the problem we are meeting:
> > > >
> > > > 1. A thread invokes a static method createChild of a class Parent. It
> > > > causes class Parent be initialized.
> > > >
> > > > 2. In Parent's initialization, it creates an array of class Child. It
> > > > leads to class Child be initialized.
> > >
> > > 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
> > > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message