From db078459b4a4e3c97871319548ac553894fa5c61 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Thu, 25 Jan 2018 22:55:30 -0800 Subject: [PATCH] [infer][ondemand] also cache the result of analyzing a procedure description Summary: Before this diff, the `Ondemand` module would not cache the results of the function `analyze_proc_desc`, which is used by the toplvel iteration. This should not have any effect on the performances at this point as the summaries were already cached in the `Specs` module. Now, we can start remove the use of the cache in the `Specs` module to avoid the duplication. Caching at the level of `Ondemand` is better as we can safely cache the information that the outcome of the analysis is `None`, which avoids scanning the filesystem or the DB multiple times. Reviewed By: mbouaziz, jvillard Differential Revision: D6713546 fbshipit-source-id: 309701b --- infer/src/backend/ondemand.ml | 56 ++++++++++++++++------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index e93b24e1c..c983d82a5 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -23,6 +23,8 @@ type callbacks = {analyze_ondemand: analyze_ondemand; get_proc_desc: get_proc_de let callbacks_ref = ref None +let cached_results = lazy (Typ.Procname.Hash.create 128) + let set_callbacks (callbacks: callbacks) = callbacks_ref := Some callbacks let unset_callbacks () = callbacks_ref := None @@ -166,46 +168,38 @@ let run_proc_analysis analyze_proc ~caller_pdesc callee_pdesc = log_error_and_continue exn initial_summary (FKcrash (Exn.to_string exn)) -let analyze_proc_desc ?caller_pdesc callee_pdesc : Specs.summary option = +let analyze_proc_desc ?caller_pdesc callee_pdesc = + let cache = Lazy.force cached_results in let callee_pname = Procdesc.get_proc_name callee_pdesc in - let proc_attributes = Procdesc.get_attributes callee_pdesc in - match !callbacks_ref with - | None -> - L.(die InternalError) - "No callbacks registered to analyze proc desc %a (when analyzing %a)" Typ.Procname.pp - callee_pname (Pp.option Typ.Procname.pp) - (Option.map ~f:Procdesc.get_proc_name caller_pdesc) - | Some callbacks -> + try Typ.Procname.Hash.find cache callee_pname with Not_found -> + let summary_option = + let callbacks = Option.value_exn !callbacks_ref in + let proc_attributes = Procdesc.get_attributes callee_pdesc in if should_be_analyzed callee_pname proc_attributes then Some (run_proc_analysis callbacks.analyze_ondemand ~caller_pdesc callee_pdesc) else Specs.get_summary callee_pname + in + if not (is_active callee_pname) then Typ.Procname.Hash.add cache callee_pname summary_option ; + summary_option (** analyze_proc_name curr_pdesc proc_name performs an on-demand analysis of proc_name triggered during the analysis of curr_pname *) -let analyze_proc_name : ?caller_pdesc:Procdesc.t -> Typ.Procname.t -> Specs.summary option = - let cached_results = Typ.Procname.Hash.create 100 in - fun ?caller_pdesc callee_pname -> - try Typ.Procname.Hash.find cached_results callee_pname with Not_found -> - let summary_option = - match !callbacks_ref with +let analyze_proc_name ?caller_pdesc callee_pname = + let cache = Lazy.force cached_results in + try Typ.Procname.Hash.find cache callee_pname with Not_found -> + let summary_option = + let callbacks = Option.value_exn !callbacks_ref in + if procedure_should_be_analyzed callee_pname then + match callbacks.get_proc_desc callee_pname with + | Some callee_pdesc -> + analyze_proc_desc ?caller_pdesc callee_pdesc | None -> - L.(die InternalError) - "No callbacks registered to analyze proc name %a (when analyzing %a)@." - Typ.Procname.pp callee_pname (Pp.option Typ.Procname.pp) - (Option.map ~f:Procdesc.get_proc_name caller_pdesc) - | Some callbacks -> - if procedure_should_be_analyzed callee_pname then - match callbacks.get_proc_desc callee_pname with - | Some callee_pdesc -> - analyze_proc_desc ?caller_pdesc callee_pdesc - | None -> - Specs.get_summary callee_pname - else Specs.get_summary callee_pname - in - if not (is_active callee_pname) then - Typ.Procname.Hash.add cached_results callee_pname summary_option ; - summary_option + Specs.get_summary callee_pname + else Specs.get_summary callee_pname + in + if not (is_active callee_pname) then Typ.Procname.Hash.add cache callee_pname summary_option ; + summary_option (** Find a proc desc for the procedure, perhaps loading it from disk. *)