[topl] Get number of arguments from property.

Summary:
It used to recompute the number of arguments during
instrumentation, which is unnecessary.

Reviewed By: ngorogiannis

Differential Revision: D19035492

fbshipit-source-id: 0f58c8ae7
master
Radu Grigore 5 years ago committed by Facebook Github Bot
parent 91ebfe9c20
commit cbb71c6203

@ -39,14 +39,6 @@ let get_proc_attr proc_name =
Option.map ~f:Procdesc.get_attributes (get_proc_desc proc_name) Option.map ~f:Procdesc.get_attributes (get_proc_desc proc_name)
let max_args = ref 0
let get_max_args () =
let instrument_max_args = !max_args in
let automaton_max_args = ToplAutomaton.max_args (Lazy.force automaton) in
Int.max instrument_max_args automaton_max_args
let get_transitions_count () = ToplAutomaton.tcount (Lazy.force automaton) let get_transitions_count () = ToplAutomaton.tcount (Lazy.force automaton)
(** Checks whether the method name and the number of arguments matches the conditions in a (** Checks whether the method name and the number of arguments matches the conditions in a
@ -103,18 +95,15 @@ let call_execute loc =
[|ToplUtils.topl_call dummy_ret_id Tvoid loc ToplName.execute []|] [|ToplUtils.topl_call dummy_ret_id Tvoid loc ToplName.execute []|]
(* Side-effect: increases [!max_args] when it sees a call with more arguments. *)
let instrument_instruction = function let instrument_instruction = function
| Sil.Call ((ret_id, ret_typ), e_fun, arg_ts, loc, _call_flags) as i -> | Sil.Call ((ret_id, ret_typ), e_fun, arg_ts, loc, _call_flags) as i ->
let active_transitions = get_active_transitions e_fun arg_ts in let active_transitions = get_active_transitions e_fun arg_ts in
if not (Array.exists ~f:(fun x -> x) active_transitions) then [|i|] if not (Array.exists ~f:(fun x -> x) active_transitions) then [|i|]
else ( else
max_args := Int.max !max_args (List.length arg_ts) ;
tt "found %d arguments@\n" (List.length arg_ts) ;
let i1s = set_transitions loc active_transitions in let i1s = set_transitions loc active_transitions in
let i2s = call_save_args loc ret_id ret_typ arg_ts in let i2s = call_save_args loc ret_id ret_typ arg_ts in
let i3s = call_execute loc in let i3s = call_execute loc in
Array.concat [[|i|]; i1s; i2s; i3s] ) Array.concat [[|i|]; i1s; i2s; i3s]
| i -> | i ->
[|i|] [|i|]
@ -145,7 +134,7 @@ let add_types tenv =
let state = (ToplUtils.make_field ToplName.state, Typ.mk (Tint IInt), []) in let state = (ToplUtils.make_field ToplName.state, Typ.mk (Tint IInt), []) in
let retval = (ToplUtils.make_field ToplName.retval, ToplUtils.any_type, []) in let retval = (ToplUtils.make_field ToplName.retval, ToplUtils.any_type, []) in
let transitions = List.init (get_transitions_count ()) ~f:transition_field in let transitions = List.init (get_transitions_count ()) ~f:transition_field in
let saved_args = List.init (get_max_args ()) ~f:saved_arg_field in let saved_args = List.init (ToplAutomaton.max_args (Lazy.force automaton)) ~f:saved_arg_field in
let registers = List.map ~f:register_field (get_registers ()) in let registers = List.map ~f:register_field (get_registers ()) in
List.concat [[retval; state]; transitions; saved_args; registers] List.concat [[retval; state]; transitions; saved_args; registers]
in in
@ -158,7 +147,7 @@ let instrument tenv procdesc =
let f _node = instrument_instruction in let f _node = instrument_instruction in
tt "instrument@\n" ; tt "instrument@\n" ;
let _updated = Procdesc.replace_instrs_by procdesc ~f in let _updated = Procdesc.replace_instrs_by procdesc ~f in
tt "add types %d@\n" !max_args ; add_types tenv ; tt "done@\n" ) tt "add types@\n" ; add_types tenv ; tt "done@\n" )
(** [lookup_static_var var prop] expects [var] to have the form [Exp.Lfield (obj, fieldname)], and (** [lookup_static_var var prop] expects [var] to have the form [Exp.Lfield (obj, fieldname)], and

@ -198,14 +198,16 @@ let gen_maybe_call ret_id : node_generator =
let arguments_count proc_name = List.length (Typ.Procname.get_parameters proc_name) let arguments_count proc_name = List.length (Typ.Procname.get_parameters proc_name)
(* NOTE: The order of parameters must correspond to what gets generated by [call_save_args]. *) (* NOTE: The order of parameters must correspond to what gets generated by [Topl.call_save_args]. *)
let generate_save_args _automaton proc_name = let generate_save_args automaton proc_name =
let n = arguments_count proc_name in if arguments_count proc_name < 1 then
L.die InternalError "ToplMonitor: saveArgs() needs at least one argument" ;
let n = Int.min (arguments_count proc_name - 1) (ToplAutomaton.max_args automaton) in
let local_var = ToplUtils.local_var proc_name in let local_var = ToplUtils.local_var proc_name in
procedure proc_name procedure proc_name
(sequence (sequence
( assign (ToplUtils.static_var ToplName.retval) (local_var (ToplName.arg 0)) ( assign (ToplUtils.static_var ToplName.retval) (local_var (ToplName.arg 0))
:: List.init (n - 1) ~f:(fun i -> :: List.init n ~f:(fun i ->
assign assign
(ToplUtils.static_var (ToplName.saved_arg i)) (ToplUtils.static_var (ToplName.saved_arg i))
(local_var (ToplName.arg (i + 1))) ) )) (local_var (ToplName.arg (i + 1))) ) ))

Loading…
Cancel
Save