Thanks. We still can not make EUT3.5 work. But we have different log/stackTrace this time. I will post the new log to HARMONY-6062.
I think the code needs to be committed, if it does not break the precommit tests, since it fixes the issue in HARMONY-6020. Opinions? chunrong Managed Runtime Technology Center, Intel On Mon, Jan 5, 2009 at 4:48 PM, Xiao-Feng Li <[email protected]> wrote: > Please try with EUT3.5 before committing... :) > > Thanks, > xiaofeng > > On Mon, Jan 5, 2009 at 4:34 PM, chunrong lai <[email protected]> > wrote: > > Thanks for the discussion. > > Now it makes sense to me that the initializeClass from newarray operation > > > > //OPCODE_ANEWARRAY > > static void *rth_newarray_withresolve(Class_Handle klass, unsigned > cp_idx, > > unsigned arraySize) { > > ASSERT_THROW_AREA; > > //resolve and init object class > > Class* objClass = resolveClass(klass, cp_idx, false); > > initializeClass(objClass); //should be removed > > assert(!objClass->is_primitive()); > > > > can be removed. > > After removing it I see the HARMONY-6020 and other test cases I built can > > pass with same behavior with RI. I am going to commit it. For you have > more > > feedbacks please let me know. > > > > chunrong > > Managed Runtime Technology Center, Intel > > On Mon, Jan 5, 2009 at 2:19 PM, Regis <[email protected]> wrote: > > > >> > >> > >> Xiao-Feng Li wrote: > >> > >>> On Mon, Jan 5, 2009 at 5:12 AM, Ian Rogers <[email protected]> > >>> wrote: > >>> > >>>> 2009/1/4 Nathan Beyer <[email protected]> > >>>> > >>>> Could any of the IBM folks on the list get some advice from some class > >>>>> loader experts? > >>>>> > >>>>> -Nathan > >>>>> > >>>>> Hi Nathan, > >>>> > >>>> from reading the description I can describe how Jikes RVM avoids this > >>>> problem (I'm not an IBM VME expert and I've not run the test case to > >>>> check > >>>> that Jikes RVM passes it). In Jikes RVM we have two variants of all > >>>> calls, > >>>> ones to unresolved methods and ones to resolved methods. Unresolved > calls > >>>> are to classes whose initializer hasn't yet been run. If two threads > are > >>>> calling a static method the first will resolve it and in the process > >>>> acquire > >>>> a lock, the second thread must wait for the lock before it can attempt > to > >>>> resolve the method (at which point it will discover the method was > >>>> resolved > >>>> by the other thread and leave early). Checking for classes being > resolved > >>>> litters all of the class loader code, and we're slightly proactive in > >>>> resolving in the case of reflected methods so that we needn't check > for > >>>> resolution when performing reflected method invocation (which is now > >>>> pretty > >>>> much unnecessary since [1] where we generate bytecodes at runtime to > >>>> perform > >>>> reflection). An aside, I wrote a paper where I use the class loader as > a > >>>> test case for optimizations based on stationary/immutable fields > >>>> specified > >>>> via constraints [2], this work specialized the class loader to handle > the > >>>> resolved case as a class is normally accessed when it is resolved > >>>> (figures > >>>> in the paper). > >>>> > >>> > >>> Thanks for the explanation. > >>> > >>> Let me try to explain the problem we are meeting: > >>> > >>> 1. A thread invokes a static method createChild of a class Parent. It > >>> causes class Parent be initialized. > >>> > >>> 2. In Parent's initialization, it creates an array of class Child. It > >>> leads to class Child be initialized. > >>> > >> if add following code to Child > >> static { > >> System.err.println("init Child"); > >> } > >> the output on RI is: > >> null > >> init Child > >> null > >> > >> It seems create array of class Child doesn't lead to class Child be > >> initialized > >> > >> if change childCache from array to instance: > >> > >> private static final Child childCache = new Child(); > >> > >> public static Child createChild(){ > >> return childCache; > >> } > >> the output on RI is: > >> init Child > >> ch...@affc70 > >> null > >> > >> It seems when initialize Child, Parent.createChild() is called, and read > >> the value of childCache, it's not initialized, so null is returned (it's > >> already in initialize process, so just return null?). > >> > >> > >>> 3. In Child's initialization, it invokes Parent.createChild() to > >>> initialize a static field ROOT. This leads to re-entrance of Parent > >>> initialization. > >>> > >>> 4. The thread finds Parent is under initialization by itself, it quits > >>> the initialization process and invokes Parent.createChild(). > >>> > >>> 5. This invocation should not be permitted by the VM spec, and we > >>> don't know how to deal with it. It can't wait for the initialization > >>> process finished, because it is in the path of the initialization. It > >>> has to do something to proceed with the initialization. > >>> > >>> Below is the code of the micro test. Chunrong, please correct me if my > >>> understanding is inaccurate. > >>> > >>> So my suggestion is to ignore the static method invocation for the > >>> class under initialization... > >>> > >>> > >>> public class Main { > >>> public static void main(String[] args) { > >>> Child c = Parent.createChild(); > >>> System.err.println(c); > >>> System.err.println(Child.ROOT); > >>> } > >>> } > >>> > >>> class Parent { > >>> private static final Child[] childCache = new Child[5]; > >>> > >>> public static Child createChild(){ > >>> return childCache[0]; > >>> } > >>> } > >>> > >>> class Child { > >>> public static final Child ROOT = Parent.createChild(); > >>> } > >>> > >>> Thanks, > >>> xiaofeng > >>> > >>> Regards, > >>>> Ian Rogers > >>>> > >>>> [1] > >>>> > >>>> > http://icooolps.loria.fr/icooolps2008/Papers/ICOOOLPS2008_paper08_Rogers_Zhao_Watson_final.pdf > >>>> [2] http://portal.acm.org/citation.cfm?id=1411746 > >>>> > >>>> > >>> > >>> > >>> > >> -- > >> Best Regards, > >> Regis. > >> > > > > > > -- > Managed Runtime Technology Center, Intel >
