Version française
Home     About     Download     Resources     Contact us    
Browse thread
Modify macro and caml_initialize function
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Benedikt Meurer <benedikt.meurer@g...>
Subject: Re: [Caml-list] Modify macro and caml_initialize function

On Dec 5, 2010, at 17:13 , Basile Starynkevitch wrote:

> On Sun, 5 Dec 2010 17:02:37 +0100
> "CUOQ Pascal" <Pascal.CUOQ@cea.fr> wrote:
> 
>> ygrek wrote:
>> 
>>> BTW, while we are on this topic, why the following is not in upstream yet?
>>> 
>>> http://eigenclass.org/R2/writings/optimizing-caml_modify
>>> 
>>> Looks like a clear win-win without drawbacks (increased code size shouldn't be significant
>>> cause Modify is only used in a couple of places). What do you think?
>> 
>> This is very interesting. Thanks for pointing it out.
> 
> 
> Sorry to be nitpicking, but...
> 
> IIRC, there might be some rare occasions where the Modify macro could
> be called several times in a C routine. And then you've got several
> caml_modify_maybe_add_to_ref_table labels in the same C routine.
> 
> With GCC, you could use a local __label__
> http://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html but if you want to
> be portable to non GCC compilers, you'll need a Modify macro which
> generates a unique label (perhaps using __LINE__ for that purpose).
> 
> I am thinking of something like [UNTESTED CODE]
> 
> #define Modify(fp, val) Modify_at(fp, val, __LINE__)
> 
> #define Modify_at(fp, val, lin) do{                                         \
>  value in_heap = 0;                                                        \
>  value _old_ = *(fp);                                                      \
>  *(fp) = (val);                                                            \
>  if (caml_gc_phase == Phase_mark) {                                        \
>    if (Is_in_heap (fp)) {                                                  \
>      caml_darken (_old_, NULL);                                            \
>      in_heap = 1;                                                          \
>      goto caml_modify_maybe_add_to_ref_table##Lin;                         \
>    }                                                                       \
>  } else {                                                                  \
>      caml_modify_maybe_add_to_ref_table##Lin:                              \
>      if (Is_block (val) && Is_young (val)                                  \
>          && ! (Is_block (_old_) && Is_young (_old_)) &&                    \
>          (in_heap || Is_in_heap (fp)) ){                                   \
>        if (caml_ref_table.ptr >= caml_ref_table.limit){                    \
>          CAMLassert (caml_ref_table.ptr == caml_ref_table.limit);          \
>          caml_realloc_ref_table (&caml_ref_table);                         \
>        }                                                                   \
>        *caml_ref_table.ptr++ = (fp);                                       \
>      }                                                                     \
>  }                                                                         \
> }while(0)

Just use a static inline function, maybe with __attribute__((force_inline)) for GCC.

Benedikt