You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.8 KiB

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module L = Logging
module PerfProfilerDataMap = Caml.Map.Make (struct
type t = Typ.Procname.t
let compare = Typ.Procname.compare
end)
let global_perf_profiler_data : Perf_profiler_t.perf_profiler_item PerfProfilerDataMap.t ref =
ref PerfProfilerDataMap.empty
let split_class_method_name =
let class_sep = String.Search_pattern.create "::" in
fun qualified_method_name ->
match String.Search_pattern.index class_sep ~in_:qualified_method_name with
| Some class_sep_pos ->
let class_name =
String.sub qualified_method_name ~pos:0 ~len:class_sep_pos
|> String.tr ~target:'/' ~replacement:'.'
in
let method_name =
let prefix_len = class_sep_pos + 2 in
String.sub qualified_method_name ~pos:prefix_len
~len:(String.length qualified_method_name - prefix_len)
in
Some (class_name, method_name)
| _ ->
None
let pp_perf_profiler_item itm =
let open Perf_profiler_t in
L.(debug Analysis Medium)
"@\n\n\
\ [Perf Profiler Log] Function: '%s' @\n\
\ count trace id = %i @\n\
\ sum inclusive cpu time = %f@\n\
\ avg inclusive time = %f @\n\
\ sum exclusive cpu time = %f @\n\
\ avg exclusive_time = %f @\n\
\ inclusive p90 = %f @\n\
\ exclusive p90 = %f @\n\
\ inclusive p50 = %f @\n\
\ exclusive p50 = %f @\n\
\ inclusive p25 = %f @\n\
\ exclusive p25 = %f @\n"
itm.function_name itm.count_trace_id itm.sum_inclusive_cpu_time itm.avg_inclusive_cpu_time_ms
itm.sum_exclusive_cpu_time itm.avg_exclusive_cpu_time_ms itm.p90_inclusive_cpu_time_ms
itm.p90_exclusive_cpu_time_ms itm.p50_inclusive_cpu_time_ms itm.p50_exclusive_cpu_time_ms
itm.p25_inclusive_cpu_time_ms itm.p25_exclusive_cpu_time_ms
let make_void_signature_procname classname methodname =
let signature = JavaProfilerSamples.JNI.void_method_with_no_arguments in
L.(debug Analysis Medium)
"@\n Making procname with void signature for classname = %s methodname = %s @\n" classname
methodname ;
let procname = JavaProfilerSamples.create_procname ~classname ~methodname ~signature in
L.(debug Analysis Medium) " Resulting procname= %a @\n" Typ.Procname.pp procname ;
procname
let _read_file_perf_data fname =
let perf_profiler_data_str =
match Utils.read_file fname with
| Ok l ->
List.map ~f:Perf_profiler_j.perf_profiler_of_string l
| Error error ->
L.user_error "Failed to read file '%s': %s@." fname error ;
[]
in
let do_item itm =
pp_perf_profiler_item itm ;
match split_class_method_name itm.Perf_profiler_t.function_name with
| Some (classname, methodname) ->
let procname = make_void_signature_procname classname methodname in
global_perf_profiler_data :=
PerfProfilerDataMap.add procname itm !global_perf_profiler_data
| _ ->
()
in
List.iter ~f:(fun items -> List.iter ~f:do_item items) perf_profiler_data_str
let read_file_flag = ref false
let in_profiler_data_map key =
match Config.perf_profiler_data_file with
| Some fname ->
if not !read_file_flag then (
_read_file_perf_data fname ;
read_file_flag := true ) ;
if PerfProfilerDataMap.is_empty !global_perf_profiler_data then
L.(debug Analysis Medium) "@\n\n[Perf Profiler Log] WARNING: EMPTY PERF PROFILER DATA@\n" ;
PerfProfilerDataMap.mem key !global_perf_profiler_data
| _ ->
false