[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
master
Jeremy Dubreil 7 years ago committed by Facebook Github Bot
parent 96ca6b6f02
commit db078459b4

@ -23,6 +23,8 @@ type callbacks = {analyze_ondemand: analyze_ondemand; get_proc_desc: get_proc_de
let callbacks_ref = ref None let callbacks_ref = ref None
let cached_results = lazy (Typ.Procname.Hash.create 128)
let set_callbacks (callbacks: callbacks) = callbacks_ref := Some callbacks let set_callbacks (callbacks: callbacks) = callbacks_ref := Some callbacks
let unset_callbacks () = callbacks_ref := None 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)) 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 callee_pname = Procdesc.get_proc_name callee_pdesc in
let proc_attributes = Procdesc.get_attributes callee_pdesc in try Typ.Procname.Hash.find cache callee_pname with Not_found ->
match !callbacks_ref with let summary_option =
| None -> let callbacks = Option.value_exn !callbacks_ref in
L.(die InternalError) let proc_attributes = Procdesc.get_attributes callee_pdesc in
"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 ->
if should_be_analyzed callee_pname proc_attributes then if should_be_analyzed callee_pname proc_attributes then
Some (run_proc_analysis callbacks.analyze_ondemand ~caller_pdesc callee_pdesc) Some (run_proc_analysis callbacks.analyze_ondemand ~caller_pdesc callee_pdesc)
else 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
(** analyze_proc_name curr_pdesc proc_name performs an on-demand analysis of proc_name triggered (** analyze_proc_name curr_pdesc proc_name performs an on-demand analysis of proc_name triggered
during the analysis of curr_pname *) during the analysis of curr_pname *)
let analyze_proc_name : ?caller_pdesc:Procdesc.t -> Typ.Procname.t -> Specs.summary option = let analyze_proc_name ?caller_pdesc callee_pname =
let cached_results = Typ.Procname.Hash.create 100 in let cache = Lazy.force cached_results in
fun ?caller_pdesc callee_pname -> try Typ.Procname.Hash.find cache callee_pname with Not_found ->
try Typ.Procname.Hash.find cached_results callee_pname with Not_found -> let summary_option =
let summary_option = let callbacks = Option.value_exn !callbacks_ref in
match !callbacks_ref with 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 -> | None ->
L.(die InternalError) Specs.get_summary callee_pname
"No callbacks registered to analyze proc name %a (when analyzing %a)@." else Specs.get_summary callee_pname
Typ.Procname.pp callee_pname (Pp.option Typ.Procname.pp) in
(Option.map ~f:Procdesc.get_proc_name caller_pdesc) if not (is_active callee_pname) then Typ.Procname.Hash.add cache callee_pname summary_option ;
| Some callbacks -> summary_option
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
(** Find a proc desc for the procedure, perhaps loading it from disk. *) (** Find a proc desc for the procedure, perhaps loading it from disk. *)

Loading…
Cancel
Save