After trying to make this scheme work out in a practical setting for a
day or so I think I'll give up and shelve it for now. While property
access is notably fast, the overhead of transitioning from one class
to the other (even if it just happens once) outweights that benefit,
so I'm as fast as I was before. This might still be interesting as a
special purpose tool (think of it as an IdScriptableObject created on
the fly), but I don't see it replacing ScriptableObject anymore.

At least I learned a lot about Java bytecode. Maybe I'll use that to
dig deeper into the rhino optimizer code.

On Nov 3, 2:39 pm, Attila Szegedi <[email protected]> wrote:
>
> John Rose was experimenting with a MethodHandle (the invokedynamic  
> stuff slated for Java 7 as per JSR-292) based approach with Rhino, he  
> forwarded me some of his code doodles for it (I gave them to Norris  
> since, I'll send them to you too so you can take a look).

That sounds very interesting, I'd love to see this.

> I'm of course thinking that next time we'd need to overhaul Rhino  
> would be when Java 7 is widespread, and actually rewrite it in terms  
> of my invokedynamic-based linker framework, see slides of the  
> presentation I gave at JVM Language Summit here: 
> <http://wiki.jvmlangsummit.com/MOP_and_Invokedynamic
>  >; the slides have a link to the SVN repository too. That'll make it  
> possible to emit bytecode of the form "invoke method named  
> dyn:getProp:foo" and have the linker framework resolve it to a fully  
> optimizable (inlinable) method call on the object of appropriate type  
> at the call site just before it is invoked.

I must admit I don't know a lot about invokedynamic, but it definitely
sounds like the way to go. I'm reading up on it now.

> You can also get a working OpenJDK build with invokedynamic in it for  
> Mac OS X at <http://www.szegedi.org/mlvm-macosx.html> (for Windows and  
> Linux, you can just download the latest OpenJDK beta from Sun)
>
> Of course, that's all well and good, but we'll need Java 7 for it to  
> work :-) (Or, alternatively, Rémi Forax's backport of JSR-292)
>
> As for Rhino internals relying on ScriptableObject, I believe these  
> should be considered bad practice. All Rhino internals should ideally  
> only rely on Scriptable interface. I think you can liberally change  
> code from using ScriptableObject to Scriptable whereever you can.

The thing is that Scriptable is not enough for most things (getters/
setters, attributes, etc.) so I thought of introducing an extended
scriptable interface for these purposes. Alas, it would be necessary
to touch a lot of code and I'm not really keen on doing that. Maybe we
should start thinking about a release that introduces some non-
backward-compatible changes and API cleanup?

Hannes

> In any case, I'll make sure to take a look at your effort sometime  
> when I get a bit of time (maybe over weekend).
>
> Attila.
>
> On 2009.11.03., at 10:48, Hannes Wallnoefer wrote:
>
> > Inspired by Norris' recent remark about low hanging fruit in the Rhino
> > garden I've started to experiment with mapping individual JS Objects
> > directly to Java classes with property access implemented by auto-
> > generated bytecode. I've created a project on github with some initial
> > proof-of-concept code:
>
> >http://github.com/hns/rhino-8
>
> > I called it rhino-8 because I started out on the idea of native JS
> > property access implemented by Google's V8 engine described here:
>
> >http://code.google.com/apis/v8/design.html#prop_access
>
> > Obviously, the JVM poses some restrictions on what you can do (for
> > example, to invoke a method or access a field in a class from Java
> > bytecode, the target interface or class must be "baked" into the local
> > class so it can't really be generated on the fly). So I went for a
> > more conservative approach which has the benefit of also being more
> > compatible with the Rhino script runtime.
>
> > What I am currently doing is to generate a Java class implementing
> > Rhino's Scriptable interface for each individual set of properties,
> > store property values in a dense object array, and generate switch
> > statements in the get(), put(), has(), and delete() methods similar to
> > those created by the IdSwitch tool to directly map the object's
> > properties into the value array *). When put() is called with an
> > unknown property id, it throws an UnknownFieldError that is caught by
> > a wrapper which transparently "morphes" the object to a newly
> > generated class that includes the new property id.
>
> > *) Note: I previously used individual native Java fields to store
> > property values but changed to the array representation for easier
> > transition between classes. I may go back to individual fields if it
> > benefits performance.
>
> > In other words, I'm providing a faster implementation of Scriptable by
> > implementing property access methods using a switch statement for a
> > well-known set of properties similar to the one used for NativeObject,
> > NativeString, NativeArray etc. prototypes instead of the generic slot
> > hashing implemented by ScriptableObject.
>
> > The code for this is in the org.mozilla.javascript.adaptive package:
>
> >http://github.com/hns/rhino-8/tree/master/src/org/mozilla/javascript/...
>
> > You can use the Rhino shell's defineClass() function to play with it:
>
> > js> defineClass(org.mozilla.javascript.adaptive.AdaptiveObject);
> > js> a = new AdaptiveObject();
>
> > On initial benchmarks, this yields something like 30% - 50%
> > improvement in property access time compared to the current
> > ScriptableObject property implementation (quite a bit when using the
> > server HotSpot VM, which obviously does its own optimization magic on
> > ScriptableObject). Of course the approach won't work for all
> > situations. If you create an object and subsequently add properties to
> > it, a new Java class is generated in each step, and the object is
> > "morphed" to the new class in each step. So this isn't a magic pill
> > that will bring Rhino performance on par with V8 (not even close), but
> > I think it's an approach worth following. The good thing is that it
> > should be relatively easy to use different object implementations for
> > different situations, or switch between them as needed.
>
> > For example, one area where this would most probably make immediate
> > sense is object literals. Object literals have a set of properties
> > that is known beforehand, and they are often read-only and used over
> > and over again, so creating an optimized Java class for them should be
> > worth the overhead most of the time. Other ideas I'm playing with may
> > be to initially use a hashed object and watch usage patterns to decide
> > when and if to switch to compiled, "switched" state, or more simply to
> > delay class generation until the first invocation of get(), which
> > might work well for many common JS programming patterns.
>
> > Unfortunately, a lot of Rhino code currently assumes things to be
> > ScriptableObject instances, so it's not easy to test other object
> > implementations "in the wild". For example, Object.defineProperty
> > assumes not only the target object to be an instance of
> > ScriptableObject, but also the property descriptor argument. So one of
> > the next steps will be to factor the "advanced" property access
> > methods implemented by ScriptableObject into a new sub-interface of
> > Scriptable (I'll probably call it
> > org.mozilla.javascript.ExtendedScriptable - any other suggestions?)
> > and use that wherever ScriptableObject is used. That won't be fun, so
> > maybe as a short-term hack I'll just extend ScriptableObject in
> > AdaptiveObject and override the required methods.
>
> > I'm looking forward to your feedback and suggestions!
>
> > Hannes
>
>

_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to