caml_input_value_from_string (unused since e227fb007d)
caml_ml_flush_partial, caml_ml_output_partial (unused since 705054b3)
caml_obj_is_block (unused since b1f93a66)
The previous implementation (caml_obj_reachable_words in runtime/obj.c)
was using the mark bits of block headers to detect sharing.
This is not compatible with Multicore OCaml.
This commit reimplements caml_obj_reachable_words to detect sharing
with a hash table of addresses already seen.
The implementation reuses the hash table used to detect sharing
during marshaling (commit 67ada54ce), and other bits of the marshaler,
hence the function caml_obj_reachable_words was moved to runtime/extern.c.
In no-naked-pointers mode, to anticipate the disappearance of the page
table, statically-allocated blocks cannot be treated specially and will
be counted towards the size. This change of semantics is mentioned
in the documentation for Obj.reachable_words.
* camlinternalMod: use closure metadata for copying a closure over another
This change is careful to avoid writing a value into what was
previously a raw field or conversely, clearing fields that change
category first.
We also clear the end of the block, to make it easier to reason about
lifetime of values that could have been referenced there. (We don't
expect this to make a different in practice.)
* Obj: new submodule Closure giving basic access to closure metadata
* Ensure that Obj.new_block returns a sensible uninitialized closure
* Changes
The first closure info field must be valid.
Also document two other places where no change is needed because of
the new closure representation, but for nonobvious reasons.
These primitives are dangerous because they produce naked pointers
outside the OCaml heap, with a risk of "GC pointer confusion".
(After caml_free and a heap extension, the freed memory area can be
reallocated as part of the OCaml heap, causing the naked pointer to
become a bad heap pointer).
These primitives are not used anywhere in the core OCaml system
(in particular they are not exposed via the Obj module).
An OPAM-wide grep shows no uses there either.
Some OCaml objects contain data that cannot be safely represented
as an OCaml value (type Obj.t). For example, in no-naked-pointers mode,
this is the case for code pointers inside closures, and for the
"custom operations" pointers inside custom blocks.
This PR introduces a type Obj.raw_data (an alias for nativeint)
to encapsulate this data, and functions
Obj.raw_field / Obj.set_raw_field to read and write the "raw" contents
of fields of blocks.
Note: just like it is wrong to access code pointers and custom operations
using Obj.field / Obj.set_field, it is wrong to access regular fields
possibly containing pointers into the OCaml heap using
Obj.raw_field / Obj.set_raw_field. The OCaml heap block can be
reclaimed or moved after its address was captured by Obj.raw_field.
Symmetrically, Obj.set_raw_field on a regular field bypasses the
write barrier of the GC.
caml_alloc returns initialised blocks for tag < No_scan_tag. Otherwise,
initialise the blocks as necessary.
For Abtract_tag, Double_tag and Double_array_tag, the initial contents
are irrelevant.
Uninitialised Custom_tag objects are difficult to use correctly. Hence,
reject custom block allocations through Obj.new_block.
For String_tag, the last byte encodes the string length. Hence, reject
zero-length string objects. Initialise the last byte which encodes the
length to ensure non-negative lengths for uninitialised strings.
In debug builds, the minor GC now asserts that young_ptr points to
a valid minor heap header before starting GC. Since very few bit
patterns are valid minor heap headers, this is unlikely to be true
by coincidence.
This patch also ensures that minor allocations have color 0. This
was inconsistent between backends before.
Introduce caml_process_pending_actions and
caml_process_pending_actions_exn: a variant of the former which does
not raise but returns a value that has to be checked against
Is_exception_value.
I keep the current conventions from caml_callback{,_exn}: For a
resource-safe interface, we mostly care about the _exn variants, but
every time there is a public _exn function I provide a function that
raises directly for convenience.
They are introduced and documented in caml/signals.h.
Private functions are converted to their _exn variant on the way as
needed: for internal functions of the runtime, it is desirable to go
towards a complete elimination of functions that raise implicitly.
Get rid of the distant logic of caml_raise_in_async_callback. Instead,
caml_process_pending_events takes care itself of its something_to_do
"resource". This avoids calling the former function in places
unrelated to asynchronous callbacks.
In 8691, caml_check_urgent_gc was merged with the function that runs
asynchronous callbacks. The rationale was that caml_check_urgent_gc
already runs finalisers, and so could have run any asynchronous
callbacks.
We agreed on a different strategy: we know that users could not rely
on asynchronous callbacks being called at this point, so take the
opportunity to make it callback-safe, like was done for allocation
functions.
The new check_urgent_gc no longer calls finalisers (nor any
callbacks), and instead two internal functions are introduced:
* caml_do_urgent_gc_and_callbacks : function to perform actions
unconditionally.
* caml_check_urgent_gc_and_callbacks : function that checks for
something to do, and then executes all actions (GC and callbacks).