/usr/lib/ocaml/caml/weak.h is in ocaml-nox 4.05.0-10ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /**************************************************************************/
/* */
/* OCaml */
/* */
/* Damien Doligez, projet Para, INRIA Rocquencourt */
/* */
/* Copyright 1997 Institut National de Recherche en Informatique et */
/* en Automatique. */
/* */
/* All rights reserved. This file is distributed under the terms of */
/* the GNU Lesser General Public License version 2.1, with the */
/* special exception on linking described in the file LICENSE. */
/* */
/**************************************************************************/
/* Operations on weak arrays */
#ifndef CAML_WEAK_H
#define CAML_WEAK_H
#ifdef CAML_INTERNALS
#include "mlvalues.h"
extern value caml_ephe_list_head;
extern value caml_ephe_none;
/** The first field 0: weak list;
second field 1: data;
others 2..: keys;
A weak pointer is an ephemeron with the data at caml_ephe_none
If fields are added, don't forget to update weak.ml [additional_values].
*/
#define CAML_EPHE_LINK_OFFSET 0
#define CAML_EPHE_DATA_OFFSET 1
#define CAML_EPHE_FIRST_KEY 2
/* In the header, in order to let major_gc.c
and weak.c see the body of the function */
static inline void caml_ephe_clean (value v){
value child;
int release_data = 0;
mlsize_t size, i;
header_t hd;
Assert(caml_gc_phase == Phase_clean);
hd = Hd_val (v);
size = Wosize_hd (hd);
for (i = 2; i < size; i++){
child = Field (v, i);
ephemeron_again:
if (child != caml_ephe_none
&& Is_block (child) && Is_in_heap_or_young (child)){
if (Tag_val (child) == Forward_tag){
value f = Forward_val (child);
if (Is_block (f)) {
if (!Is_in_value_area(f) || Tag_val (f) == Forward_tag
|| Tag_val (f) == Lazy_tag || Tag_val (f) == Double_tag){
/* Do not short-circuit the pointer. */
}else{
Field (v, i) = child = f;
if (Is_block (f) && Is_young (f))
add_to_ephe_ref_table(&caml_ephe_ref_table, v, i);
goto ephemeron_again;
}
}
}
if (Is_white_val (child) && !Is_young (child)){
release_data = 1;
Field (v, i) = caml_ephe_none;
}
}
}
child = Field (v, 1);
if(child != caml_ephe_none){
if (release_data){
Field (v, 1) = caml_ephe_none;
} else {
/* The mark phase must have marked it */
Assert( !(Is_block (child) && Is_in_heap (child)
&& Is_white_val (child)) );
}
}
}
#endif /* CAML_INTERNALS */
#endif /* CAML_WEAK_H */
|