[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: More JNI vs. Pika comparison




    > From: Jim Blandy <jimb@xxxxxxxxxx>

    > Tom Lord <lord@xxxxxxx> writes:
    > >     > It seems to me similar problems will occur working with any
    > >     > third-party tool that presumes it is sufficient to let people pass
    > >     > around pointers to data of their own definition.

    > >     > So, in the end, it looks to me as if Pika will need to provide a
    > >     > JNI-style interface anyway, in addition to the C compound-statement-
    > >     > bound interface, which would still be the preferred interface for C
    > >     > code written against Pika interfaces.

    > > I think that has to be read as "JNI-style" in only the broadest sense
    > > of the term -- a need for an interface to create locations whose
    > > lifetime is explicitly managed.  Narrower "JNI-style" features that
    > > are _not_ necessary include:

    > > ~ reference counting for locations
    > > ~ "linear" functions
    > > ~ attachment of locations to a "call" structure whose lifetime
    > >   trumps the reference count of attached locations

    > Where did reference counting come from?  I don't think I've ever
    > mentioned it.  

My faulty memory, apparently.   I'm surprised you wouldn't have
specified it that way in the first place.

    > The Minor interface doesn't include any, nor does the
    > actual JNI, as far as I know.  Is there some use case where simply
    > duplicating references won't work just as well?

Obviously.   Anytime you want a location shared by multiple data
structures whose lifetimes are independent of one another.


    > I see the idea of explicitly freed references with dynamic lifetimes
    > as the essential idea in the JNI model.

I think the clearest way to look at things is in terms of (scheme)
locations and values.   References are locations.   If you have an
important class of locations that follow some constrained allocation
pattern (like locals and intermediates), then it's worth looking for a
nice interface for those other than explicit-free.


    >> Second, all intermediate values constructed in this parse but _not_
    >> stored in a reference that will be destructively updated (such as $2
    >> in the action above) are GC protected for the lifetime of the parse.
    >> To have a parse that protected a number of locations bound by the 
    >> depth of the value stack, one would need to write something like:

    >>       datum list_data { 
    >>                         $$ = mn_to_cons (c, $1, $2); 
    >>                         mn_unref (c, $2);
    >>                       }

    >> In other words, on two counts at least, the enticing simplicity 
    >> of the exhibited code is at least a little bit misleading.

    > mn_to_cons is defined to free both its arguments.  Given that, there
    > shouldn't be any reference leak in the code as written, right?  

Right, but -- ick.

    >> I suppose that the brute force Pika solution would look something
    >> like:

    >>       datum list_data { 
    >>                         $$ = scm_allocate_location (instance);
    >>                         scm_cons ($$, instance, $1, $2);
    >>                         scm_location_unref (instance, $1);
    >>                         scm_location_unref (instance, $2);
    >>                       }

    >> which, although four times as verbose as your original code (twice as
    >> verbose as the more robust form of your code), is not fragile wrt to
    >> "linear" operations and is accurate wrt to GC.

    > I can't refer to $1 and $2 after those *_unref calls, right?  

No, but you can between the CONS and the UNREFs.

    > The purpose of the linear versions of functions like mn_cons is
    > simply to reduce clutter from the 'free' calls (while leaving
    > them visible), and to put them someplace they could be
    > optimized.  But they're still there; I think our code is
    > essentially the same.

You conclusion is fine with me.   How you got there is kind of goofy.

It's a question of locality of changes.   In my code, with the
explicit UNREFS, if I need to add an additional use of $1 and $2 I
just insert code before the unrefs.   In your code, with the semantics
of "_to_cons", I need (1) change the _to_cons call to something else;
(2) insert the new code; (3) append the explicit deallocations.

In 3-10-line code fragments, that non-locality thing isn't a big
deal.  In larger code, I would think it's a pain in the butt.

-t