This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Idea for culling the core of guile to a neater system


On Wed, 2 Dec 1998, Tel wrote:

> A lot of the SCM stuff is related to dynamic storage,
> lists and garbage collection. In many ways, such storage
> could quite conceivably make a useful library in itself.
[...]
> Such a library could be billed as a general purpose storage
> and garbage collection library and could be given quite a
> neat API.
[...]
> Worth considering?

Definitely. It's a fascinating idea that would be beneficial for a
lot of other projects as well. However, I think some effort must be
taken to do it efficiently. Do you have any ideas regarding the API yet?
Maybe there is already an approach in this direction?

The following suggestion is not just aimed towards this idea, but maybe
would be beneficial for the current guile as well:

Suggestion:
- The memory library should have a list of hooks which are called to
  'mark' objects in the garbage collected area. The stack scanning could
  be done by such a hook.

  example (simplified):

    void scan_the_stack(void* params) {
      for-each stack-element s:
        gc_mark_object(s);
    }

    initialization-code:

    ...
    gc_add_hook(scan_the_stack, (void*)top-of-stack);
    ...

  This could even be used to handle SCM objects on the heap. Assume a C++
  list of SCM objects. Currently every single list element has to be
  protected, which causes additional pairs to be created. In contrast:

    void scan_the_SCM_list(void* param) {
      SCM_list* theList = (SCM_list*)param;
      for-each element e:
        gc_mark_object(e);
    }

    and at every place a SCM_list is created:

    ...
    gc_add_hook(scan_the_SCM_list, (void*)(&theList));
    ...

    and finally, at the place where the list is destroyed (best place
    would be in the destructor if C++ is used):

    ...
    gc_remove_hook(scan_the_SCM_list, (void*)(&theList)));
    ...

This suggestion adds another level of flexibility to garbage collection.
Currently we have three mechanisms:

A builtin into the collector: stack scanning and static memory scanning
  belong into this category. There is no way for ordinary users to
  interfere.
B scm_protect: In order to generate a C/C++ list of SCM objects, I
  basically have to generate a mirror scheme list due to the consing done
  by scm_protect.
C the mark function of smobs. This is far more efficient than the
  scm_protect approach, but requires that a smob type for my C/C++
  container object is defined and that a global reference to this object
  is created on the scheme level. (otherwise the mark function would never
  be called.)

The third point offers a workaround to emulate the possibilities that
could be achieved by the hook variant: If I want to have a container of
SCM objects on the C/C++ level, I
* must create a smob type for the C/C++ container
* must guarantee, that every such container has a corresponding reference
  to it from scheme. The lifetimes of the scheme reference and the
  corresponding C/C++ container must be equal: Otherwise, the
  mark-function of the smob would be called although the C/C++ container
  has been destroyed already, or, the scheme objects that are only
  accessed from within that container are garbaged collected although the
  C/C++ container still lives.

With the availability of gc_add_hook, such a workaround becomes
unnecessary. Further, the need for builtin special code for the collector
becomes unnecessary as well.

Hey, you could even go further and implement scm_protect this way (-:

  void protect_single_scm_object(void* scm) {
    gc_mark_object(scm);
  }

  void scm_protect(SCM scm) {
    gc_add_hook(protect_single_scm_object, (void*)scm);
  }

  :-) but I doubt that (for single SCM objects) this is more efficient
  than the current solution.

Best regards, 
Dirk Herrmann