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

Re: Memory Management

>Is there any way to walk the lisp memory ala GC? I would like to set up a heap
>zone that is swept automatically; e.g. _disposePtr when no Lisp value
>references it.  I would like to do this in assembly language.
>Could I use weak hash tables for this? I thought some of using a weak hash
>table to keep a list of all the mac-ptrs to my heap zone I had allocated.  I
>can't keep them in any standard lisp collection, because this will prevent them
>from being garbage collected!
>While on the subject, why not include automatic heaps sweeps in 2.1? The
>current scheme is _very_ un-lisp like. I know that occasionally the OS needs to
>hold on to a pointer, but it seems pretty easy to keep a lisp pointer around to
>prevent the memory block from being disposed of prematurely. The problem I see
>is that if something isn't done soon, it will never be able to be done because
>it will break to much code (people will stick mac-pointers in all sorts of
>crazy places)

I don't understand how your "automatic heap sweep" differs from GC, except
that you want to call #_DisposPtr on macptr's that are no longer referenced.

MCL already has an undocumented feature that causes the garbage collector
to deallocate unreachable macptrs. It works as follows in 2.0b1 & 2.0 final,
but we may change the interface in future versions.

ccl::make-gcable-macptr flags
  Make a macptr that will be tracked by the garbage collector.
  Flags should be a fixnum, usually one of the $flags_xxx values
  documented below. Use %setf-macptr to set the address

ccl::macptr-flags macptr
  Return the flags of a macptr

ccl::set-macptr-flags macptr flags
  Change the flags of a macptr. This will NOT make a non-gcable
  macptr gcable.

The macptr-flags control what the garbage collector does when it
encounters a no-longer-referenced gcable macptr. They are defined
in the file "lispequ.lisp" in the "library" folder ($flags_DisposGword
is not implemented in 2.0b1):

(defconstant $flags_Normal 0)
(defconstant $flags_DisposHandle 1)
(defconstant $flags_DisposPtr 2)
(defconstant $flags_DisposWindow 3)
(defconstant $flags_DisposGworld 4)

Here's an example of one way to use it:

(eval-when (:compile-toplevel :execute)
  (require :lispequ))

(defun new-gcable-ptr (size)
  (with-macptrs ((ptr (#_NewPtr size)))
    ; Be careful to cons the gcable macptr after allocating the pointer.
    (%setf-macptr (ccl::make-gcable-macptr #$flags_DisposPtr) ptr)))