[exe-env] refactor into a two-level hashtable

Summary:
- Eliminate dead `source` field in `field_data` record.
- Use a 2-level hashtable structure (`procname` -> `source_file` and `source_file` -> `file_data`) to help potentially using an LRU cache for layer 1.
- Use laziness instead of mutability.
- Fixed stale comments

Reviewed By: jvillard

Differential Revision: D25303360

fbshipit-source-id: 68a22d299
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent 15943b1ea1
commit 695a3df7be

@ -14,63 +14,47 @@ module F = Format
module L = Logging
(** per-file data: type environment and cfg *)
type file_data =
{ source: SourceFile.t
; mutable tenv: Tenv.t option
; mutable integer_type_widths: Typ.IntegerWidths.t option }
(** per-file data: type environment and integer widths *)
type file_data = {tenv: Tenv.t option Lazy.t; integer_type_widths: Typ.IntegerWidths.t option Lazy.t}
(** create a new file_data *)
let new_file_data source =
(* Do not fill in tenv and cfg as they can be quite large. This makes calls to fork() cheaper
until we start filling out these fields. *)
{source; tenv= None (* Sil.load_tenv_from_file tenv_file *); integer_type_widths= None}
{ tenv= lazy (Tenv.load source)
; integer_type_widths=
lazy (Option.first_some (Typ.IntegerWidths.load source) (Some Typ.IntegerWidths.java)) }
let create_file_data table source =
match SourceFile.Hash.find table source with
| file_data ->
let file_data_of_source table source =
match SourceFile.Hash.find_opt table source with
| Some file_data ->
file_data
| exception Caml.Not_found ->
| None ->
let file_data = new_file_data source in
SourceFile.Hash.add table source file_data ;
file_data
type t =
{ proc_map: file_data Procname.Hash.t (** map from procedure name to file data *)
; file_map: file_data SourceFile.Hash.t (** map from source files to file data *) }
type t = {proc_map: SourceFile.t Procname.Hash.t; file_map: file_data SourceFile.Hash.t}
let get_file_data exe_env pname =
try Some (Procname.Hash.find exe_env.proc_map pname)
with Caml.Not_found ->
let source_file_opt =
match Attributes.load pname with
| None ->
L.debug Analysis Medium "can't find attributes for %a@." Procname.pp pname ;
None
| Some proc_attributes ->
Some proc_attributes.ProcAttributes.translation_unit
in
let get_file_data_for_source source_file =
let file_data = create_file_data exe_env.file_map source_file in
Procname.Hash.replace exe_env.proc_map pname file_data ;
file_data
in
Option.map ~f:get_file_data_for_source source_file_opt
let file_data_to_tenv file_data =
if is_none file_data.tenv then file_data.tenv <- Tenv.load file_data.source ;
file_data.tenv
match Procname.Hash.find_opt exe_env.proc_map pname with
| Some source ->
Some (file_data_of_source exe_env.file_map source)
| None -> (
match Attributes.load pname with
| None ->
L.debug Analysis Medium "can't find attributes for %a@." Procname.pp pname ;
None
| Some proc_attributes ->
let source_file = proc_attributes.ProcAttributes.translation_unit in
let file_data = file_data_of_source exe_env.file_map source_file in
Procname.Hash.add exe_env.proc_map pname source_file ;
Some file_data )
let file_data_to_integer_type_widths file_data =
if is_none file_data.integer_type_widths then
file_data.integer_type_widths <-
Option.first_some (Typ.IntegerWidths.load file_data.source) (Some Typ.IntegerWidths.java) ;
file_data.integer_type_widths
let file_data_to_tenv file_data = Lazy.force file_data.tenv
let file_data_to_integer_type_widths file_data = Lazy.force file_data.integer_type_widths
let java_global_tenv =
lazy

Loading…
Cancel
Save