Commit Graph

36 Commits (3d63a106b678f54c47698f11db7d810d91d442ec)

Author SHA1 Message Date
Jacques-Henri Jourdan 3d63a106b6
Memprof: optimize random sampling (#9466)
Instead of using the stdlib logf function for computing logarithms, we
use a faster polynomial-based approximation.

We use the xoshiro PRNG instead of the Mersenne Twister.  xoshiro is
simpler and faster.

We generate samples by batches so that compilers can vectorize the
generation loops using SIMD instructions when possible.
2020-05-25 09:51:15 +02:00
Jacques-Henri Jourdan 97eb98db94 Memprof: fatal error if thread is stopped from a callback.
This is specified as undefined behavior in gc.mli.

We now use dedicated functions for the interraction between Memprof
and systhreads.
2020-05-11 15:55:07 +02:00
Enguerrand Decorne b7f0494df5 Rewrite the instrumented runtime to store traces in the CTF format.
The instrumentation code in the instrumented runtime was replaced
with new APIs to gather runtime statistics and output them in a new format
(Common Trace Format).
This commit also exposes new functions in the Gc module to pause or resume
instrumentation during a program execution (Gc.eventlog_pause and
Gc.eventlog_resume).
2020-04-30 10:32:01 +02:00
Gabriel Scherer d440079a3e memprof runtime: keep tracker callbacks in a single value 2020-04-01 16:38:39 +02:00
Gabriel Scherer 14a4510cb7 memprof: remove caml_unused memprof_start_byt and then bootstrap
Build steps for this commit (from a valid core build for the previous commit):

    make coreall
    make coreboot

(Note: `make core` would not work as we remove a primitive.)
2020-04-01 16:38:39 +02:00
Gabriel Scherer ff6b20098f Gc.Memprof.start: take a record instead of 5 optional parameters
The Gc.Memprof module provides a low-level API, that will hopefully be
paired with user libraries that provide high-level instrumentation
choices.

A natural question is: how are the higher-level API going to expose
their choice of instrumentation to their users? With the current
Memprof.start API (before this patch), they would have to either
provide their own `start` function wrapping Memprof.start, or provide
a tuple of callbacks for to their users to pass to Memprof.start
themselves.

    val start : params -> unit
    (* or *)
    val callback : params ->
      ((allocation -> foo option) * (allocation -> bar option) * ... )

With an explicit record, it is easier for libraries to expose an
instrumentation choice (possibility parametrized over
user-provided settings):

    val tracker : params -> (foo, bar) Gc.Memprof.tracker

In addition, providing a record instead of optional parameters makes
it much easier to provide "default settings" (helper functions) that
instantiates the types `'minor` and `'ḿajor`, see for example
`simple_tracker` in this patch (which stores the same information for
the minor and major heap, and does not observe promotion), or to later
define checking predicates that can verify that a given choice of
callbacks is sensible (for example: providing a major-dealloc callback
but no promotion callback (dropping all tracked value on promotion) is
probably not a good idea).

Bootstrap: to avoid requiring an awkward bootstrap, this commit keeps
the (now unused) function caml_memprof_start_byt unchanged -- it is
used in the bootstrap binaries, so removing it would break the
build. The intention is to remove it in the following commit.
2020-04-01 16:37:28 +02:00
David Allsopp 3aab294513 Replace static inline with Caml_inline
The inline keyword is consequently no longer forced on MSVC builds.
2020-02-11 09:33:55 +00:00
Stephen Dolan 20f6a17ae3 Review 2020-02-04 11:03:07 +00:00
Stephen Dolan 060f6e8e47 Avoid scanning the stack twice when collecting callstacks in Memprof. 2020-02-03 10:51:53 +00:00
Stephen Dolan 8633c32525 Distinguish "0" from "don't care" in caml_current_callstack_write. 2020-01-25 22:55:56 +01:00
Stephen Dolan 2ab32f4772 Comments per review. 2020-01-25 22:55:56 +01:00
Stephen Dolan f874b3ee01 Memprof: report different callstacks for different combined allocations 2020-01-25 22:55:56 +01:00
Stephen Dolan 07bf49db5b Statmemprof support for native allocations (incl. Comballoc) 2020-01-25 22:55:56 +01:00
Jacques-Henri Jourdan e1a22e80fb Memprof API: cannot be start if already running, cannot be stopped if not already running. 2020-01-14 10:42:16 +01:00
Jacques-Henri Jourdan 0c8416478c Drop support for tags in memprof.
They are somewhat difficult to handle for native allocations, and it is not clear how useful they are. Moreover, they are easy to add back since [Gc.Memprof.allocation] is a private record.
2020-01-11 13:19:10 +01:00
Jacques-Henri Jourdan 7dbbfce890 New ephemeron-free API for Memprof.
The user can register several callbacks, which are called for various
events during the block's lifetime. We need to maintain a data
structure for tracked blocks in the runtime. When using threads,
callbacks can be called concurrently in a reentrant way, so the
functions manipulating this data structure need to be reentrant.
2019-12-21 10:21:48 +01:00
Guillaume Munch-Maccagnoni d0f70f757a Resource-safe C interface for async callbacks
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.
2019-10-17 20:14:19 +02:00
Guillaume Munch-Maccagnoni 1220986b72 [minor] typo 2019-10-16 14:22:49 +02:00
Guillaume Munch-Maccagnoni e64a8618fe [cleanup] Rename caml_set_something_to_do into caml_set_action_pending 2019-10-15 14:02:22 +02:00
Jacques-Henri Jourdan 1e31beb993 Remove dead variables [caml_memprof_to_do] and [caml_final_to_do]. 2019-10-11 11:17:20 +02:00
Jacques-Henri Jourdan 90073e96e5 Memprof tracking of interned data. 2019-08-27 19:14:56 +02:00
Jacques-Henri Jourdan c0dbbfdd71 Memprof: stop using C global roots, and use our own root system.
Registering and unregistering global C roots was time consuming.
2019-08-27 19:05:03 +02:00
KC Sivaramakrishnan 64d0501c5c Fix references to removed variables 2019-08-23 09:50:05 +05:30
KC Sivaramakrishnan 28c5b9c860 Various minor heap pointers moved to domain state 2019-08-23 09:50:05 +05:30
KC Sivaramakrishnan 45b1e18f59 young_ptr and young_limit are now in domain state 2019-08-23 09:50:05 +05:30
Jacques-Henri Jourdan 42ab59aab1 Use [caml_something_to_do] both in native and bytecode mode to remember that callbacks are pending.
This make us able to get rid of to xxx_to_do variables in `final.c`
and `memprof.c`. The variable is reset to 0 when entering
`caml_check_urgent_gc`, which is now the main entry point for
asynchronous callbacks. In case a callback raises an exception, we
need to set it back to 1 to make sure no callback is missed.
2019-06-06 16:08:06 +02:00
Jacques-Henri Jourdan 0ca84f52cd Refactor the postponed blocks machinery in memprof.c
This makes sure that:
- Callbacks are never called when another is running
- The postponed queue is purged when setting memprof parameters

We now use a FIFO implemented as a circular buffer for remembering of
postponed blocks.
2019-06-05 14:25:33 +02:00
Jacques-Henri Jourdan 79088fb09d Guarantee that no finalisers will be called while allocating memory in OCaml heap from C code.
The finalizers and all the other asynchronous callbacks (including
signal handlers, memprof callbacks and finalizers) are now called in a
common function, [caml_async_callbacks]. It is called in
[caml_check_urgent_gc] and wherever [caml_process_pending_signals] was
called.

This makes it possible to simplify the [caml_gc_dispatch] logic by
removing the loop it contains, since it no longer calls finalizers.
2019-06-05 14:25:26 +02:00
Stephen Dolan 16611aacc1
Merge branch 'trunk' into memprof_binomial 2019-05-27 11:32:07 +01:00
Gabriel Scherer e973cde5a4
Merge pull request #8685 from Fourchaux/trunk
Fixing misspellings
2019-05-24 06:58:30 +02:00
Jacques-Henri Jourdan b838e48c39 Memprof: Instead of a Poisson process, use a binomial distribution.
The workaround used for ignoring samples in the minor heap in native
mode now makes allocation very slow (or non-terminating) when the
sampling rate is not small enough. This will be fixed when sampling in
the minor heap in native mode will be implemented.
2019-05-21 17:10:16 +02:00
Jacques-Henri Jourdan a2cc89c605 Bugfix: handle the OOM case in [capture_callstack_major]. 2019-05-21 15:13:44 +02:00
Damien Doligez 1d7740f624 additional fixes for #8634 2019-05-21 12:44:10 +02:00
JPR 6dc59549ce Fixing misspellings 2019-05-21 10:23:27 +02:00
Jacques-Henri Jourdan cea1ff7534 Memprof sampling for blocks in the minor heap, allocated by C code.
Allocations ignored by this version
- Marshalling
- In the minor heap by natively-compiled OCaml code

Allocations potentially sampled
- In the major heap
- In the minor heap by C code and OCaml code in bytecode mode
2019-05-20 13:04:28 +02:00
Jacques-Henri Jourdan 052a950dea Statistical memory profiling of blocks allocated in the major heap. 2019-05-09 16:40:45 +02:00