From 266ae2ed6ef393c6768440fe2e57dd97fe9117f4 Mon Sep 17 00:00:00 2001 From: Varun Arora Date: Wed, 14 Mar 2018 09:09:48 -0700 Subject: [PATCH] [reporting][perf] designate frontend perf stats as either Capture or Linters in EventLogger Summary: - Rather than passing a directory name to PerfStats reporting api to write the stats to, and then determining the EventLogger `stats_type` from that dirname, there is now a `stats_type` type in PerfStats, and the directory name and EventLogger tag is automatically determined from that type after it is passed to the API - This allows us to determine whether we're in capture mode or linters mode dynamically from PerfStats itself, and use the appropriate tag when creating an event Reviewed By: dulmarod Differential Revision: D7251580 fbshipit-source-id: 0dec071 --- infer/src/backend/InferPrint.ml | 2 +- infer/src/backend/PerfStats.ml | 65 +++++++++++++++++++++++++++++---- infer/src/backend/PerfStats.mli | 14 ++++++- infer/src/backend/callbacks.ml | 2 +- infer/src/clang/Capture.ml | 13 ++++++- infer/src/integration/Driver.ml | 2 +- infer/src/java/jMain.ml | 2 +- 7 files changed, 85 insertions(+), 15 deletions(-) diff --git a/infer/src/backend/InferPrint.ml b/infer/src/backend/InferPrint.ml index 18123a8cb..c8a98ff73 100644 --- a/infer/src/backend/InferPrint.ml +++ b/infer/src/backend/InferPrint.ml @@ -868,7 +868,7 @@ let get_summary_iterator () = let register_perf_stats_report () = let filename = F.sprintf "%s.json" Config.perf_stats_prefix in - PerfStats.register_report_at_exit filename Config.reporting_stats_dir_name + PerfStats.register_report_at_exit filename PerfStats.Reporting (** Although the out_file is an Option type, the None option is strictly meant for the diff --git a/infer/src/backend/PerfStats.ml b/infer/src/backend/PerfStats.ml index 81462a6f5..d324a25f2 100644 --- a/infer/src/backend/PerfStats.ml +++ b/infer/src/backend/PerfStats.ml @@ -30,6 +30,54 @@ type perf_stats = ; stack_kb: float ; minor_heap_kb: float } +type stats_type = + | ClangLinters + | ClangFrontend + | ClangFrontendLinters + | JavaFrontend + | PythonFrontend + | Backend + | Reporting + | Driver + +let dirname_of_stats_type = function + | ClangLinters -> + Config.frontend_stats_dir_name + | ClangFrontend -> + Config.frontend_stats_dir_name + | ClangFrontendLinters -> + Config.frontend_stats_dir_name + | JavaFrontend -> + Config.frontend_stats_dir_name + | PythonFrontend -> + Config.frontend_stats_dir_name + | Backend -> + Config.backend_stats_dir_name + | Reporting -> + Config.reporting_stats_dir_name + | Driver -> + Config.driver_stats_dir_name + + +let string_of_stats_type = function + | ClangLinters -> + "linters" + | ClangFrontend -> + "clang_frontend" + | ClangFrontendLinters -> + "clang_frontend_and_linters" + | JavaFrontend -> + "java_frontend" + | PythonFrontend -> + "python_frontend" + | Backend -> + "backend" + | Reporting -> + "reporting" + | Driver -> + "driver" + + let to_json ps = `Assoc [ ("rtime", `Float ps.rtime) @@ -141,7 +189,7 @@ let stats source_file stats_type = EventLogger.PerformanceStats { lang= Language.to_explicit_string !Language.curr_language ; source_file - ; stats_type + ; stats_type= string_of_stats_type stats_type ; real_time= rtime ; user_time= utime ; sys_time= stime @@ -185,19 +233,20 @@ let report file source_file stats_type () = let registered_files = ref String.Set.empty -let handle_report filename ?source_file dirname ~f = +let handle_report filename ?source_file stats_type ~f = + let dirname = dirname_of_stats_type stats_type in let relative_path = Filename.concat dirname filename in let absolute_path = Filename.concat Config.results_dir relative_path in (* make sure to not double register the same perf stat report *) if not (String.Set.mem !registered_files relative_path) then ( registered_files := String.Set.add !registered_files relative_path ; - f (report absolute_path source_file dirname) ) + f (report absolute_path source_file stats_type) relative_path ) -let report_now filename ?source_file dirname = - handle_report filename ?source_file dirname ~f:(fun report_f -> report_f ()) +let report_now filename ?source_file stats_type = + handle_report filename ?source_file stats_type ~f:(fun report _ -> report ()) -let register_report_at_exit filename ?source_file dirname = - handle_report filename ?source_file dirname ~f:(fun report_f -> - Epilogues.register ~f:report_f ("stats reporting in " ^ Filename.concat dirname filename) ) +let register_report_at_exit filename ?source_file stats_type = + handle_report filename ?source_file stats_type ~f:(fun report relative_path -> + Epilogues.register ~f:report ("stats reporting in " ^ relative_path) ) diff --git a/infer/src/backend/PerfStats.mli b/infer/src/backend/PerfStats.mli index 28cdfad38..726573199 100644 --- a/infer/src/backend/PerfStats.mli +++ b/infer/src/backend/PerfStats.mli @@ -13,12 +13,22 @@ open! IStd type perf_stats +type stats_type = + | ClangLinters + | ClangFrontend + | ClangFrontendLinters + | JavaFrontend + | PythonFrontend + | Backend + | Reporting + | Driver + val from_json : Yojson.Basic.json -> perf_stats val aggregate : perf_stats list -> Yojson.Basic.json -val report_now : string -> ?source_file:SourceFile.t -> string -> unit +val report_now : string -> ?source_file:SourceFile.t -> stats_type -> unit (** Create performance report immediately *) -val register_report_at_exit : string -> ?source_file:SourceFile.t -> string -> unit +val register_report_at_exit : string -> ?source_file:SourceFile.t -> stats_type -> unit (** Create performance report when the current process terminates *) diff --git a/infer/src/backend/callbacks.ml b/infer/src/backend/callbacks.ml index f3309ace7..4860e2c9d 100644 --- a/infer/src/backend/callbacks.ml +++ b/infer/src/backend/callbacks.ml @@ -121,7 +121,7 @@ let dump_duplicate_procs (exe_env: Exe_env.t) procs = let create_perf_stats_report source_file = let abbrev_source_file = DB.source_file_encoding source_file in let filename = F.sprintf "%s_%s.json" Config.perf_stats_prefix abbrev_source_file in - PerfStats.report_now filename ~source_file Config.backend_stats_dir_name + PerfStats.report_now filename ~source_file PerfStats.Backend (** Invoke all procedure and cluster callbacks on a given environment. *) diff --git a/infer/src/clang/Capture.ml b/infer/src/clang/Capture.ml index 66c53f860..3c4f7dcfa 100644 --- a/infer/src/clang/Capture.ml +++ b/infer/src/clang/Capture.ml @@ -27,7 +27,18 @@ let validate_decl_from_channel chan = let register_perf_stats_report source_file = let abbrev_source_file = DB.source_file_encoding source_file in let filename = F.sprintf "%s_%s.json" Config.perf_stats_prefix abbrev_source_file in - PerfStats.register_report_at_exit filename ~source_file Config.frontend_stats_dir_name + let stats_type = + match (Config.capture, Config.linters) with + | true, true -> + PerfStats.ClangFrontendLinters + | true, false -> + PerfStats.ClangFrontend + | false, true -> + PerfStats.ClangLinters + | false, false -> + Logging.(die UserError) "Clang frontend should be run in capture and/or linters mode." + in + PerfStats.register_report_at_exit filename ~source_file stats_type let init_global_state_for_capture_and_linters source_file = diff --git a/infer/src/integration/Driver.ml b/infer/src/integration/Driver.ml index 1ae444ee0..7be194f37 100644 --- a/infer/src/integration/Driver.ml +++ b/infer/src/integration/Driver.ml @@ -128,7 +128,7 @@ let clean_results_dir () = let register_perf_stats_report () = let filename = F.sprintf "%s.json" Config.perf_stats_prefix in - PerfStats.register_report_at_exit filename Config.driver_stats_dir_name + PerfStats.register_report_at_exit filename PerfStats.Driver let reset_duplicates_file () = diff --git a/infer/src/java/jMain.ml b/infer/src/java/jMain.ml index 0b9c39c18..cf8ae6f65 100644 --- a/infer/src/java/jMain.ml +++ b/infer/src/java/jMain.ml @@ -17,7 +17,7 @@ module L = Logging let register_perf_stats_report source_file = let abbrev_source_file = DB.source_file_encoding source_file in let filename = F.sprintf "%s_%s.json" Config.perf_stats_prefix abbrev_source_file in - PerfStats.register_report_at_exit filename ~source_file Config.frontend_stats_dir_name + PerfStats.register_report_at_exit filename ~source_file PerfStats.JavaFrontend let init_global_state source_file =