From 57b449766328d5d3e2d4ef645c0936c0a8ae70a1 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 23 Feb 2016 03:16:29 -0800 Subject: [PATCH] Start reactive exploration from changed procedures only. Reviewed By: jberdine Differential Revision: D2965370 fb-gh-sync-id: d00e360 shipit-source-id: d00e360 --- infer/src/backend/cfg.ml | 6 ++---- infer/src/backend/fork.ml | 29 +++++++++++++++++----------- infer/src/backend/procAttributes.ml | 17 +++++++++------- infer/src/backend/procAttributes.mli | 3 ++- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/infer/src/backend/cfg.ml b/infer/src/backend/cfg.ml index 9a2348192..df13bf2fe 100644 --- a/infer/src/backend/cfg.ml +++ b/infer/src/backend/cfg.ml @@ -43,7 +43,6 @@ module Node = struct mutable pd_nodes : t list; (** list of nodes of this procedure *) mutable pd_start_node : t; (** start node of this procedure *) mutable pd_exit_node : t; (** exit node of ths procedure *) - mutable pd_changed : bool; (** true if proc has changed since last analysis *) } let exn_handler_kind = Stmt_node "exception handler" @@ -112,7 +111,7 @@ module Node = struct try let old_pdesc = Procname.Hash.find old_procs pname in let changed = not (pdescs_eq old_pdesc new_pdesc) in - new_pdesc.pd_changed <- changed + new_pdesc.pd_attributes.changed <- changed with Not_found -> () in Procname.Hash.iter mark_pdesc_if_unchanged new_procs @@ -133,7 +132,7 @@ module Node = struct let proc_name_is_changed cfg proc_name = try let pdesc = proc_name_to_proc_desc cfg proc_name in - pdesc.pd_changed + pdesc.pd_attributes.changed with Not_found -> true let iter_proc_desc cfg f = @@ -376,7 +375,6 @@ module Node = struct pd_nodes = []; pd_start_node = dummy (); pd_exit_node = dummy (); - pd_changed = true } in pdesc_tbl_add cfg proc_attributes.ProcAttributes.proc_name pdesc; pdesc diff --git a/infer/src/backend/fork.ml b/infer/src/backend/fork.ml index 233adab0a..0aa556759 100644 --- a/infer/src/backend/fork.ml +++ b/infer/src/backend/fork.ml @@ -349,17 +349,24 @@ let main_algorithm exe_env analyze_proc filter_out process_result : unit = (Specs.get_timestamp (Specs.get_summary_unsafe "main_algorithm" pname) = 0 || not (proc_is_up_to_date call_graph pname)) in let filter_out_ondemand pname = - if !Config.ondemand_enabled then - try - let cfg = Exe_env.get_cfg exe_env pname in - match Cfg.Procdesc.find_from_name cfg pname with - | Some pdesc -> - not (Ondemand.procedure_should_be_analyzed pdesc pname) - | None -> - false - with Not_found -> false - else - false in + let to_analyze = + if !Config.ondemand_enabled then + try + let cfg = Exe_env.get_cfg exe_env pname in + match Cfg.Procdesc.find_from_name cfg pname with + | Some pdesc -> + let reactive_changed = + if !Config.reactive_mode + then (Cfg.Procdesc.get_attributes pdesc).ProcAttributes.changed + else true in + reactive_changed && (* in reactive mode, only analyze changed procedures *) + Ondemand.procedure_should_be_analyzed pdesc pname + | None -> + true + with Not_found -> true + else + true in + not to_analyze in let process_one_proc ((pname, _) as elem) = DB.current_source := (Specs.get_summary_unsafe "main_algorithm" pname) diff --git a/infer/src/backend/procAttributes.ml b/infer/src/backend/procAttributes.ml index f4bd92221..a6b78b3a4 100644 --- a/infer/src/backend/procAttributes.ml +++ b/infer/src/backend/procAttributes.ml @@ -21,6 +21,7 @@ type t = { access : Sil.access; (** visibility access *) captured : (Mangled.t * Sil.typ) list; (** name and type of variables captured in blocks *) + mutable changed : bool; (** true if proc has changed since last analysis *) err_log: Errlog.t; (** Error log for the procedure *) exceptions : string list; (** exceptions thrown by the procedure *) formals : (Mangled.t * Sil.typ) list; (** name and type of formal parameters *) @@ -30,12 +31,12 @@ type t = is_defined : bool; (** true if the procedure is defined, and not just declared *) is_objc_instance_method : bool; (** the procedure is an objective-C instance method *) is_cpp_instance_method : bool; (** the procedure is an C++ instance method *) - objc_accessor : objc_accessor_type option; (** the proc is ObjC accessor *) mutable is_synthetic_method : bool; (** the procedure is a synthetic method *) language : Config.language; (** language of the procedure *) loc : Location.t; (** location of this procedure in the source code *) mutable locals : (Mangled.t * Sil.typ) list; (** name and type of local variables *) method_annotation : Sil.method_annotation; (** annotations for java methods *) + objc_accessor : objc_accessor_type option; (** type of ObjC accessor, if any *) proc_flags : proc_flags; (** flags of the procedure *) proc_name : Procname.t; (** name of the procedure *) ret_type : Sil.typ; (** return type *) @@ -45,21 +46,22 @@ let copy pa = { access = pa.access; captured = pa.captured; + changed = pa.changed; err_log = pa.err_log; exceptions = pa.exceptions; formals = pa.formals; func_attributes = pa.func_attributes; is_abstract = pa.is_abstract; is_bridge_method = pa.is_bridge_method; + is_cpp_instance_method = pa.is_cpp_instance_method; is_defined = pa.is_defined; is_objc_instance_method = pa.is_objc_instance_method; - is_cpp_instance_method = pa.is_cpp_instance_method; - objc_accessor = pa.objc_accessor; is_synthetic_method = pa.is_synthetic_method; language = pa.language; loc = pa.loc; locals = pa.locals; method_annotation = pa.method_annotation; + objc_accessor = pa.objc_accessor; proc_flags = pa.proc_flags; proc_name = pa.proc_name; ret_type = pa.ret_type; @@ -67,22 +69,23 @@ let copy pa = let default proc_name language = { access = Sil.Default; - formals = []; captured = []; + changed = true; err_log = Errlog.empty (); exceptions = []; + formals = []; func_attributes = []; is_abstract = false; - is_defined = false; is_bridge_method = false; - is_objc_instance_method = false; is_cpp_instance_method = false; - objc_accessor = None; + is_defined = false; + is_objc_instance_method = false; is_synthetic_method = false; language; loc = Location.dummy; locals = []; method_annotation = Sil.method_annotation_empty; + objc_accessor = None; proc_flags = proc_flags_empty (); proc_name; ret_type = Sil.Tvoid; diff --git a/infer/src/backend/procAttributes.mli b/infer/src/backend/procAttributes.mli index 83d5a622f..e6b430178 100644 --- a/infer/src/backend/procAttributes.mli +++ b/infer/src/backend/procAttributes.mli @@ -17,6 +17,7 @@ type t = { access : Sil.access; (** visibility access *) captured : (Mangled.t * Sil.typ) list; (** name and type of variables captured in blocks *) + mutable changed : bool; (** true if proc has changed since last analysis *) err_log: Errlog.t; (** Error log for the procedure *) exceptions : string list; (** exceptions thrown by the procedure *) formals : (Mangled.t * Sil.typ) list; (** name and type of formal parameters *) @@ -26,12 +27,12 @@ type t = is_defined : bool; (** true if the procedure is defined, and not just declared *) is_objc_instance_method : bool; (** the procedure is an objective-C instance method *) is_cpp_instance_method : bool; (** the procedure is an C++ instance method *) - objc_accessor : objc_accessor_type option; (** the proc is ObjC accessor *) mutable is_synthetic_method : bool; (** the procedure is a synthetic method *) language : Config.language; (** language of the procedure *) loc : Location.t; (** location of this procedure in the source code *) mutable locals : (Mangled.t * Sil.typ) list; (** name and type of local variables *) method_annotation : Sil.method_annotation; (** annotations for java methods *) + objc_accessor : objc_accessor_type option; (** type of ObjC accessor, if any *) proc_flags : proc_flags; (** flags of the procedure *) proc_name : Procname.t; (** name of the procedure *) ret_type : Sil.typ; (** return type *)