Version française
Home     About     Download     Resources     Contact us    
Browse thread
problem creating .cma library
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Richard Jones <rich@a...>
Subject: Re: [Caml-list] problem creating .cma library
On Sat, Jan 09, 2010 at 12:33:08PM +0100, Guillaume Yziquel wrote:
> David Allsopp a écrit :
> >Guillaume Yziquel:
> >
> >>So, no allocation of OCaml values (or in place modification, either, I
> >>guess) implies no need for CAMLparam/CAMLreturn stuff?
> >
> >Chapter 18 of the manual in Section 18.5 describes pretty much everything 
> >you need to know about writing safe stubs that work with the garbage 
> >collector.  
> 
> Yes. It is all I need to know to write safe stubs. But it does not 
> answer the question above. It does state that you do not need 
> registration of the result value if there's no allocation going on 
> between the moment result get its value and the return statement. But it 
> does not say when you can avoid CAMLparam macros.

The basic problem is that whenever you do an allocation, the allocator
might need to run the garbage collector.  Allocations from the minor
heap are normally quick (just comparing and decrementing a pointer),
but once the minor heap runs out a minor heap collection has to be
done, and that implies a slice of major heap collection too.

Why is this a problem?  Because you might in your C code have some
value on the stack.  'value' is (or can be) a pointer.  The OCaml
garbage collector can move pointed-to-objects around, firstly from the
minor heap to the major heap, secondly when compacting the major heap.
So your C value (pointer) *could* become an invalid pointer if what it
was pointing to got moved.

The way to avoid this small chance is to register the value with the
garbage collector, which is essentially what the CAMLparam* and
CAMLlocal* macros do.  So if the GC needs to move that object, it will
update the pointer for you.

If your function never allocates (and never calls anything which
allocates), then you don't need to register values, because no
allocation => they can't be moved.  [In fact there are some other
exceptions as well where you can prove that an allocation won't move
your pointer, eg. if you only allocate one thing and immediately
return the value.]

However it's always safe to use the macros, even if you're not
allocating, albeit a tiny little bit slower.

You might find my series on the garbage collector interesting if you
want to look into this further:

http://rwmj.wordpress.com/?s=ocaml+internals

Also if you are calling C functions which don't allocate from OCaml
code, you might want to read about noalloc:

http://camltastic.blogspot.com/2008/08/tip-calling-c-functions-directly-with.html

> By the way, here's a question I've been wondering about this section. 
> Rule 3: When I have a Abstract_tag block used to wrap a pointer in the C 
> heap, it seems to me that you can just do it with a Field(v,0)= 
> assignment. Do you need Store_field for that?

This is to do with the Remembered Set.  See part 5 of the above
series.

Rich.

-- 
Richard Jones
Red Hat