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
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
|