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
94
95
open! Core
open Memtrace_viewer_common
type t =
{ trace : Memtrace.Trace.Reader.t
; info : Data.Info.t
}
let time_ns_of_memtrace_timestamp ts =
Int64.(1000L * (ts |> Memtrace.Trace.Timestamp.to_int64))
|> Int63.of_int64_exn
|> Time_ns.of_int63_ns_since_epoch
;;
let info_of_trace_info
{ Memtrace.Trace.Info.sample_rate
; word_size
; executable_name
; host_name
; ocaml_runtime_params
; pid
; start_time
; context
}
=
{ Data.Info.sample_rate
; word_size = word_size / 8 |> Byte_units.of_bytes_int
; executable_name
; host_name
; ocaml_runtime_params
; pid
; start_time = start_time |> time_ns_of_memtrace_timestamp
; context
}
;;
let time_span_of_timedelta time =
let us = time |> Memtrace.Trace.Timedelta.to_int64 in
Int64.(us * 1000L) |> Int63.of_int64_exn |> Time_ns.Span.of_int63_ns
;;
let info t = t.info
let bytes_of_words t words = Byte_units.scale t.info.word_size words
let bytes_of_int_words t words = bytes_of_words t (words |> Float.of_int)
let bytes_of_nsamples t nsamples =
let words = Float.of_int nsamples /. t.info.sample_rate in
bytes_of_words t words
;;
module Event = struct
type t = Location.Code.t Event.t [@@deriving sexp_of]
let of_memtrace_event trace (event : Memtrace.Trace.Event.t) : t =
match event with
| Alloc
{ obj_id
; length
; nsamples
; source
; backtrace_buffer
; backtrace_length
; common_prefix
} ->
let single_allocation_size = length |> bytes_of_int_words trace in
let size = nsamples |> bytes_of_nsamples trace in
Alloc
{ obj_id
; source
; single_allocation_size
; nsamples
; size
; backtrace_buffer
; backtrace_length
; common_prefix
}
| Promote obj_id -> Promote obj_id
| Collect obj_id -> Collect obj_id
;;
end
let of_memtrace_trace trace =
let info = Memtrace.Trace.Reader.info trace |> info_of_trace_info in
{ trace; info }
;;
let iter t ~parse_backtraces f =
let last_time = ref Time_ns.Span.zero in
Memtrace.Trace.Reader.iter t.trace ~parse_backtraces (fun time event ->
let time = time |> time_span_of_timedelta in
let event = event |> Event.of_memtrace_event t in
last_time := time;
f time event);
f !last_time End
;;