|
|
|
@ -14,15 +14,18 @@ let read filename =
|
|
|
|
|
List.iter sexps ~f:(fun sexp ->
|
|
|
|
|
let {Report.name; entry} = Report.t_of_sexp sexp in
|
|
|
|
|
match (Tbl.find_opt tbl name, entry) with
|
|
|
|
|
| None, ProcessTimes ptimes -> Tbl.replace tbl name ([ptimes], [], [])
|
|
|
|
|
| None, GcStats gc -> Tbl.replace tbl name ([], [gc], [])
|
|
|
|
|
| None, Status status -> Tbl.replace tbl name ([], [], [status])
|
|
|
|
|
| Some (times, gcs, statuses), ProcessTimes ptimes ->
|
|
|
|
|
Tbl.replace tbl name (ptimes :: times, gcs, statuses)
|
|
|
|
|
| Some (times, gcs, statuses), GcStats gc ->
|
|
|
|
|
Tbl.replace tbl name (times, gc :: gcs, statuses)
|
|
|
|
|
| Some (times, gc, statuses), Status status ->
|
|
|
|
|
Tbl.replace tbl name (times, gc, status :: statuses) ) ;
|
|
|
|
|
| None, ProcessTimes t -> Tbl.replace tbl name ([t], [], [], [])
|
|
|
|
|
| None, GcStats g -> Tbl.replace tbl name ([], [g], [], [])
|
|
|
|
|
| None, Coverage c -> Tbl.replace tbl name ([], [], [c], [])
|
|
|
|
|
| None, Status s -> Tbl.replace tbl name ([], [], [], [s])
|
|
|
|
|
| Some (times, gcs, coverages, statuses), ProcessTimes ptimes ->
|
|
|
|
|
Tbl.replace tbl name (ptimes :: times, gcs, coverages, statuses)
|
|
|
|
|
| Some (times, gcs, coverages, statuses), GcStats gc ->
|
|
|
|
|
Tbl.replace tbl name (times, gc :: gcs, coverages, statuses)
|
|
|
|
|
| Some (times, gcs, coverages, statuses), Coverage c ->
|
|
|
|
|
Tbl.replace tbl name (times, gcs, c :: coverages, statuses)
|
|
|
|
|
| Some (times, gc, coverages, statuses), Status status ->
|
|
|
|
|
Tbl.replace tbl name (times, gc, coverages, status :: statuses) ) ;
|
|
|
|
|
tbl
|
|
|
|
|
|
|
|
|
|
type times = {etime: float; utime: float; stime: float}
|
|
|
|
@ -33,6 +36,8 @@ type ('t, 'g) row =
|
|
|
|
|
; times_deltas: 't
|
|
|
|
|
; gcs: 'g
|
|
|
|
|
; gcs_deltas: 'g
|
|
|
|
|
; cov: Report.coverage list
|
|
|
|
|
; cov_deltas: Report.coverage list option
|
|
|
|
|
; status: Report.status list
|
|
|
|
|
; status_deltas: Report.status list option }
|
|
|
|
|
|
|
|
|
@ -75,6 +80,27 @@ let add_gcs base_gcs gcs row =
|
|
|
|
|
if List.is_empty gcs then {row with gcs_deltas= Option.to_list base_gcs}
|
|
|
|
|
else List.fold ~f:(add_gc base_gcs) gcs row
|
|
|
|
|
|
|
|
|
|
let add_cov base_cov cov row =
|
|
|
|
|
if List.mem ~eq:Report.equal_coverage cov row.cov then row
|
|
|
|
|
else
|
|
|
|
|
let cov_deltas =
|
|
|
|
|
match base_cov with
|
|
|
|
|
| Some (base_cov :: _) ->
|
|
|
|
|
let covd =
|
|
|
|
|
Report.
|
|
|
|
|
{ steps= cov.steps - base_cov.steps
|
|
|
|
|
; hit= cov.hit - base_cov.hit
|
|
|
|
|
; fraction= cov.fraction -. base_cov.fraction }
|
|
|
|
|
in
|
|
|
|
|
Some (covd :: Option.value row.cov_deltas ~default:[])
|
|
|
|
|
| _ -> None
|
|
|
|
|
in
|
|
|
|
|
{row with cov= cov :: row.cov; cov_deltas}
|
|
|
|
|
|
|
|
|
|
let add_covs base_cov covs row =
|
|
|
|
|
let row = List.fold ~f:(add_cov base_cov) covs row in
|
|
|
|
|
{row with cov= List.sort ~cmp:(Ord.opp Report.compare_coverage) row.cov}
|
|
|
|
|
|
|
|
|
|
let add_status base_status status row =
|
|
|
|
|
if List.mem ~eq:Report.equal_status status row.status then row
|
|
|
|
|
else
|
|
|
|
@ -103,9 +129,9 @@ let ave_floats flts =
|
|
|
|
|
else sum /. Float.of_int num
|
|
|
|
|
|
|
|
|
|
let combine name b_result c_result =
|
|
|
|
|
let base_times, base_gcs, base_status =
|
|
|
|
|
let base_times, base_gcs, base_cov, base_status =
|
|
|
|
|
match b_result with
|
|
|
|
|
| Some (times, gcs, statuses) ->
|
|
|
|
|
| Some (times, gcs, covs, statuses) ->
|
|
|
|
|
let times =
|
|
|
|
|
if List.is_empty times then None
|
|
|
|
|
else
|
|
|
|
@ -149,11 +175,12 @@ let combine name b_result c_result =
|
|
|
|
|
; promoted= ave_floats promos
|
|
|
|
|
; peak_size= ave_floats peaks }
|
|
|
|
|
in
|
|
|
|
|
let covs = if List.is_empty covs then None else Some covs in
|
|
|
|
|
let status =
|
|
|
|
|
Some (List.sort_uniq ~cmp:Report.compare_status statuses)
|
|
|
|
|
in
|
|
|
|
|
(times, gcs, status)
|
|
|
|
|
| None -> (None, None, None)
|
|
|
|
|
(times, gcs, covs, status)
|
|
|
|
|
| None -> (None, None, None, None)
|
|
|
|
|
in
|
|
|
|
|
let row =
|
|
|
|
|
{ name
|
|
|
|
@ -161,6 +188,8 @@ let combine name b_result c_result =
|
|
|
|
|
; times_deltas= []
|
|
|
|
|
; gcs= []
|
|
|
|
|
; gcs_deltas= []
|
|
|
|
|
; cov= []
|
|
|
|
|
; cov_deltas= None
|
|
|
|
|
; status= []
|
|
|
|
|
; status_deltas= None }
|
|
|
|
|
in
|
|
|
|
@ -168,12 +197,14 @@ let combine name b_result c_result =
|
|
|
|
|
| None ->
|
|
|
|
|
let times_deltas = Option.to_list base_times in
|
|
|
|
|
let gcs_deltas = Option.to_list base_gcs in
|
|
|
|
|
let cov_deltas = base_cov in
|
|
|
|
|
let status_deltas = base_status in
|
|
|
|
|
{row with times_deltas; gcs_deltas; status_deltas}
|
|
|
|
|
| Some (c_times, c_gcs, c_statuses) ->
|
|
|
|
|
{row with times_deltas; gcs_deltas; cov_deltas; status_deltas}
|
|
|
|
|
| Some (c_times, c_gcs, c_cov, c_statuses) ->
|
|
|
|
|
row
|
|
|
|
|
|> add_times base_times c_times
|
|
|
|
|
|> add_gcs base_gcs c_gcs
|
|
|
|
|
|> add_covs base_cov c_cov
|
|
|
|
|
|> add_statuses base_status c_statuses
|
|
|
|
|
|
|
|
|
|
type ranges =
|
|
|
|
@ -258,7 +289,8 @@ let color max dat =
|
|
|
|
|
Printf.sprintf "#%2x%2x%2x" (to_int r) (to_int g) (to_int b)
|
|
|
|
|
in
|
|
|
|
|
let rat = dat /. max in
|
|
|
|
|
if Float.is_nan rat then rgb_to_hex lace else rgb_to_hex (gradient rat)
|
|
|
|
|
if Float.(abs dat < 0.000001 || is_nan rat) then rgb_to_hex lace
|
|
|
|
|
else rgb_to_hex (gradient rat)
|
|
|
|
|
|
|
|
|
|
let write_html ranges rows chan =
|
|
|
|
|
let pf fmt = Printf.fprintf chan fmt in
|
|
|
|
@ -295,11 +327,24 @@ let write_html ranges rows chan =
|
|
|
|
|
<th>Δ%%<br></th>
|
|
|
|
|
<th>Status</th>
|
|
|
|
|
<th>Δ<br></th>
|
|
|
|
|
<th>Steps</th>
|
|
|
|
|
<th>Δ<br></th>
|
|
|
|
|
<th>Cover</th>
|
|
|
|
|
<th>%%</th>
|
|
|
|
|
<th>Δ<br></th>
|
|
|
|
|
<th>Δ%%<br></th>
|
|
|
|
|
</tr>|} ;
|
|
|
|
|
pf "\n" ;
|
|
|
|
|
Iter.iter rows ~f:(fun row ->
|
|
|
|
|
let {name; times; times_deltas; gcs; gcs_deltas; status; status_deltas}
|
|
|
|
|
=
|
|
|
|
|
let { name
|
|
|
|
|
; times
|
|
|
|
|
; times_deltas
|
|
|
|
|
; gcs
|
|
|
|
|
; gcs_deltas
|
|
|
|
|
; cov
|
|
|
|
|
; cov_deltas
|
|
|
|
|
; status
|
|
|
|
|
; status_deltas } =
|
|
|
|
|
row
|
|
|
|
|
in
|
|
|
|
|
let max_name_length = 50 in
|
|
|
|
@ -354,6 +399,41 @@ let write_html ranges rows chan =
|
|
|
|
|
let status_to_string = Format.asprintf "%a" Report.pp_status in
|
|
|
|
|
Printf.fprintf ppf "%s" (String.take 50 (status_to_string s))
|
|
|
|
|
in
|
|
|
|
|
let steps attr ppf = function
|
|
|
|
|
| [] -> Printf.fprintf ppf "<td %s></td>\n" attr
|
|
|
|
|
| cs ->
|
|
|
|
|
List.iter cs ~f:(fun {Report.steps} ->
|
|
|
|
|
if steps = 0 then Printf.fprintf ppf "<td></td>\n"
|
|
|
|
|
else
|
|
|
|
|
Printf.fprintf ppf "<td %s align=\"right\">%i</td>\n" attr
|
|
|
|
|
steps )
|
|
|
|
|
in
|
|
|
|
|
let hit attr ppf = function
|
|
|
|
|
| [] -> Printf.fprintf ppf "<td %s></td>\n" attr
|
|
|
|
|
| cs ->
|
|
|
|
|
List.iter cs ~f:(fun {Report.hit} ->
|
|
|
|
|
if hit = 0 then Printf.fprintf ppf "<td></td>\n"
|
|
|
|
|
else
|
|
|
|
|
Printf.fprintf ppf "<td %s align=\"right\">%i</td>\n" attr
|
|
|
|
|
hit )
|
|
|
|
|
in
|
|
|
|
|
let coverage attr ppf = function
|
|
|
|
|
| [] -> Printf.fprintf ppf "<td align=\"right\"></td>\n"
|
|
|
|
|
| cs ->
|
|
|
|
|
List.iter cs ~f:(fun {Report.fraction} ->
|
|
|
|
|
if Float.(abs fraction < 0.000001) then
|
|
|
|
|
Printf.fprintf ppf "<td></td>\n"
|
|
|
|
|
else
|
|
|
|
|
Printf.fprintf ppf
|
|
|
|
|
"<td %s align=\"right\">%12.0f%%</td>\n" attr
|
|
|
|
|
(Base.Float.round_decimal ~decimal_digits:2
|
|
|
|
|
(100. *. fraction)) )
|
|
|
|
|
in
|
|
|
|
|
let coveraged coverage ppf cs =
|
|
|
|
|
let cs = Option.value cs ~default:[] in
|
|
|
|
|
let attr = if List.is_empty cs then "" else " class=\"neutral\"" in
|
|
|
|
|
Printf.fprintf ppf "%a" (coverage attr) cs
|
|
|
|
|
in
|
|
|
|
|
let stat ppf = function
|
|
|
|
|
| [] ->
|
|
|
|
|
Printf.fprintf ppf
|
|
|
|
@ -437,6 +517,13 @@ let write_html ranges rows chan =
|
|
|
|
|
<td style=\"border-left: 2px solid \
|
|
|
|
|
#eee8d5\";></td><td></td><td></td>\n" ) ;
|
|
|
|
|
pf "%a%a" stat status statd status_deltas ;
|
|
|
|
|
pf "%a%a"
|
|
|
|
|
(steps " style=\"border-left: 2px solid #eee8d5\";")
|
|
|
|
|
cov (coveraged steps) cov_deltas ;
|
|
|
|
|
pf "%a%a"
|
|
|
|
|
(hit " style=\"border-left: 2px solid #eee8d5\";")
|
|
|
|
|
cov (coverage "") cov ;
|
|
|
|
|
pf "%a%a" (coveraged hit) cov_deltas (coveraged coverage) cov_deltas ;
|
|
|
|
|
pf "</tr>\n" ) ;
|
|
|
|
|
pf "<table>\n" ;
|
|
|
|
|
pf "</body></html>\n"
|
|
|
|
@ -488,6 +575,8 @@ let add_total rows =
|
|
|
|
|
; times_deltas= Some {etime= 0.; utime= 0.; stime= 0.}
|
|
|
|
|
; gcs= Some {Report.allocated= 0.; promoted= 0.; peak_size= 0.}
|
|
|
|
|
; gcs_deltas= Some {Report.allocated= 0.; promoted= 0.; peak_size= 0.}
|
|
|
|
|
; cov= []
|
|
|
|
|
; cov_deltas= None
|
|
|
|
|
; status= []
|
|
|
|
|
; status_deltas= None }
|
|
|
|
|
in
|
|
|
|
|