[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 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. *)

Loading…
Cancel
Save