Re: when GC is permitted Jim Blandy 08 Jan 2004 19:05 UTC

Felix Winkelmann <xxxxxx@proxima-mt.de> writes:
> I should have been more precise there: I understand the intention
> behind the "critical section". My point is that with an extra-indirection
> (as proposed by Tom or as used in JNI/minor - if I understand it right)
> the second class values point to something opaque. The values inside
> C locals and registers point to some "box" object that could easily be
> registered
> with the collector. Since the user can only access the data via
> extraction forms, it's completely transparent.
>
> This means that the problem would simply go away (IMHO), provided the
> current draft proposal is changed in an appropriate manner.

Oh, I see now.  Yes, you're right --- JNI-style interfaces don't have
this problem; all their critical sections can be wrapped up inside the
API functions themselves.

But you need to be clear about exactly what JNI-style really implies.
Here's the implementation of mn_car, with run-time typechecking
removed:

    mn_ref *
    mn_car (mn_call *call, mn_ref *pair)
    {
      mn_ref *result;

      mn__begin_incoherent (call);
      {
        result = mn__make_local_ref (mn__untag_pair (pair->obj)->car);
      }
      mn__end_incoherent (call);

      return result;
    }

mn__make_local_ref is an allocation.  Sure, it's implemented with free
lists, and when the free list is empty, it'll just bump a pointer to
get the next ref out of a block, which is initialized lazily, and each
new block is allocated to be twice the size of the previous one, so
you're doing log (n) mallocs for n references, blah blah blah.

But here's the alternative.  Under a SRFI-50 style interface, here's
the implementation of car:

    scheme_value
    SCHEME_CAR (scheme_value pair)
    {
      return untag_pair (pair)->car;
    }

Under most reasonable tagging systems, untag_pair can be a
subtraction; the '->car' is a subsequent addition, which can be folded
in with the untagging; and then the whole thing can be easily inlined,
and possibly turned into an offset in the addressing mode of a load
instruction.  So the whole thing turns into a single instruction.

There's no comparison.  I think JNI entails at least one order of
magnitude more instructions to implement 'car'.

This is why Richard doesn't like JNI-style.

(BTW, Tom will be quite disappointed with what GCC's optimizer will do
to Pika-style code; go and try it.)