2011/5/6 Rémi Forax <[email protected]>: > On 05/06/2011 12:39 PM, Hannes Wallnoefer wrote: > >> The reason I'll probably not start from John's branch directly is it >> is based on invokedynamic from the ground up, and we need to support >> Java 6 and earlier for the foreseeable future. >> >> As for type inference, specialization etc.: that is certainly >> interesting, but right now property access seems to be the most >> significant bottleneck, so it seems like a good idea to target that >> first. >> >> Hannes > > I can agree about property access being a bottleneck > but for me to solve property access you need type profiling > which is the common ground for type inference and type > specialization too. > > Let me explain how property access problem can be solved. > As usual, you need an assumption, mine is that any instances > created at one allocation site will have the same set of properties, > i.e the same class. > > So in the interpreter, each allocation site has a reified object > corresponding to that allocation site (in my implementation, I > reuse j.l.invoke.CallSite but it's a detail). > When the interpreter creates an object (a hash map because > in the interpreter we don't have enough information) it > also stores the allocation site. > The idea is that the reified object corresponding to the allocation > site can be considered as describing the class of the instance. > > Each time, there is a lookup in the hashmap that correspond to > a property that was not seen before, the allocation site object > of the instance is updated to say that when optimized, the class > should have the property. If the property already exist, I keep > the class of the value stored (which is equivalent to profiling > the runtime type of the property). > > When the code containing the allocation site needs to be compiled > because it's a hot code, a new class containing all the properties > of the allocation site is generated and used to create the instance. > The class is also used by the inference algorithm to avoid to > generate guards if not needed. > > In fact, it's a little more complex. First, the generated class also own > a field named data which is used as an optimized hashmap if an instance > is used in a code that was never used before and this code adds dynamically > a new property to that instance. > Here, perhaps it could be great to update the allocation site object, > currently I don't do that. > Second, instead of creating a class for each allocation site, I try to see > if an already > generated class for another allocation site doesn't match. > Here, I do the lookup only when I need to generate the code, it should be > done before > because if you have a property with the same name but two different profiled > types, > I will never generate one class but two versions of the same class. > A way to reuse the same class is to take a look to callsites where the > instance are used. > If two instances of different allocation site are used at the same callsite > and have > the same property names, then it should be the same class. > > As you see, you first need to profile variables, callsites and allocations > sites > before being able to optimize.
Thanks for the detailed explanation, Rémi. Rhino in its current form is a bit different from what you describe in that it runs in either interpreted or compiled-to-bytecode mode but doesn't profile and selectively compile hot code. My plan, and what John implemented in the davincimonkey branch, is to use a generic struct-like class that stores values in generic fields or an array. A hidden class (maybe "layout" is the better term, as these are not Java classes) simply maps the actual property names to these generic slots, so a callsite can directly access that slot provided the cached layout/hidden class matches that of the actual object. The way hidden classes/layouts are managed (and AFAIK this is also the way it's implemented in V8) is by recording their evolution paths: each time a property is assigned that is not part of the class, a new hidden class is created along with a reference from the old one. If a hidden class/layout already exists for a property you can immediately walk down the layout graph until it ends or forks to reduce the number of layout switches. So I agree that hidden classes provide a good base on which to implement profiling and optimizations that build on top of it, but Rhino is missing a few other requirements to make that happen in the near future. Hannes > Rémi > > -- > You received this message because you are subscribed to the Google Groups > "JVM Languages" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/jvm-languages?hl=en. > > -- You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.
