Finalizers and FFI

Alastair Reid alastair at reid-consulting-uk.ltd.uk
Fri Jun 11 19:16:58 EDT 2004


> AFAIK this creates some dynamic machine code in malloce'd area, so there
> is need to free it afterward with freeHaskellFunPtr. Are you doing that?
> How? And when? I did not find any suitable place in my code to call
> freeHaskellFunPtr.

Machine code is dynamically created when you turn a Haskell function into a C 
function using Dynamic wrapper (i.e., using the "wrapper" specifier).  (It 
might also be used  for foreign exports as well since the easiest 
implementation is to generate a wrapper and call that as the runtime is 
initialized.)

Dedicated users of valgrind would take care to free up all the HaskellFunPtr's 
generated this way but, apart from that, I'd only worry about it if:

1) There are lots of them.

   The dynamic machine code is quite small (probably 10-20 bytes plus 
    another 8 bytes for malloc admin purposes).
   The Haskell function you're exporting will use a StablePtr which
    takes another 8-16 bytes.
   The Haskell function itself will probably be another 16 bytes or so
    for the closure.

   Overall, you're looking at less than 100 bytes per object unless...

2) The Haskell functions you are wrapping are large.

   For example, if you wrap:

      foo :: Int -> Int
      foo = let primes = ...
            in \ n -> primes !! n

    then the 'primes' object could get quite big and you'd worry about
    a space leak. 

As for how you keep track of them and free them.  It's probably easiest to do 
it on the C side of things using conventional C memory management techniques
(reference counting, etc.)  Of course, there's a problem if you have C 
function pointers generated using '&' in C and function pointers generated
using dynamic wrappers in Haskell.  There's no reliable way to tell them
apart.

--
Alastair Reid


More information about the Glasgow-haskell-users mailing list