Use the summaries to store the @CallsExpensive attributes

Summary: public
Load and store the inferred attributes on the analysis summaries. The next step is to use the call stack from performance critical methods to expensive methods form the summary payload instead of modifying the attributes.

Reviewed By: sblackshear, cristianoc

Differential Revision: D2644530

fb-gh-sync-id: b99a8e3
master
jrm 9 years ago committed by facebook-github-bot-7
parent 4fa4c9f0d6
commit 5691f24090

@ -19,6 +19,7 @@ let expensive_overrides_unexpensive =
let unannotated_overrides_performance_critical = let unannotated_overrides_performance_critical =
"CHECKERS_UNANNOTATED_OVERRIDES_PERFOMANCE_CRITICAL" "CHECKERS_UNANNOTATED_OVERRIDES_PERFOMANCE_CRITICAL"
let search_expensive_call checked_pnames expensive_callee (pname, _) = let search_expensive_call checked_pnames expensive_callee (pname, _) =
match expensive_callee with match expensive_callee with
| Some callee_pname -> Some callee_pname | Some callee_pname -> Some callee_pname
@ -27,9 +28,10 @@ let search_expensive_call checked_pnames expensive_callee (pname, _) =
else else
begin begin
checked_pnames := Procname.Set.add pname !checked_pnames; checked_pnames := Procname.Set.add pname !checked_pnames;
match AttributesTable.load_attributes pname with match Specs.get_summary pname with
| None -> None | None -> None
| Some attributes -> | Some summary ->
let attributes = Specs.get_attributes summary in
let annotated_signature = Annotations.get_annotated_signature attributes in let annotated_signature = Annotations.get_annotated_signature attributes in
let ret_annotation, _ = annotated_signature.Annotations.ret in let ret_annotation, _ = annotated_signature.Annotations.ret in
if Annotations.ia_calls_expensive ret_annotation then if Annotations.ia_calls_expensive ret_annotation then
@ -67,6 +69,23 @@ let method_is_expensive pname =
check_method Annotations.ia_is_expensive pname check_method Annotations.ia_is_expensive pname
let update_summary_attributes pname =
match Specs.get_summary pname with
| None ->
let pname_str = Procname.to_string pname in
failwith ("The summary should have been created before running the checker on "^pname_str)
| Some summary ->
let attributes = Specs.get_attributes summary in
let ret_annot, param_annot = attributes.ProcAttributes.method_annotation in
let updated_method_annot =
(Annotations.calls_expensive_annotation, true) :: ret_annot, param_annot in
let updated_attributes =
{ attributes with ProcAttributes.method_annotation = updated_method_annot } in
let updated_summary =
{ summary with Specs.attributes = updated_attributes } in
Specs.add_summary pname updated_summary
let callback_performance_checker _ _ _ tenv pname pdesc = let callback_performance_checker _ _ _ tenv pname pdesc =
let loc = Cfg.Procdesc.get_loc pdesc in let loc = Cfg.Procdesc.get_loc pdesc in
@ -119,10 +138,6 @@ let callback_performance_checker _ _ _ tenv pname pdesc =
Checkers.ST.report_error Checkers.ST.report_error
pname pdesc calls_expensive_method loc description pname pdesc calls_expensive_method loc description
| Some _ when not expensive -> | Some _ when not expensive ->
let ret_annot, param_annot = attributes.ProcAttributes.method_annotation in update_summary_attributes pname
let updated_method_annot =
(Annotations.calls_expensive_annotation, true) :: ret_annot, param_annot in
let updated_attributes =
{ attributes with ProcAttributes.method_annotation = updated_method_annot } in
AttributesTable.store_attributes updated_attributes
| Some _ -> () (* Nothing to do if method already annotated with @Expensive *) | Some _ -> () (* Nothing to do if method already annotated with @Expensive *)

Loading…
Cancel
Save