On Sun, Jun 13, 2010 at 2:54 AM, Wayne Meissner <wmeiss...@gmail.com> wrote: > Could the weak ref wiring be done lazily, so the overhead is only > incurred when someone sets an ivar on a java object? > > e.g. when a java object enters jruby, it gets a new lightweight > wrapper, but when someone does an ivar get/set on it, it looks for the > ivar holder for the java object in the weak map, and attaches it to > the wrapper (or creates one and adds it to the weak map if it is > missing). > > This way, java objects that are just passing through, don't take the > hit of wiring up a Reference, but when it is needed, it automagically > works (with perhaps a bit more overhead than at present).
I've tried to think of a way to do this, but we'd need to be able to trigger all in-flight references to a given object to start using the ivars from the wrapper where we just added ivars. In other words a = someJavaCall # first reference to a Java object b = someJavaCall # second reference to the same Java object b.instance_variable_set :@foo, :bar # ivar assigned only on the "b" wrapper We'd need a way to make the "a" wrapper know about the "b" wrapper's new ivars. I can't think of a way to make this work without doing what we do now. > Of course, it gets complicated by other things like method dispatch - > if someone defines a ruby method on a java object, then they would > want that used in preference to the java one when in ruby, so you > would always have to lookup the holder object in the weak map when > calling methods anyway. Making people explicitly request the > behaviour might be more efficient. I also tried another implementation that shipped in 1.5.0 but was reverted because of memory leaks. In 1.5.0, the ivar table itself was kept in a weak-keyed map where the key was the Java object and the value was an array of instance variables. This works great, isolating the ivar table from the wrapper and allowing us to throw wrappers away. It also puts the current cost of ivars (weak map wrangling) only on the *objects* that use them. Unfortunately, it has a fundamental flaw I didn't think of before release: ivars that cause a hard reference to lead back to the original object will prevent the object from being collected, since the value field of that weak map needs to hard-reference the ivar table, and the ivar table needs to hard-reference the ivar values. I reverted this change back to the in-wrapper ivars for 1.5.1. Because of the failure of that implementation, I now have no other ideas for how to support ivars (and singletons) on Java objects without doing it on the actual wrapper object, and the only way I have thought of to make that efficient is to make it opt-in. It's a bummer that this particular feature of Ruby incurs such a cost for Java objects, but I have no other ideas right now. If I had my choice and we didn't have any users using ivars or singletons on Java objects, I'd just disable both :) - Charlie --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email