diff --git a/otherlibs/memtrace/memprof_tracer.ml b/otherlibs/memtrace/memprof_tracer.ml index a967ae50ed7d..a6bdcf1c3dc6 100644 --- a/otherlibs/memtrace/memprof_tracer.ml +++ b/otherlibs/memtrace/memprof_tracer.ml @@ -32,8 +32,7 @@ let default_report_exn e = let start ?(report_exn=default_report_exn) ~sampling_rate trace = let s = { trace; locked = false; stopped = false; failed = false; report_exn } in - let tracker : (_,_) Gc.Memprof.tracker = { - alloc_minor = (fun info -> + let minor_alloc_callback = (fun (info : Gc.Memprof.allocation) -> if lock_tracer s then begin match Trace.Writer.put_alloc_with_raw_backtrace trace (Trace.Timestamp.now ()) ~length:info.size @@ -43,8 +42,9 @@ let start ?(report_exn=default_report_exn) ~sampling_rate trace = with | r -> unlock_tracer s; Some r | exception e -> mark_failed s e; None - end else None); - alloc_major = (fun info -> + end else None) + in + let major_alloc_callback = (fun (info : Gc.Memprof.allocation) -> if lock_tracer s then begin match Trace.Writer.put_alloc_with_raw_backtrace trace (Trace.Timestamp.now ()) ~length:info.size @@ -54,27 +54,36 @@ let start ?(report_exn=default_report_exn) ~sampling_rate trace = with | r -> unlock_tracer s; Some r | exception e -> mark_failed s e; None - end else None); - promote = (fun id -> + end else None) + in + let promote_callback = (fun id -> if lock_tracer s then match Trace.Writer.put_promote trace (Trace.Timestamp.now ()) id with | () -> unlock_tracer s; Some id | exception e -> mark_failed s e; None - else None); - dealloc_minor = (fun id -> + else None) + in + let minor_dealloc_callback = (fun id -> if lock_tracer s then match Trace.Writer.put_collect trace (Trace.Timestamp.now ()) id with | () -> unlock_tracer s - | exception e -> mark_failed s e); - dealloc_major = (fun id -> + | exception e -> mark_failed s e) + in + let major_dealloc_callback = (fun id -> if lock_tracer s then match Trace.Writer.put_collect trace (Trace.Timestamp.now ()) id with | () -> unlock_tracer s - | exception e -> mark_failed s e) } in + | exception e -> mark_failed s e) + in Gc.Memprof.start ~sampling_rate ~callstack_size:max_int - tracker; + ~minor_alloc_callback + ~major_alloc_callback + ~promote_callback + ~minor_dealloc_callback + ~major_dealloc_callback + (); s let stop s = diff --git a/otherlibs/memtrace/vendor b/otherlibs/memtrace/vendor index dc5ed19173fd..095570a616ec 100644 --- a/otherlibs/memtrace/vendor +++ b/otherlibs/memtrace/vendor @@ -1,2 +1,7 @@ This a vendored version of the `src` dir of: git@github.com:janestreet/memtrace.git#6c7ed830b3535bcd77be698a5d556fe4a54974ba + +Additional patches: +- Use the 5 arguments interface of Gc.Memprof.start instead of the record one, + + see 2805c598a94b3081f887eaf6403b8de4582cb653 for the commit that changed the contents of this directory + + see ff6b20098f7f51758d78546af4bb8747cdc8c9f4 for the commit introducing the record representation diff --git a/runtime/memprof.c b/runtime/memprof.c index e71f06657859..bacb4a1eeef7 100644 --- a/runtime/memprof.c +++ b/runtime/memprof.c @@ -867,19 +867,17 @@ void caml_memprof_shutdown(void) { callstack_buffer_len = 0; } -CAMLprim value caml_memprof_start(value lv, value szv, value tracker) +CAMLprim value caml_memprof_start(value lv, value szv, + value cb_alloc_minor, value cb_alloc_major, + value cb_promote, + value cb_dealloc_minor, + value cb_dealloc_major) { - CAMLparam3(lv, szv, tracker); - + CAMLparam5(lv, szv, cb_alloc_minor, cb_alloc_major, cb_promote); + CAMLxparam2(cb_dealloc_minor, cb_dealloc_major); double l = Double_val(lv); intnat sz = Long_val(szv); - value cb_alloc_minor = Field(tracker, 0); - value cb_alloc_major = Field(tracker, 1); - value cb_promote = Field(tracker, 2); - value cb_dealloc_minor = Field(tracker, 3); - value cb_dealloc_major = Field(tracker, 4); - if (started) caml_failwith("Gc.Memprof.start: already started."); if (sz < 0 || !(l >= 0.) || l > 1.) /* Checks that [l] is not NAN. */ @@ -914,10 +912,11 @@ CAMLprim value caml_memprof_start(value lv, value szv, value tracker) CAMLreturn(Val_unit); } -/* not used anymore, the prototype is only kept until the next bootstrap */ CAMLprim value caml_memprof_start_byt(value* argv, int argn) { - return(Val_unit); + CAMLassert(argn == 7); + return caml_memprof_start(argv[0], argv[1], argv[2], argv[3], + argv[4], argv[5], argv[6]); } CAMLprim value caml_memprof_stop(value unit) diff --git a/stdlib/gc.ml b/stdlib/gc.ml index 52433ca43235..771dea51b8b2 100644 --- a/stdlib/gc.ml +++ b/stdlib/gc.ml @@ -127,31 +127,27 @@ module Memprof = unmarshalled : bool; callstack : Printexc.raw_backtrace } - type ('minor, 'major) tracker = { - alloc_minor: allocation -> 'minor option; - alloc_major: allocation -> 'major option; - promote: 'minor -> 'major option; - dealloc_minor: 'minor -> unit; - dealloc_major: 'major -> unit; - } - - let null_tracker = { - alloc_minor = (fun _ -> None); - alloc_major = (fun _ -> None); - promote = (fun _ -> None); - dealloc_minor = (fun _ -> ()); - dealloc_major = (fun _ -> ()); - } - external c_start : - float -> int -> ('minor, 'major) tracker -> unit - = "caml_memprof_start" + float -> int -> + (allocation -> 'minor option) -> + (allocation -> 'major option) -> + ('minor -> 'major option) -> + ('minor -> unit) -> + ('major -> unit) -> + unit + = "caml_memprof_start_byt" "caml_memprof_start" let start ~sampling_rate ?(callstack_size = max_int) - tracker = - c_start sampling_rate callstack_size tracker + ?(minor_alloc_callback = fun _ -> None) + ?(major_alloc_callback = fun _ -> None) + ?(promote_callback = fun _ -> None) + ?(minor_dealloc_callback = fun _ -> ()) + ?(major_dealloc_callback = fun _ -> ()) () = + c_start sampling_rate callstack_size minor_alloc_callback + major_alloc_callback promote_callback minor_dealloc_callback + major_dealloc_callback external stop : unit -> unit = "caml_memprof_stop" end diff --git a/stdlib/gc.mli b/stdlib/gc.mli index 77682456f7da..fb84421bd9f2 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -458,32 +458,15 @@ module Memprof : type of records passed to the callback triggered by the sampling of an allocation. *) - type ('minor, 'major) tracker = { - alloc_minor: allocation -> 'minor option; - alloc_major: allocation -> 'major option; - promote: 'minor -> 'major option; - dealloc_minor: 'minor -> unit; - dealloc_major: 'major -> unit; - } - (** - A [('minor, 'major) tracker] describes how memprof should track - sampled blocks over their lifetime, keeping a user-defined piece - of metadata for each of them: ['minor] is the type of metadata - to keep for minor blocks, and ['major] the type of metadata - for major blocks. - - If an allocation-tracking or promotion-tracking function returns [None], - memprof stops tracking the corresponding value. - *) - - val null_tracker: ('minor, 'major) tracker - (** Default callbacks simply return [None] or [()] *) - val start : sampling_rate:float -> ?callstack_size:int -> - ('minor, 'major) tracker -> - unit + ?minor_alloc_callback:(allocation -> 'minor option) -> + ?major_alloc_callback:(allocation -> 'major option) -> + ?promote_callback:('minor -> 'major option) -> + ?minor_dealloc_callback:('minor -> unit) -> + ?major_dealloc_callback:('major -> unit) -> + unit -> unit (** Start the sampling with the given parameters. Fails if sampling is already active. @@ -495,10 +478,14 @@ module Memprof : The parameter [callstack_size] is the length of the callstack recorded at every sample. Its default is [max_int]. - The parameter [tracker] determines how to track sampled blocks - over their lifetime in the minor and major heap. + The parameters *[_callback] are functions called when an event + occurs on a sampled block. If such a callback returns [None], + then the tracking of this particular block is cancelled. If + they return [Some v], then the value [v] will be passed to the + next callback for this block. Default callbacks simply return + [None] or [()]. - Sampling is temporarily disabled when calling a callback + The sampling is temporarily disabled when calling a callback for the current thread. So they do not need to be reentrant if the program is single-threaded. However, if threads are used, it is possible that a context switch occurs during a callback, diff --git a/testsuite/tests/statmemprof/arrays_in_major.ml b/testsuite/tests/statmemprof/arrays_in_major.ml index f3c5b8a68f79..f213828670c8 100644 --- a/testsuite/tests/statmemprof/arrays_in_major.ml +++ b/testsuite/tests/statmemprof/arrays_in_major.ml @@ -17,12 +17,12 @@ let[@inline never] allocate_arrays lo hi cnt keep = let check_nosample () = Printf.printf "check_nosample\n%!"; - let alloc _ = + let cb _ = Printf.printf "Callback called with sampling_rate = 0\n"; assert(false) in - start ~callstack_size:10 ~sampling_rate:0. - { null_tracker with alloc_minor = alloc; alloc_major = alloc; }; + start ~callstack_size:10 ~minor_alloc_callback:cb ~major_alloc_callback:cb + ~sampling_rate:0. (); allocate_arrays 300 3000 1 false; stop () @@ -36,26 +36,25 @@ let check_counts_full_major force_promote = let npromote = ref 0 in let ndealloc_minor = ref 0 in let ndealloc_major = ref 0 in - start ~callstack_size:10 ~sampling_rate:0.01 - { - alloc_minor = (fun _ -> - if not !enable then None - else Some (incr nalloc_minor) - ); - alloc_major = (fun _ -> - if not !enable then None - else Some (incr nalloc_major) - ); - promote = (fun _ -> - Some (incr npromote) - ); - dealloc_minor = (fun _ -> - incr ndealloc_minor - ); - dealloc_major = (fun _ -> - incr ndealloc_major - ); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun _ -> + if !enable then begin + incr nalloc_minor; + Some () + end else + None) + ~major_alloc_callback:(fun _ -> + if !enable then begin + incr nalloc_major; + Some () + end else + None) + ~promote_callback:(fun _ -> + incr npromote; + Some ()) + ~minor_dealloc_callback:(fun _ -> incr ndealloc_minor) + ~major_dealloc_callback:(fun _ -> incr ndealloc_major) + ~sampling_rate:0.01 (); allocate_arrays 300 3000 1 true; enable := false; assert (!ndealloc_minor = 0 && !ndealloc_major = 0); @@ -92,14 +91,11 @@ let check_no_nested () = () in let cb' _ = cb (); Some () in - start ~callstack_size:10 ~sampling_rate:1. - { - alloc_minor = cb'; - alloc_major = cb'; - promote = cb'; - dealloc_minor = cb; - dealloc_major = cb; - }; + start ~callstack_size:10 + ~minor_alloc_callback:cb' ~major_alloc_callback:cb' + ~promote_callback:cb' ~minor_dealloc_callback:cb + ~major_dealloc_callback:cb + ~sampling_rate:1. (); allocate_arrays 300 300 100 false; stop () @@ -108,16 +104,15 @@ let () = check_no_nested () let check_distrib lo hi cnt rate = Printf.printf "check_distrib %d %d %d %f\n%!" lo hi cnt rate; let smp = ref 0 in - start ~callstack_size:10 ~sampling_rate:rate - { null_tracker with - alloc_major = (fun info -> - assert (info.size >= lo && info.size <= hi); - assert (info.n_samples > 0); - assert (not info.unmarshalled); - smp := !smp + info.n_samples; - None - ); - }; + start ~callstack_size:10 + ~major_alloc_callback:(fun info -> + assert (info.size >= lo && info.size <= hi); + assert (info.n_samples > 0); + assert (not info.unmarshalled); + smp := !smp + info.n_samples; + None + ) + ~sampling_rate:rate (); allocate_arrays lo hi cnt false; stop (); diff --git a/testsuite/tests/statmemprof/arrays_in_minor.ml b/testsuite/tests/statmemprof/arrays_in_minor.ml index ec6131f19b24..4fb2013430d1 100644 --- a/testsuite/tests/statmemprof/arrays_in_minor.ml +++ b/testsuite/tests/statmemprof/arrays_in_minor.ml @@ -25,12 +25,12 @@ let[@inline never] allocate_arrays lo hi cnt keep = let check_nosample () = Printf.printf "check_nosample\n%!"; - let alloc _ = + let cb _ = Printf.printf "Callback called with sampling_rate = 0\n"; assert(false) in - start ~callstack_size:10 ~sampling_rate:0. - { null_tracker with alloc_minor = alloc; alloc_major = alloc }; + start ~callstack_size:10 ~minor_alloc_callback:cb ~major_alloc_callback:cb + ~sampling_rate:0. (); allocate_arrays 1 250 100 false; stop () @@ -44,28 +44,23 @@ let check_counts_full_major force_promote = let npromote = ref 0 in let ndealloc_minor = ref 0 in let ndealloc_major = ref 0 in - start ~callstack_size:10 ~sampling_rate:0.01 - { - alloc_minor = (fun info -> - if !enable then begin - incr nalloc_minor; if !nalloc_minor mod 100 = 0 then Gc.minor (); - Some (ref 42) - end else begin - allocate_arrays 1 250 1 true; - None - end); - alloc_major = (fun _ -> assert false); - promote = (fun k -> - assert (!k = 42 && !promotes_allowed); - incr npromote; if !npromote mod 1097 = 0 then Gc.minor (); - Some (ref 17)); - dealloc_minor = (fun k -> - assert (!k = 42); - incr ndealloc_minor); - dealloc_major = (fun r -> - assert (!r = 17); - incr ndealloc_major); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun info -> + if !enable then begin + incr nalloc_minor; if !nalloc_minor mod 100 = 0 then Gc.minor (); + Some (ref 42) + end else begin + allocate_arrays 1 250 1 true; + None + end) + ~major_alloc_callback:(fun _ -> assert false) + ~promote_callback:(fun k -> + assert (!k = 42 && !promotes_allowed); + incr npromote; if !npromote mod 1097 = 0 then Gc.minor (); + Some (ref 17)) + ~minor_dealloc_callback:(fun k -> assert (!k = 42); incr ndealloc_minor) + ~major_dealloc_callback:(fun r -> assert (!r = 17); incr ndealloc_major) + ~sampling_rate:0.01 (); allocate_arrays 1 250 100 true; enable := false; assert (!ndealloc_minor = 0 && !ndealloc_major = 0); @@ -105,14 +100,11 @@ let check_no_nested () = () in let cb' _ = cb (); Some () in - start ~callstack_size:10 ~sampling_rate:1. - { - alloc_minor = cb'; - alloc_major = cb'; - promote = cb'; - dealloc_minor = cb; - dealloc_major = cb; - }; + start ~callstack_size:10 + ~minor_alloc_callback:cb' ~major_alloc_callback:cb' + ~promote_callback:cb' ~minor_dealloc_callback:cb + ~major_dealloc_callback:cb + ~sampling_rate:1. (); allocate_arrays 1 250 5 false; stop () @@ -121,17 +113,16 @@ let () = check_no_nested () let check_distrib lo hi cnt rate = Printf.printf "check_distrib %d %d %d %f\n%!" lo hi cnt rate; let smp = ref 0 in - start ~callstack_size:10 ~sampling_rate:rate - { null_tracker with - alloc_major = (fun _ -> assert false); - alloc_minor = (fun info -> - assert (info.size >= lo && info.size <= hi); - assert (info.n_samples > 0); - assert (not info.unmarshalled); - smp := !smp + info.n_samples; - None - ); - }; + start ~callstack_size:10 + ~major_alloc_callback:(fun _ -> assert false) + ~minor_alloc_callback:(fun info -> + assert (info.size >= lo && info.size <= hi); + assert (info.n_samples > 0); + assert (not info.unmarshalled); + smp := !smp + info.n_samples; + None + ) + ~sampling_rate:rate (); allocate_arrays lo hi cnt false; stop (); diff --git a/testsuite/tests/statmemprof/blocking_in_callback.ml b/testsuite/tests/statmemprof/blocking_in_callback.ml index d5e8d2ce175b..b1562ba74f18 100644 --- a/testsuite/tests/statmemprof/blocking_in_callback.ml +++ b/testsuite/tests/statmemprof/blocking_in_callback.ml @@ -59,8 +59,11 @@ let rec go () = let () = let t = Thread.create go () in - Gc.Memprof.(start ~callstack_size:10 ~sampling_rate:1. - { null_tracker with alloc_minor = minor_alloc_callback; }); + Gc.Memprof.start + ~callstack_size:10 + ~minor_alloc_callback + ~major_alloc_callback:(fun _ -> None) + ~sampling_rate:1. (); Mutex.unlock mut; go (); Thread.join t; diff --git a/testsuite/tests/statmemprof/callstacks.ml b/testsuite/tests/statmemprof/callstacks.ml index c1064806f6e5..c921577ab89b 100644 --- a/testsuite/tests/statmemprof/callstacks.ml +++ b/testsuite/tests/statmemprof/callstacks.ml @@ -71,17 +71,16 @@ let allocators = let test alloc = Printf.printf "-----------\n%!"; let callstack = ref None in - start ~callstack_size:10 ~sampling_rate:1. - { null_tracker with - alloc_minor = (fun info -> - callstack := Some info.callstack; - None - ); - alloc_major = (fun info -> - callstack := Some info.callstack; - None - ); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun info -> + callstack := Some info.callstack; + None + ) + ~major_alloc_callback:(fun info -> + callstack := Some info.callstack; + None + ) + ~sampling_rate:1. (); alloc (); stop (); match !callstack with diff --git a/testsuite/tests/statmemprof/callstacks.reference b/testsuite/tests/statmemprof/callstacks.reference index bd0239d435c0..d5707751e659 100644 --- a/testsuite/tests/statmemprof/callstacks.reference +++ b/testsuite/tests/statmemprof/callstacks.reference @@ -1,74 +1,74 @@ ----------- Raised by primitive operation at file "callstacks.ml", line 11, characters 30-53 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 14, characters 30-76 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 19, characters 12-66 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 22, characters 30-60 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 25, characters 30-55 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 29, characters 12-62 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 32, characters 22-27 Called from file "callstacks.ml", line 34, characters 30-65 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 37, characters 30-69 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 40, characters 30-73 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 44, characters 30-43 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 47, characters 28-33 Called from file "callstacks.ml", line 49, characters 30-47 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "marshal.ml", line 61, characters 9-35 Called from file "callstacks.ml", line 55, characters 12-87 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 58, characters 30-59 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 ----------- Raised by primitive operation at file "callstacks.ml", line 61, characters 37-43 Called from file "callstacks.ml", line 63, characters 30-49 -Called from file "callstacks.ml", line 85, characters 2-10 +Called from file "callstacks.ml", line 84, characters 2-10 Called from file "list.ml", line 110, characters 12-15 -Called from file "callstacks.ml", line 92, characters 2-27 +Called from file "callstacks.ml", line 91, characters 2-27 diff --git a/testsuite/tests/statmemprof/comballoc.byte.reference b/testsuite/tests/statmemprof/comballoc.byte.reference index afbd1ed547c6..cb17fd093379 100644 --- a/testsuite/tests/statmemprof/comballoc.byte.reference +++ b/testsuite/tests/statmemprof/comballoc.byte.reference @@ -1,49 +1,49 @@ 2: 0.42 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.42 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.42 true Raised by primitive operation at file "comballoc.ml", line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 2: 0.01 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.01 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.01 true Raised by primitive operation at file "comballoc.ml", line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 2: 0.83 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.83 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.83 true Raised by primitive operation at file "comballoc.ml", line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 OK diff --git a/testsuite/tests/statmemprof/comballoc.ml b/testsuite/tests/statmemprof/comballoc.ml index f2998594415c..9d135f47c7b4 100644 --- a/testsuite/tests/statmemprof/comballoc.ml +++ b/testsuite/tests/statmemprof/comballoc.ml @@ -20,21 +20,20 @@ let test sampling_rate = let deallocs = Array.make 257 0 in let promotes = Array.make 257 0 in let callstacks = Array.make 257 None in - start ~callstack_size:10 ~sampling_rate - { null_tracker with - alloc_minor = (fun info -> - allocs.(info.size) <- allocs.(info.size) + info.n_samples; - begin match callstacks.(info.size) with - | None -> callstacks.(info.size) <- Some info.callstack - | Some s -> assert (s = info.callstack) - end; - Some (info.size, info.n_samples)); - dealloc_minor = (fun (sz,n) -> - deallocs.(sz) <- deallocs.(sz) + n); - promote = (fun (sz,n) -> - promotes.(sz) <- promotes.(sz) + n; - None); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun info -> + allocs.(info.size) <- allocs.(info.size) + info.n_samples; + begin match callstacks.(info.size) with + | None -> callstacks.(info.size) <- Some info.callstack + | Some s -> assert (s = info.callstack) + end; + Some (info.size, info.n_samples)) + ~minor_dealloc_callback:(fun (sz,n) -> + deallocs.(sz) <- deallocs.(sz) + n) + ~promote_callback:(fun (sz,n) -> + promotes.(sz) <- promotes.(sz) + n; + None) + ~sampling_rate (); let iter = 100_000 in let arr = Array.make iter (0,0,0,0) in for i = 0 to Array.length arr - 1 do @@ -74,17 +73,17 @@ let () = let no_callback_after_stop trigger = let stopped = ref false in let cnt = ref 0 in - start ~callstack_size:0 ~sampling_rate:1. - { null_tracker with - alloc_minor = (fun info -> - assert(not !stopped); - incr cnt; - if !cnt > trigger then begin - stop (); - stopped := true - end; - None); - }; + start ~callstack_size:0 + ~minor_alloc_callback:(fun info -> + assert(not !stopped); + incr cnt; + if !cnt > trigger then begin + stop (); + stopped := true + end; + None + ) + ~sampling_rate:1. (); for i = 0 to 1000 do ignore (Sys.opaque_identity f i) done; assert !stopped diff --git a/testsuite/tests/statmemprof/comballoc.opt.reference b/testsuite/tests/statmemprof/comballoc.opt.reference index 3c7eb6c09af1..073747c99391 100644 --- a/testsuite/tests/statmemprof/comballoc.opt.reference +++ b/testsuite/tests/statmemprof/comballoc.opt.reference @@ -1,49 +1,49 @@ 2: 0.42 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.42 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.42 true Raised by primitive operation at file "comballoc.ml" (inlined), line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 2: 0.01 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.01 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.01 true Raised by primitive operation at file "comballoc.ml" (inlined), line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 2: 0.83 false Raised by primitive operation at file "comballoc.ml", line 16, characters 2-19 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 3: 0.83 false Raised by primitive operation at file "comballoc.ml", line 16, characters 6-18 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 4: 0.83 true Raised by primitive operation at file "comballoc.ml" (inlined), line 13, characters 11-20 Called from file "comballoc.ml", line 16, characters 13-17 -Called from file "comballoc.ml", line 41, characters 25-48 +Called from file "comballoc.ml", line 40, characters 25-48 Called from file "list.ml", line 110, characters 12-15 -Called from file "comballoc.ml", line 71, characters 2-35 +Called from file "comballoc.ml", line 70, characters 2-35 OK diff --git a/testsuite/tests/statmemprof/exception_callback.ml b/testsuite/tests/statmemprof/exception_callback.ml index 55dd5e555cbb..3280c778b009 100644 --- a/testsuite/tests/statmemprof/exception_callback.ml +++ b/testsuite/tests/statmemprof/exception_callback.ml @@ -4,12 +4,6 @@ open Gc.Memprof -let alloc_tracker on_alloc = - { null_tracker with - alloc_minor = (fun info -> on_alloc info; None); - alloc_major = (fun info -> on_alloc info; None); - } - (* We don't want to print the backtrace. We just want to make sure the exception is printed. This also makes sure [Printexc] is loaded, otherwise we don't use @@ -17,7 +11,9 @@ let alloc_tracker on_alloc = let _ = Printexc.record_backtrace false let _ = - start ~callstack_size:10 ~sampling_rate:1. - (alloc_tracker (fun _ -> failwith "callback failed")); + start ~callstack_size:10 + ~minor_alloc_callback:(fun _ -> assert false) + ~major_alloc_callback:(fun _ -> assert false) + ~sampling_rate:1. (); ignore (Sys.opaque_identity (Array.make 200 0)); stop () diff --git a/testsuite/tests/statmemprof/exception_callback.reference b/testsuite/tests/statmemprof/exception_callback.reference index 6371f8249e29..b389da5b1fd2 100644 --- a/testsuite/tests/statmemprof/exception_callback.reference +++ b/testsuite/tests/statmemprof/exception_callback.reference @@ -1 +1 @@ -Fatal error: exception Failure("callback failed") +Fatal error: exception File "exception_callback.ml", line 15, characters 40-46: Assertion failed diff --git a/testsuite/tests/statmemprof/exception_callback_minor.ml b/testsuite/tests/statmemprof/exception_callback_minor.ml index f51412327643..0b1f59ff50bf 100644 --- a/testsuite/tests/statmemprof/exception_callback_minor.ml +++ b/testsuite/tests/statmemprof/exception_callback_minor.ml @@ -11,10 +11,9 @@ open Gc.Memprof let _ = Printexc.record_backtrace false let _ = - start ~callstack_size:10 ~sampling_rate:1. - { null_tracker with - alloc_minor = (fun _ -> assert false); - alloc_major = (fun _ -> assert false); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun _ -> assert false) + ~major_alloc_callback:(fun _ -> assert false) + ~sampling_rate:1. (); ignore (Sys.opaque_identity (ref (ref 42))); stop () diff --git a/testsuite/tests/statmemprof/exception_callback_minor.reference b/testsuite/tests/statmemprof/exception_callback_minor.reference index af75fbbe9b2b..63e3b54836cc 100644 --- a/testsuite/tests/statmemprof/exception_callback_minor.reference +++ b/testsuite/tests/statmemprof/exception_callback_minor.reference @@ -1 +1 @@ -Fatal error: exception File "exception_callback_minor.ml", line 16, characters 30-36: Assertion failed +Fatal error: exception File "exception_callback_minor.ml", line 15, characters 40-46: Assertion failed diff --git a/testsuite/tests/statmemprof/intern.ml b/testsuite/tests/statmemprof/intern.ml index 5a5ff558e383..2a0173f8967d 100644 --- a/testsuite/tests/statmemprof/intern.ml +++ b/testsuite/tests/statmemprof/intern.ml @@ -7,12 +7,6 @@ open Gc.Memprof -let alloc_tracker on_alloc = - { null_tracker with - alloc_minor = (fun info -> on_alloc info; None); - alloc_major = (fun info -> on_alloc info; None); - } - type t = I of int | II of int * int | Cons of t let rec t_of_len = function | len when len <= 1 -> assert false @@ -41,11 +35,12 @@ let[@inline never] do_intern lo hi cnt keep = let check_nosample () = Printf.printf "check_nosample\n%!"; precompute_marshalled_data 2 3000; - let fail_on_alloc _ = + let cb _ = Printf.printf "Callback called with sampling_rate = 0\n"; assert(false) in - start ~callstack_size:10 ~sampling_rate:0. (alloc_tracker fail_on_alloc); + start ~callstack_size:10 ~minor_alloc_callback:cb ~major_alloc_callback:cb + ~sampling_rate:0. (); do_intern 2 3000 1 false; stop () @@ -60,26 +55,25 @@ let check_counts_full_major force_promote = let npromote = ref 0 in let ndealloc_minor = ref 0 in let ndealloc_major = ref 0 in - start ~callstack_size:10 ~sampling_rate:0.01 - { - alloc_minor = (fun _ -> - if not !enable then None - else Some (incr nalloc_minor) - ); - alloc_major = (fun _ -> - if not !enable then None - else Some (incr nalloc_major) - ); - promote = (fun _ -> - Some (incr npromote) - ); - dealloc_minor = (fun _ -> - incr ndealloc_minor - ); - dealloc_major = (fun _ -> - incr ndealloc_major - ); - }; + start ~callstack_size:10 + ~minor_alloc_callback:(fun _ -> + if !enable then begin + incr nalloc_minor; + Some () + end else + None) + ~major_alloc_callback:(fun _ -> + if !enable then begin + incr nalloc_major; + Some () + end else + None) + ~promote_callback:(fun _ -> + incr npromote; + Some ()) + ~minor_dealloc_callback:(fun _ -> incr ndealloc_minor) + ~major_dealloc_callback:(fun _ -> incr ndealloc_major) + ~sampling_rate:0.01 (); do_intern 2 3000 1 true; enable := false; assert (!ndealloc_minor = 0 && !ndealloc_major = 0); @@ -117,14 +111,11 @@ let check_no_nested () = () in let cb' _ = cb (); Some () in - start ~callstack_size:10 ~sampling_rate:1. - { - alloc_minor = cb'; - alloc_major = cb'; - promote = cb'; - dealloc_minor = cb; - dealloc_major = cb; - }; + start ~callstack_size:10 + ~minor_alloc_callback:cb' ~major_alloc_callback:cb' + ~promote_callback:cb' ~minor_dealloc_callback:cb + ~major_dealloc_callback:cb + ~sampling_rate:1. (); do_intern 100 200 1 false; stop () @@ -134,7 +125,7 @@ let check_distrib lo hi cnt rate = Printf.printf "check_distrib %d %d %d %f\n%!" lo hi cnt rate; precompute_marshalled_data lo hi; let smp = ref 0 in - let alloc info = + let cb info = (* We also allocate the list constructor in the minor heap, so we filter that out. *) if info.unmarshalled then begin @@ -142,8 +133,10 @@ let check_distrib lo hi cnt rate = assert (info.n_samples > 0); smp := !smp + info.n_samples end; + None in - start ~callstack_size:10 ~sampling_rate:rate (alloc_tracker alloc); + start ~callstack_size:10 ~major_alloc_callback:cb ~minor_alloc_callback:cb + ~sampling_rate:rate (); do_intern lo hi cnt false; stop (); diff --git a/testsuite/tests/statmemprof/lists_in_minor.ml b/testsuite/tests/statmemprof/lists_in_minor.ml index 7a3736a21f7f..8aaae3e545f4 100644 --- a/testsuite/tests/statmemprof/lists_in_minor.ml +++ b/testsuite/tests/statmemprof/lists_in_minor.ml @@ -19,16 +19,15 @@ let[@inline never] allocate_lists len cnt = let check_distrib len cnt rate = Printf.printf "check_distrib %d %d %f\n%!" len cnt rate; let smp = ref 0 in - start ~callstack_size:10 ~sampling_rate:rate - { null_tracker with - alloc_major = (fun _ -> assert false); - alloc_minor = (fun info -> - assert (info.size = 2); - assert (info.n_samples > 0); - assert (not info.unmarshalled); - smp := !smp + info.n_samples; - None); - }; + start ~callstack_size:10 + ~major_alloc_callback:(fun _ -> assert false) + ~minor_alloc_callback:(fun info -> + assert (info.size = 2); + assert (info.n_samples > 0); + assert (not info.unmarshalled); + smp := !smp + info.n_samples; + None) + ~sampling_rate:rate (); allocate_lists len cnt; stop (); diff --git a/testsuite/tests/statmemprof/minor_no_postpone.ml b/testsuite/tests/statmemprof/minor_no_postpone.ml index 9d9ecd7917ef..cd5f0e7298ae 100644 --- a/testsuite/tests/statmemprof/minor_no_postpone.ml +++ b/testsuite/tests/statmemprof/minor_no_postpone.ml @@ -4,19 +4,15 @@ open Gc.Memprof -let notify_minor ref_ok ref_done = - { null_tracker with - alloc_minor = (fun _ -> - assert !ref_ok; - ref_done := true; - None); - } - let () = let callback_ok = ref true in let callback_done = ref false in - start ~callstack_size:0 ~sampling_rate:1. - (notify_minor callback_ok callback_done); + start ~callstack_size:0 + ~minor_alloc_callback:(fun _ -> + assert !callback_ok; + callback_done := true; + None) + ~sampling_rate:1. (); ignore (Sys.opaque_identity (ref 0)); assert(!callback_done); callback_ok := false; @@ -27,8 +23,12 @@ external alloc_stub : unit -> unit ref = "alloc_stub" let () = let callback_ok = ref false in let callback_done = ref false in - start ~callstack_size:0 ~sampling_rate:1. - (notify_minor callback_ok callback_done); + start ~callstack_size:0 + ~minor_alloc_callback:(fun _ -> + assert !callback_ok; + callback_done := true; + None) + ~sampling_rate:1. (); ignore (Sys.opaque_identity (alloc_stub ())); assert(not !callback_done); callback_ok := true;