[ondemand] remove type environments from cluster callbacks

Summary: There is no need to provide type environments to cluster analysers, since the execution environment can be used to retrieve those on demand.

Reviewed By: jvillard

Differential Revision: D19543561

fbshipit-source-id: f9b064011
master
Nikos Gorogiannis 5 years ago committed by Facebook Github Bot
parent edc47d4a96
commit c878aa6135

@ -15,7 +15,7 @@ type proc_callback_args =
type proc_callback_t = proc_callback_args -> Summary.t type proc_callback_t = proc_callback_args -> Summary.t
type cluster_callback_args = type cluster_callback_args =
{procedures: (Tenv.t * Summary.t) list; source_file: SourceFile.t; exe_env: Exe_env.t} {procedures: Summary.t list; source_file: SourceFile.t; exe_env: Exe_env.t}
type cluster_callback_t = cluster_callback_args -> unit type cluster_callback_t = cluster_callback_args -> unit
@ -37,12 +37,8 @@ let register_cluster_callback ~name language (callback : cluster_callback_t) =
cluster_callbacks := {name; language; callback} :: !cluster_callbacks cluster_callbacks := {name; language; callback} :: !cluster_callbacks
(** Collect what we need to know about a procedure for the analysis. *) let get_procedure_definition proc_name =
let get_procedure_definition exe_env proc_name = Procdesc.load proc_name |> Option.map ~f:Summary.OnDisk.reset
Procdesc.load proc_name
|> Option.map ~f:(fun proc_desc ->
let tenv = Exe_env.get_tenv exe_env proc_name in
(tenv, Summary.OnDisk.reset proc_desc) )
(** Invoke all registered procedure callbacks on the given procedure. *) (** Invoke all registered procedure callbacks on the given procedure. *)
@ -80,11 +76,11 @@ let iterate_procedure_callbacks exe_env summary =
(** Invoke all registered cluster callbacks on a cluster of procedures. *) (** Invoke all registered cluster callbacks on a cluster of procedures. *)
let iterate_cluster_callbacks all_procs exe_env source_file = let iterate_cluster_callbacks all_procs exe_env source_file =
if !cluster_callbacks <> [] then if !cluster_callbacks <> [] then
let procedures = List.filter_map ~f:(get_procedure_definition exe_env) all_procs in let procedures = List.filter_map ~f:get_procedure_definition all_procs in
let environment = {procedures; source_file; exe_env} in let environment = {procedures; source_file; exe_env} in
let language_matches language = let language_matches language =
match procedures with match procedures with
| (_, summary) :: _ -> | summary :: _ ->
Language.equal language (Procname.get_language (Summary.get_proc_name summary)) Language.equal language (Procname.get_language (Summary.get_proc_name summary))
| _ -> | _ ->
true true

@ -21,7 +21,7 @@ type proc_callback_args =
type proc_callback_t = proc_callback_args -> Summary.t type proc_callback_t = proc_callback_args -> Summary.t
type cluster_callback_args = type cluster_callback_args =
{procedures: (Tenv.t * Summary.t) list; source_file: SourceFile.t; exe_env: Exe_env.t} {procedures: Summary.t list; source_file: SourceFile.t; exe_env: Exe_env.t}
type cluster_callback_t = cluster_callback_args -> unit type cluster_callback_t = cluster_callback_args -> unit

@ -1093,37 +1093,40 @@ let report_unsafe_accesses ~issue_log classname (aggregated_access_map : ReportM
may touch that memory loc. the abstraction of a location is an access may touch that memory loc. the abstraction of a location is an access
path like x.f.g whose concretization is the set of memory cells path like x.f.g whose concretization is the set of memory cells
that x.f.g may point to during execution *) that x.f.g may point to during execution *)
let make_results_table file_env = let make_results_table exe_env summaries =
let open RacerDDomain in let open RacerDDomain in
let aggregate_post tenv procname acc {threads; accesses} = let aggregate_post tenv procname acc {threads; accesses} =
AccessDomain.fold AccessDomain.fold
(fun snapshot acc -> ReportMap.add {threads; snapshot; tenv; procname} acc) (fun snapshot acc -> ReportMap.add {threads; snapshot; tenv; procname} acc)
accesses acc accesses acc
in in
List.fold file_env ~init:ReportMap.empty ~f:(fun acc (tenv, summary) -> List.fold summaries ~init:ReportMap.empty ~f:(fun acc summary ->
let procname = Summary.get_proc_name summary in let procname = Summary.get_proc_name summary in
let tenv = Exe_env.get_tenv exe_env procname in
Payload.read_toplevel_procedure procname Payload.read_toplevel_procedure procname
|> Option.fold ~init:acc ~f:(aggregate_post tenv procname) ) |> Option.fold ~init:acc ~f:(aggregate_post tenv procname) )
(* aggregate all of the procedures in the file env by their declaring (* aggregate all of the procedures in the file env by their declaring
class. this lets us analyze each class individually *) class. this lets us analyze each class individually *)
let aggregate_by_class file_env = let aggregate_by_class exe_env file_env =
List.fold file_env ~init:String.Map.empty ~f:(fun acc ((tenv, summary) as proc) -> List.fold file_env ~init:String.Map.empty ~f:(fun acc summary ->
let pdesc = Summary.get_proc_desc summary in let pdesc = Summary.get_proc_desc summary in
let procname = Summary.get_proc_name summary in
let tenv = Exe_env.get_tenv exe_env procname in
if should_report_on_proc tenv pdesc then if should_report_on_proc tenv pdesc then
Procdesc.get_proc_name pdesc |> Procname.get_class_name Procdesc.get_proc_name pdesc |> Procname.get_class_name
|> Option.fold ~init:acc ~f:(fun acc classname -> |> Option.fold ~init:acc ~f:(fun acc classname ->
String.Map.add_multi acc ~key:classname ~data:proc ) String.Map.add_multi acc ~key:classname ~data:summary )
else acc ) else acc )
(* Gathers results by analyzing all the methods in a file, then (* Gathers results by analyzing all the methods in a file, then
post-processes the results to check an (approximation of) thread post-processes the results to check an (approximation of) thread
safety *) safety *)
let file_analysis ({procedures; source_file} : Callbacks.cluster_callback_args) = let file_analysis ({procedures; source_file; exe_env} : Callbacks.cluster_callback_args) =
let init = IssueLog.empty in let init = IssueLog.empty in
aggregate_by_class procedures aggregate_by_class exe_env procedures
|> String.Map.fold ~init ~f:(fun ~key:classname ~data:class_env issue_log -> |> String.Map.fold ~init ~f:(fun ~key:classname ~data:summaries issue_log ->
make_results_table class_env |> report_unsafe_accesses ~issue_log classname ) make_results_table exe_env summaries |> report_unsafe_accesses ~issue_log classname )
|> IssueLog.store ~dir:Config.racerd_issues_dir_name ~file:source_file |> IssueLog.store ~dir:Config.racerd_issues_dir_name ~file:source_file

@ -658,7 +658,7 @@ let report_on_parallel_composition ~should_report_starvation tenv pdesc pair loc
else report_map else report_map
let report_on_pair ((tenv, summary) as env) (pair : Domain.CriticalPair.t) report_map = let report_on_pair tenv summary (pair : Domain.CriticalPair.t) report_map =
let open Domain in let open Domain in
let pdesc = Summary.get_proc_desc summary in let pdesc = Summary.get_proc_desc summary in
let pname = Summary.get_proc_name summary in let pname = Summary.get_proc_name summary in
@ -716,7 +716,7 @@ let report_on_pair ((tenv, summary) as env) (pair : Domain.CriticalPair.t) repor
and retrieve all the summaries of the methods of that class; and retrieve all the summaries of the methods of that class;
then, report on the parallel composition of the current pair and any pair in these then, report on the parallel composition of the current pair and any pair in these
summaries that can indeed run in parallel *) summaries that can indeed run in parallel *)
fold_reportable_summaries env other_class ~init:report_map fold_reportable_summaries (tenv, summary) other_class ~init:report_map
~f:(fun acc (other_pname, {critical_pairs}) -> ~f:(fun acc (other_pname, {critical_pairs}) ->
CriticalPairs.fold CriticalPairs.fold
(report_on_parallel_composition ~should_report_starvation tenv pdesc pair lock (report_on_parallel_composition ~should_report_starvation tenv pdesc pair lock
@ -726,17 +726,19 @@ let report_on_pair ((tenv, summary) as env) (pair : Domain.CriticalPair.t) repor
report_map report_map
let reporting {Callbacks.procedures} = let reporting {Callbacks.procedures; exe_env} =
if Config.starvation_whole_program then () if Config.starvation_whole_program then ()
else else
let report_on_summary env report_map (summary : Domain.summary) = let report_on_summary tenv summary report_map (payload : Domain.summary) =
Domain.CriticalPairs.fold (report_on_pair env) summary.critical_pairs report_map Domain.CriticalPairs.fold (report_on_pair tenv summary) payload.critical_pairs report_map
in in
let report_procedure report_map ((_, summary) as env) = let report_procedure report_map summary =
let proc_desc = Summary.get_proc_desc summary in let proc_desc = Summary.get_proc_desc summary in
let procname = Summary.get_proc_name summary in
let tenv = Exe_env.get_tenv exe_env procname in
if should_report proc_desc then if should_report proc_desc then
Payload.read_toplevel_procedure (Procdesc.get_proc_name proc_desc) Payload.read_toplevel_procedure procname
|> Option.fold ~init:report_map ~f:(report_on_summary env) |> Option.fold ~init:report_map ~f:(report_on_summary tenv summary)
else report_map else report_map
in in
List.fold procedures ~init:ReportMap.empty ~f:report_procedure |> ReportMap.store List.fold procedures ~init:ReportMap.empty ~f:report_procedure |> ReportMap.store
@ -793,7 +795,7 @@ let report exe_env work_set =
|> Option.fold ~init ~f:(fun acc summary -> |> Option.fold ~init ~f:(fun acc summary ->
let pdesc = Summary.get_proc_desc summary in let pdesc = Summary.get_proc_desc summary in
let tenv = Exe_env.get_tenv exe_env procname in let tenv = Exe_env.get_tenv exe_env procname in
let acc = report_on_pair (tenv, summary) pair acc in let acc = report_on_pair tenv summary pair acc in
match pair.elem.event with match pair.elem.event with
| LockAcquire lock -> | LockAcquire lock ->
let should_report_starvation = let should_report_starvation =

Loading…
Cancel
Save