diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index b53412241..6c486cfc7 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -304,7 +304,8 @@ OPTIONS BUFFER_OVERRUN_U5, CLASS_CAST_EXCEPTION, CONDITION_ALWAYS_FALSE, CONDITION_ALWAYS_TRUE, DANGLING_POINTER_DEREFERENCE, DIVIDE_BY_ZERO, EXPENSIVE_ALLOCATION_CALL, - EXPENSIVE_EXECUTION_CALL, EXPENSIVE_IO_TIME_CALL, + EXPENSIVE_EXECUTION_CALL, EXPENSIVE_EXECUTION_CALL_IN_COLD_START, + EXPENSIVE_IO_TIME_CALL, GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL, INFINITE_EXECUTION_TIME_CALL, INTEGER_OVERFLOW_L5, INTEGER_OVERFLOW_U5, NULL_TEST_AFTER_DEREFERENCE, @@ -315,7 +316,7 @@ OPTIONS See also --report-issue-type. (default: - ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) + ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_EXECUTION_CALL_IN_COLD_START,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) See also infer-report(1). --dump-duplicate-symbols diff --git a/infer/man/man1/infer-report.txt b/infer/man/man1/infer-report.txt index 5b2aa8135..b8cf2792b 100644 --- a/infer/man/man1/infer-report.txt +++ b/infer/man/man1/infer-report.txt @@ -57,7 +57,8 @@ OPTIONS BUFFER_OVERRUN_U5, CLASS_CAST_EXCEPTION, CONDITION_ALWAYS_FALSE, CONDITION_ALWAYS_TRUE, DANGLING_POINTER_DEREFERENCE, DIVIDE_BY_ZERO, EXPENSIVE_ALLOCATION_CALL, - EXPENSIVE_EXECUTION_CALL, EXPENSIVE_IO_TIME_CALL, + EXPENSIVE_EXECUTION_CALL, EXPENSIVE_EXECUTION_CALL_IN_COLD_START, + EXPENSIVE_IO_TIME_CALL, GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL, INFINITE_EXECUTION_TIME_CALL, INTEGER_OVERFLOW_L5, INTEGER_OVERFLOW_U5, NULL_TEST_AFTER_DEREFERENCE, @@ -68,7 +69,7 @@ OPTIONS See also --report-issue-type. (default: - ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) + ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_EXECUTION_CALL_IN_COLD_START,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) --enable-issue-type +issue_type Show reports coming from this type of issue. By default, all issue diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index bb7219580..8f620ff0a 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -304,7 +304,8 @@ OPTIONS BUFFER_OVERRUN_U5, CLASS_CAST_EXCEPTION, CONDITION_ALWAYS_FALSE, CONDITION_ALWAYS_TRUE, DANGLING_POINTER_DEREFERENCE, DIVIDE_BY_ZERO, EXPENSIVE_ALLOCATION_CALL, - EXPENSIVE_EXECUTION_CALL, EXPENSIVE_IO_TIME_CALL, + EXPENSIVE_EXECUTION_CALL, EXPENSIVE_EXECUTION_CALL_IN_COLD_START, + EXPENSIVE_IO_TIME_CALL, GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL, INFINITE_EXECUTION_TIME_CALL, INTEGER_OVERFLOW_L5, INTEGER_OVERFLOW_U5, NULL_TEST_AFTER_DEREFERENCE, @@ -315,7 +316,7 @@ OPTIONS See also --report-issue-type. (default: - ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) + ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,EXPENSIVE_ALLOCATION_CALL,EXPENSIVE_EXECUTION_CALL,EXPENSIVE_EXECUTION_CALL_IN_COLD_START,EXPENSIVE_IO_TIME_CALL,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFINITE_EXECUTION_TIME_CALL,INTEGER_OVERFLOW_L5,INTEGER_OVERFLOW_U5,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION,UNTRUSTED_BUFFER_ACCESS,UNTRUSTED_HEAP_ALLOCATION,ZERO_EXECUTION_TIME_CALL) See also infer-report(1). --dump-duplicate-symbols diff --git a/infer/src/backend/Differential.ml b/infer/src/backend/Differential.ml index 73fa18556..8ab1cec16 100644 --- a/infer/src/backend/Differential.ml +++ b/infer/src/backend/Differential.ml @@ -138,10 +138,29 @@ let to_map key_func report = let issue_of_cost cost_info ~delta ~prev_cost ~curr_cost = let file = cost_info.Jsonbug_t.loc.file in + let class_name, method_name = + match String.split cost_info.Jsonbug_t.procedure_id ~on:'(' with + | [qualified_function; _] -> ( + match String.split qualified_function ~on:'.' with + | [class_name; method_name] -> + (class_name, method_name) + | _ -> + ("", cost_info.Jsonbug_t.procedure_id) ) + | _ -> + ("", cost_info.Jsonbug_t.procedure_id) + in + let procname = ExternalPerfData.make_void_signature_procname class_name method_name in + Logging.internal_error + "@\n\ + [DIFF ANALYSIS] class_name = '%s' method_name = '%s' procedure_id = '%s' Procname = \ + '%a' @\n" + class_name method_name cost_info.Jsonbug_t.procedure_id Typ.Procname.pp procname ; let source_file = SourceFile.create ~warn_on_error:false file in let issue_type = if CostDomain.BasicCost.is_top curr_cost then IssueType.infinite_execution_time_call else if CostDomain.BasicCost.is_zero curr_cost then IssueType.zero_execution_time_call + else if ExternalPerfData.in_profiler_data_map procname then + IssueType.performance_variation_critical_cold_start else IssueType.performance_variation in let curr_degree_with_term = CostDomain.BasicCost.get_degree_with_term curr_cost in diff --git a/infer/src/backend/LoadPerfData.ml b/infer/src/backend/ExternalPerfData.ml similarity index 72% rename from infer/src/backend/LoadPerfData.ml rename to infer/src/backend/ExternalPerfData.ml index 0ab32a053..9cc75559a 100644 --- a/infer/src/backend/LoadPerfData.ml +++ b/infer/src/backend/ExternalPerfData.ml @@ -58,7 +58,17 @@ let pp_perf_profiler_item itm = itm.p25_inclusive_cpu_time_ms itm.p25_exclusive_cpu_time_ms -let read_file_perf_data fname = +let make_void_signature_procname classname methodname = + let signature = JavaProfilerSamples.JNI.void_method_with_no_arguments in + L.(debug Analysis Medium) + "@\n Making procname with void signature for classname = %s methodname = %s @\n" classname + methodname ; + let procname = JavaProfilerSamples.create_procname ~classname ~methodname ~signature in + L.(debug Analysis Medium) " Resulting procname= %a @\n" Typ.Procname.pp procname ; + procname + + +let _read_file_perf_data fname = let perf_profiler_data_str = match Utils.read_file fname with | Ok l -> @@ -71,14 +81,25 @@ let read_file_perf_data fname = pp_perf_profiler_item itm ; match split_class_method_name itm.Perf_profiler_t.function_name with | Some (classname, methodname) -> - let signature = JavaProfilerSamples.JNI.void_method_with_no_arguments in - L.(debug Analysis Medium) - "@\n classname = %s methodname = %s @\n" classname methodname ; - let procname = JavaProfilerSamples.create_procname ~classname ~methodname ~signature in - L.(debug Analysis Medium) " procname= %a @\n" Typ.Procname.pp procname ; + let procname = make_void_signature_procname classname methodname in global_perf_profiler_data := PerfProfilerDataMap.add procname itm !global_perf_profiler_data | _ -> () in List.iter ~f:(fun items -> List.iter ~f:do_item items) perf_profiler_data_str + + +let read_file_flag = ref false + +let in_profiler_data_map key = + match Config.perf_profiler_data_file with + | Some fname -> + if not !read_file_flag then ( + _read_file_perf_data fname ; + read_file_flag := true ) ; + if PerfProfilerDataMap.is_empty !global_perf_profiler_data then + L.(debug Analysis Medium) "@\n\n\[Perf Profiler Log] WARNING: EMPTY PERF PROFILER DATA@\n" ; + PerfProfilerDataMap.mem key !global_perf_profiler_data + | _ -> + false diff --git a/infer/src/backend/LoadPerfData.mli b/infer/src/backend/ExternalPerfData.mli similarity index 61% rename from infer/src/backend/LoadPerfData.mli rename to infer/src/backend/ExternalPerfData.mli index 607d2e426..9e59871a3 100644 --- a/infer/src/backend/LoadPerfData.mli +++ b/infer/src/backend/ExternalPerfData.mli @@ -7,4 +7,6 @@ open! IStd -val read_file_perf_data : string -> unit +val in_profiler_data_map : Typ.Procname.t -> bool + +val make_void_signature_procname : string -> string -> Typ.Procname.t diff --git a/infer/src/backend/InferPrint.ml b/infer/src/backend/InferPrint.ml index 63b71286a..93a0996d9 100644 --- a/infer/src/backend/InferPrint.ml +++ b/infer/src/backend/InferPrint.ml @@ -1068,12 +1068,6 @@ let register_perf_stats_report () = let main ~report_json = - ( if Config.loop_hoisting then - match Config.perf_profiler_data_file with - | Some fname -> - LoadPerfData.read_file_perf_data fname - | _ -> - () ) ; let issue_formats = init_issues_format_list report_json in let formats_by_report_kind = let costs_report_format_kind = diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index ae2a6ebaa..a28ed8e01 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -258,6 +258,10 @@ let expensive_allocation_call = from_string ~enabled:false "EXPENSIVE_ALLOCATION let expensive_IO_call = from_string ~enabled:false "EXPENSIVE_IO_TIME_CALL" +let expensive_execution_time_call_cold_start = + from_string ~enabled:false "EXPENSIVE_EXECUTION_CALL_IN_COLD_START" + + let exposed_insecure_intent_handling = from_string "EXPOSED_INSECURE_INTENT_HANDLING" let failure_exe = from_string "Failure_exe" @@ -343,6 +347,8 @@ let parameter_not_null_checked = from_string "PARAMETER_NOT_NULL_CHECKED" let performance_variation = from_string "PERFORMANCE_VARIATION" +let performance_variation_critical_cold_start = from_string "PERFORMANCE_VARIATION_COLD_START" + let pointer_size_mismatch = from_string "POINTER_SIZE_MISMATCH" let precondition_not_found = from_string "PRECONDITION_NOT_FOUND" diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index 31a6d43d2..dfec9040e 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -169,6 +169,8 @@ val expensive_allocation_call : t val expensive_IO_call : t +val expensive_execution_time_call_cold_start : t + val exposed_insecure_intent_handling : t val failure_exe : t @@ -243,6 +245,8 @@ val parameter_not_null_checked : t val performance_variation : t +val performance_variation_critical_cold_start : t + val pointer_size_mismatch : t val precondition_not_found : t diff --git a/infer/src/checkers/cost.ml b/infer/src/checkers/cost.ml index 5d16536e1..23d884435 100644 --- a/infer/src/checkers/cost.ml +++ b/infer/src/checkers/cost.ml @@ -718,7 +718,7 @@ module Check = struct Polynomials.TopTraces.make_err_trace trace - let report_threshold summary ~name ~location ~cost ~threshold ~kind = + let report_threshold proc_desc summary ~name ~location ~cost ~threshold ~kind = let degree_str = match BasicCost.degree cost with | Some degree -> @@ -731,7 +731,12 @@ module Check = struct | CostDomain.AllocationCost -> IssueType.expensive_allocation_call | CostDomain.OperationCost -> - IssueType.expensive_execution_time_call + L.(debug Analysis Medium) + "@\n\n++++++ Checking error type for %a **** @\n" Typ.Procname.pp + (Procdesc.get_proc_name proc_desc) ; + if ExternalPerfData.in_profiler_data_map (Procdesc.get_proc_name proc_desc) then + IssueType.expensive_execution_time_call_cold_start + else IssueType.expensive_execution_time_call | CostDomain.IOCost -> IssueType.expensive_IO_call in @@ -772,8 +777,8 @@ module Check = struct | ThresholdReports.Threshold _ -> () | ThresholdReports.ReportOn {location; cost} -> - report_threshold summary ~name ~location ~cost ~threshold:(Option.value_exn threshold) - ~kind ) ; + report_threshold proc_desc summary ~name ~location ~cost + ~threshold:(Option.value_exn threshold) ~kind ) ; CostDomain.CostKindMap.iter2 ReportConfig.as_map costs ~f:(fun _kind ReportConfig.{name; top_and_bottom} cost -> if top_and_bottom then report_top_and_bottom proc_desc summary ~name ~cost ) diff --git a/infer/tests/build_systems/differential_of_costs_report/Makefile b/infer/tests/build_systems/differential_of_costs_report/Makefile index 67961adcb..99ff5e9cc 100644 --- a/infer/tests/build_systems/differential_of_costs_report/Makefile +++ b/infer/tests/build_systems/differential_of_costs_report/Makefile @@ -6,7 +6,7 @@ # E2E test for differential of costs TESTS_DIR = ../.. -SOURCES = src/DiffExample.java.current src/DiffExample.java.previous +SOURCES = src/DiffExample.java.current src/DiffExample.java.previous src/DiffExampleColdStart.java.current src/DiffExampleColdStart.java.previous CLEAN_EXTRA = src/Diff*.java *.class include $(TESTS_DIR)/differential.make INFERPRINT_ISSUES_FIELDS = \ @@ -16,10 +16,12 @@ $(CURRENT_REPORT) $(PREVIOUS_REPORT): $(JAVA_DEPS) $(CURRENT_REPORT): $(QUIET)$(COPY) src/DiffExample.java.current src/DiffExample.java + $(QUIET)$(COPY) src/DiffExampleColdStart.java.current src/DiffExampleColdStart.java $(QUIET)$(call silent_on_success,Testing Cost Differential: current,\ $(INFER_BIN) --enable-issue-type INFINITE_EXECUTION_TIME_CALL --cost-only -o $(CURRENT_DIR) -- $(JAVAC) src/*.java) $(PREVIOUS_REPORT): $(QUIET)$(COPY) src/DiffExample.java.previous src/DiffExample.java + $(QUIET)$(COPY) src/DiffExampleColdStart.java.previous src/DiffExampleColdStart.java $(QUIET)$(call silent_on_success,Testing Cost Differential: previous,\ - $(INFER_BIN) --enable-issue-type INFINITE_EXECUTION_TIME_CALL --cost-only -o $(PREVIOUS_DIR) -- $(JAVAC) src/*.java) + $(INFER_BIN) --debug --enable-issue-type INFINITE_EXECUTION_TIME_CALL --cost-only -o $(PREVIOUS_DIR) -- $(JAVAC) src/*.java) diff --git a/infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp b/infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp index f15470489..9732fbb52 100644 --- a/infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp +++ b/infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp @@ -1 +1 @@ -{"top":{"current":2,"previous":1},"zero":{"current":0,"previous":0},"degrees":[{"degree":0,"current":3,"previous":2},{"degree":100,"current":1,"previous":2},{"degree":101,"current":2,"previous":0},{"degree":200,"current":0,"previous":2}]} \ No newline at end of file +{"top":{"current":4,"previous":2},"zero":{"current":0,"previous":0},"degrees":[{"degree":0,"current":6,"previous":4},{"degree":100,"current":2,"previous":4},{"degree":101,"current":4,"previous":0},{"degree":200,"current":0,"previous":4}]} \ No newline at end of file diff --git a/infer/tests/build_systems/differential_of_costs_report/fixed.exp b/infer/tests/build_systems/differential_of_costs_report/fixed.exp index 24833b948..b544aafc9 100644 --- a/infer/tests/build_systems/differential_of_costs_report/fixed.exp +++ b/infer/tests/build_systems/differential_of_costs_report/fixed.exp @@ -1 +1,2 @@ PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f6(java.util.ArrayList):void, 0, [Updated Cost is 5 + list.length × log(list.length) (degree is 1 + 1⋅log),{list.length},call to void DiffExample.f5(ArrayList),Modeled call to List.length,{list.length},call to void DiffExample.f5(ArrayList),Modeled call to List.length] +PERFORMANCE_VARIATION_COLD_START, no_bucket, src/DiffExampleColdStart.java, DiffExampleColdStart.f6(java.util.ArrayList):void, 0, [Updated Cost is 5 + list.length × log(list.length) (degree is 1 + 1⋅log),{list.length},call to void DiffExampleColdStart.f5(ArrayList),Modeled call to List.length,{list.length},call to void DiffExampleColdStart.f5(ArrayList),Modeled call to List.length] diff --git a/infer/tests/build_systems/differential_of_costs_report/introduced.exp b/infer/tests/build_systems/differential_of_costs_report/introduced.exp index 829386765..7e149c40b 100644 --- a/infer/tests/build_systems/differential_of_costs_report/introduced.exp +++ b/infer/tests/build_systems/differential_of_costs_report/introduced.exp @@ -1,3 +1,6 @@ INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExample.java, DiffExample.f1(int):void, 0, [Unbounded loop,Loop at line 26] PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f4(int):int, 0, [Updated Cost is 6 + 5 ⋅ k (degree is 1),{k},Loop at line 45] PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f5(java.util.ArrayList):void, 0, [Updated Cost is 2 + list.length × log(list.length) (degree is 1 + 1⋅log),{list.length},Modeled call to List.length,{list.length},Modeled call to List.length] +INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExampleColdStart.java, DiffExampleColdStart.f1(int):void, 0, [Unbounded loop,Loop at line 26] +PERFORMANCE_VARIATION_COLD_START, no_bucket, src/DiffExampleColdStart.java, DiffExampleColdStart.f4(int):int, 0, [Updated Cost is 6 + 5 ⋅ k (degree is 1),{k},Loop at line 45] +PERFORMANCE_VARIATION, no_bucket, src/DiffExampleColdStart.java, DiffExampleColdStart.f5(java.util.ArrayList):void, 0, [Updated Cost is 2 + list.length × log(list.length) (degree is 1 + 1⋅log),{list.length},Modeled call to List.length,{list.length},Modeled call to List.length] diff --git a/infer/tests/build_systems/differential_of_costs_report/loom_test.json b/infer/tests/build_systems/differential_of_costs_report/loom_test.json new file mode 100644 index 000000000..938a324e8 --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report/loom_test.json @@ -0,0 +1 @@ +[{"function_name":"DiffExampleColdStart::f1","count_trace_id":2,"sum_inclusive_cpu_time":44,"avg_inclusive_cpu_time_ms":22,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":22,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":22,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":22,"p25_exclusive_cpu_time_ms":0},{"function_name":"DiffExampleColdStart::f2","count_trace_id":1,"sum_inclusive_cpu_time":11,"avg_inclusive_cpu_time_ms":11,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":11,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":11,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":11,"p25_exclusive_cpu_time_ms":0},{"function_name":"DiffExampleColdStart::f3","count_trace_id":2,"sum_inclusive_cpu_time":44,"avg_inclusive_cpu_time_ms":22,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":22,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":22,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":22,"p25_exclusive_cpu_time_ms":0},{"function_name":"DiffExampleColdStart::f4","count_trace_id":2,"sum_inclusive_cpu_time":44,"avg_inclusive_cpu_time_ms":22,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":22,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":22,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":22,"p25_exclusive_cpu_time_ms":0},{"function_name":"DiffExampleColdStart::f55","count_trace_id":2,"sum_inclusive_cpu_time":44,"avg_inclusive_cpu_time_ms":22,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":22,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":22,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":22,"p25_exclusive_cpu_time_ms":0},{"function_name":"DiffExampleColdStart::f6","count_trace_id":2,"sum_inclusive_cpu_time":44,"avg_inclusive_cpu_time_ms":22,"sum_exclusive_cpu_time":0,"avg_exclusive_cpu_time_ms":0,"p90_inclusive_cpu_time_ms":22,"p90_exclusive_cpu_time_ms":0,"p50_inclusive_cpu_time_ms":22,"p50_exclusive_cpu_time_ms":0,"p25_inclusive_cpu_time_ms":22,"p25_exclusive_cpu_time_ms":0}] diff --git a/infer/tests/build_systems/differential_of_costs_report/preexisting.exp b/infer/tests/build_systems/differential_of_costs_report/preexisting.exp index 576624911..5102bbbd9 100644 --- a/infer/tests/build_systems/differential_of_costs_report/preexisting.exp +++ b/infer/tests/build_systems/differential_of_costs_report/preexisting.exp @@ -1 +1,2 @@ INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExample.java, DiffExample.f7(int):void, 0, [Call to void DiffExample.f1(int),Unbounded loop,Loop at line 26] +INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExampleColdStart.java, DiffExampleColdStart.f7(int):void, 0, [Call to void DiffExampleColdStart.f1(int),Unbounded loop,Loop at line 26] diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.current b/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.current new file mode 100644 index 000000000..7d990b4da --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.current @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import java.util.ArrayList; + +// This class has the following costs: +// 1 bottom (zero), 2 constant, 1 linear, 1 top +// constructor: constant +// f1: top +// f2: bottom (zero) +// f3: constant +// f4: linear +// f5: n log n +// f6: n log n +// f7: top by call to f1 + +public class DiffExampleColdStart { + + // cost: top + private static void f1(int k) { + int i = 0; + while (i >=0) { + i++; + } + } + + // cost: bottom (0) + private static void f2(int k) {} + + // cost: constant (5) + private static int f3() { + int i, j; + i = 17; + j = 31; + + return i + j + 3 + 7; + } + + // cost: linear + private static int f4(int k) { + for (int i = 0; i < k; i++) { + } + return 0; + } + + // cost: n log n + private void f5(ArrayList list) { + java.util.Collections.sort(list); + } + + // cost: n log n + private void f6(ArrayList list) { + f5(list); + } + + // cost: top by call to f1 + private static void f7(int k) { + f1(k); + } +} diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.previous b/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.previous new file mode 100644 index 000000000..228e886ee --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleColdStart.java.previous @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This class has the following costs: +// 2 constant, 1 linear, 1 quadratic +// constructor: constant +// f1: linear +// f2: quadratic +// f4: constant +// f5: linear +// f6: quadratic +// f7: top + +public class DiffExampleColdStart { + // cost: linear + private static int f1(int k) { + for (int i = 0; i < k; i++) { + } + return 0; + } + + // cost: quadratic + private static void f2(int k) { + for (int i = 0; i < k; i++) { + f1(k); + } + } + + // cost: constant + private static int f4(int k) { + int i = 1; + return i + k; + } + + // cost: linear + private static void f5(int n) { + f1(n); + } + + // cost: quadratic + private static void f6(int n) { + f2(n); + } + + // cost: top + private static void f7(int k) { + int i = 0; + while (i >=0) { + i++; + } + } +} diff --git a/infer/tests/differential.make b/infer/tests/differential.make index 8937fd8d5..8c7fa7d42 100644 --- a/infer/tests/differential.make +++ b/infer/tests/differential.make @@ -35,7 +35,7 @@ $(EXPECTED_TEST_OUTPUT): $(CURRENT_REPORT) $(PREVIOUS_REPORT) $(MODIFIED_FILES_F $(INFER_BIN) $(MAKEFILE_LIST) $(QUIET)$(REMOVE_DIR) $(INFER_OUT) $(QUIET)$(call silent_on_success,Computing results difference in $(TEST_REL_DIR),\ - $(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) reportdiff \ + $(INFER_BIN) --perf-profiler-data-file loom_test.json -o $(INFER_OUT) --project-root $(CURDIR) reportdiff \ --report-current $(CURRENT_REPORT) --report-previous $(PREVIOUS_REPORT) \ --costs-current $(CURRENT_COSTS) --costs-previous $(PREVIOUS_COSTS) \ $(DIFFERENTIAL_ARGS))