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

Loading…
Cancel
Save