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


Reply via email to