From 2d26236bed7c76881b9c9960a67028af444530df Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Fri, 4 Oct 2019 05:25:29 -0700 Subject: [PATCH] [infer] Eagerly try narrowing for the outermost loops Summary: This diff tries to narrowing the fixpoint of outermost loops, so that over-approximated widened values do not flow to the following code. Problem: There are two phases for finding a fixpoint, widening and narrowing. First, it finds a fixpoint with widening, in function level. After that, it finds a fixpoint with narrowing. A problem is that sometimes an overly-approximated, imprecise, values by widening are flowed to the following loops. They are hard to narrow in the narrowing phase because there is a cycle preventing it. To mitigate the problem, it tries to do narrowing, in loop level, right after it found a fixpoint of a loop. Thus, it narrows before the widened values are flowed to the following loops. In order to guarantee the termination of the analysis, this eager narrowing is applied only to the outermost loops. Reviewed By: ezgicicek Differential Revision: D17740265 fbshipit-source-id: e2d454036 --- infer/src/absint/AbstractInterpreter.ml | 64 +++++++++++++------ .../java/performance/ArrayListTest.java | 9 +-- .../codetoanalyze/java/performance/issues.exp | 31 ++++----- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/infer/src/absint/AbstractInterpreter.ml b/infer/src/absint/AbstractInterpreter.ml index 636d481b7..b0a7c211e 100644 --- a/infer/src/absint/AbstractInterpreter.ml +++ b/infer/src/absint/AbstractInterpreter.ml @@ -356,60 +356,88 @@ module MakeUsingWTO (TransferFunctions : TransferFunctions.SIL) = struct L.(die InternalError) "Could not compute the pre of a node" - let rec exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head ~is_narrowing + (* [WidenThenNarrow] mode is to narrow the outermost loops eagerly, so that over-approximated + widened values do not flow to the following code. + + Problem: There are two phases for finding a fixpoint, widening and narrowing. First, it finds + a fixpoint with widening, in function level. After that, it finds a fixpoint with narrowing. + A problem is that sometimes an overly-approximated, imprecise, values by widening are flowed to + the following loops. They are hard to narrow in the narrowing phase because there is a cycle + preventing it. + + To mitigate the problem, it tries to do narrowing, in loop level, right after it found a + fixpoint of a loop. Thus, it narrows before the widened values are flowed to the following + loops. In order to guarantee the termination of the analysis, this eager narrowing is applied + only to the outermost loops. *) + type mode = Widen | WidenThenNarrow | Narrow + + let is_narrowing_of = function Widen | WidenThenNarrow -> false | Narrow -> true + + let rec exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head ~mode ~is_first_visit rest = + let is_narrowing = is_narrowing_of mode in match exec_wto_node ~pp_instr cfg proc_data inv_map head ~is_loop_head ~is_narrowing with | inv_map, ReachedFixPoint -> if is_narrowing && is_first_visit then - exec_wto_rest ~pp_instr cfg proc_data inv_map head ~is_narrowing rest + exec_wto_rest ~pp_instr cfg proc_data inv_map head ~mode rest else inv_map | inv_map, DidNotReachFixPoint -> - exec_wto_rest ~pp_instr cfg proc_data inv_map head ~is_narrowing rest + exec_wto_rest ~pp_instr cfg proc_data inv_map head ~mode rest - and exec_wto_rest ~pp_instr cfg proc_data inv_map head ~is_narrowing rest = - let inv_map = exec_wto_partition ~pp_instr cfg proc_data ~is_narrowing inv_map rest in - exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:true ~is_narrowing + and exec_wto_rest ~pp_instr cfg proc_data inv_map head ~mode rest = + let inv_map = exec_wto_partition ~pp_instr cfg proc_data ~mode inv_map rest in + exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:true ~mode ~is_first_visit:false rest - and exec_wto_partition ~pp_instr cfg proc_data ~is_narrowing inv_map + and exec_wto_partition ~pp_instr cfg proc_data ~mode inv_map (partition : CFG.Node.t WeakTopologicalOrder.Partition.t) = match partition with | Empty -> inv_map | Node {node; next} -> let inv_map = - exec_wto_node ~pp_instr cfg proc_data ~is_narrowing inv_map node ~is_loop_head:false + exec_wto_node ~pp_instr cfg proc_data ~is_narrowing:(is_narrowing_of mode) inv_map node + ~is_loop_head:false |> fst in - exec_wto_partition ~pp_instr cfg proc_data ~is_narrowing inv_map next + exec_wto_partition ~pp_instr cfg proc_data ~mode inv_map next | Component {head; rest; next} -> let inv_map = - exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:false ~is_narrowing - ~is_first_visit:true rest + match mode with + | Widen | Narrow -> + exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:false ~mode + ~is_first_visit:true rest + | WidenThenNarrow -> + let inv_map = + exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:false + ~mode:Widen ~is_first_visit:true rest + in + exec_wto_component ~pp_instr cfg proc_data inv_map head ~is_loop_head:false + ~mode:Narrow ~is_first_visit:true rest in - exec_wto_partition ~pp_instr cfg proc_data ~is_narrowing inv_map next + exec_wto_partition ~pp_instr cfg proc_data ~mode inv_map next let exec_cfg_internal ~pp_instr cfg proc_data ~do_narrowing ~initial = let wto = CFG.wto cfg in - let exec_cfg ~is_narrowing inv_map = + let exec_cfg ~mode inv_map = match wto with | Empty -> inv_map (* empty cfg *) | Node {node= start_node; next} as wto -> if Config.write_html then debug_wto wto start_node ; let inv_map, _did_not_reach_fix_point = - exec_node ~pp_instr proc_data start_node ~is_loop_head:false ~is_narrowing initial - inv_map + exec_node ~pp_instr proc_data start_node ~is_loop_head:false + ~is_narrowing:(is_narrowing_of mode) initial inv_map in - exec_wto_partition ~pp_instr cfg proc_data ~is_narrowing inv_map next + exec_wto_partition ~pp_instr cfg proc_data ~mode inv_map next | Component _ -> L.(die InternalError) "Did not expect the start node to be part of a loop" in - let inv_map = exec_cfg ~is_narrowing:false InvariantMap.empty in - if do_narrowing then exec_cfg ~is_narrowing:true inv_map else inv_map + if do_narrowing then exec_cfg ~mode:WidenThenNarrow InvariantMap.empty |> exec_cfg ~mode:Narrow + else exec_cfg ~mode:Widen InvariantMap.empty let exec_cfg ?(do_narrowing = false) = exec_cfg_internal ~pp_instr:pp_sil_instr ~do_narrowing diff --git a/infer/tests/codetoanalyze/java/performance/ArrayListTest.java b/infer/tests/codetoanalyze/java/performance/ArrayListTest.java index 93b357324..6d3c9324c 100644 --- a/infer/tests/codetoanalyze/java/performance/ArrayListTest.java +++ b/infer/tests/codetoanalyze/java/performance/ArrayListTest.java @@ -42,9 +42,7 @@ public class ArrayListTest { list.add(4, 666); } - // We can set the size of the list to 10. The reason of FP is that the widened [i] value at the - // second loop is failed to be narrowed precisely. - public void arraylist_add_in_loop_FP() { + public void arraylist_add_in_loop() { ArrayList list = new ArrayList(); for (int i = 0; i < 10; ++i) { list.add(i); @@ -152,10 +150,7 @@ public class ArrayListTest { list.get(1); } - // we can't set the size of the list to 10 because it depends on how - // many times the loop is executed. Should be fixed once we have - // relational domain working. - public void arraylist_remove_in_loop_Good_FP() { + public void arraylist_remove_in_loop_Good() { ArrayList list = new ArrayList(); for (int i = 0; i < 10; ++i) { list.add(i); diff --git a/infer/tests/codetoanalyze/java/performance/issues.exp b/infer/tests/codetoanalyze/java/performance/issues.exp index d857e480e..80dc57d9a 100644 --- a/infer/tests/codetoanalyze/java/performance/issues.exp +++ b/infer/tests/codetoanalyze/java/performance/issues.exp @@ -18,36 +18,33 @@ codetoanalyze/java/performance/ArrayCost.java, ArrayCost.ArrayCost(int[]):void, codetoanalyze/java/performance/ArrayCost.java, ArrayCost.isPowOfTwo_FP(int):boolean, 4, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 883, O(1), degree = 0] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_add3_overrun_bad():void, 5, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Through,Through,Array access: Offset added: 4 Size: 3] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_addAll_bad():void, 10, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Through,Through,Array access: Offset added: 5 Size: 4] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_add_in_loop_FP():void, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop at line 52] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_add_in_loop_FP():void, 5, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [,Assignment,Binary operation: ([0, +oo] + 1):signed32] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_empty_overrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Array access: Offset added: 1 Size: 0] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_empty_underrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Array access: Offset added: -1 Size: 0] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_get_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Array access: Offset: 2 Size: 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_get_underrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Array access: Offset: 0 Size: 0] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_bad():void, 5, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Through,Through,Array access: Offset: 1 Size: 1] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_in_loop_Good_FP():void, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop at line 163] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_in_loop_Good_FP():void, 5, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [,Assignment,Binary operation: ([0, +oo] + 1):signed32] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_in_loop_Good_FP():void, 6, BUFFER_OVERRUN_L5, no_bucket, ERROR, [,Assignment,,Array declaration,Array access: Offset: [0, +oo] Size: [0, +oo]] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_in_loop_Good():void, 5, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 211, O(1), degree = 0] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_in_loop_Good():void, 6, BUFFER_OVERRUN_L5, no_bucket, ERROR, [,Assignment,,Array declaration,Array access: Offset: [0, 9] Size: [0, 10]] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Array access: Offset: 1 Size: 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Through,Array access: Offset: 1 Size: 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_underrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [,Array declaration,Array access: Offset: 0 Size: 0] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.boolean_control_var_linear():void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + 19 ⋅ this.arr.length + 4 ⋅ (this.arr.length + 1), O(this.arr.length), degree = 1,{this.arr.length + 1},Loop at line 294,{this.arr.length},Loop at line 294] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.boolean_control_var_linear():void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + 19 ⋅ this.arr.length + 4 ⋅ (this.arr.length + 1), O(this.arr.length), degree = 1,{this.arr.length + 1},Loop at line 289,{this.arr.length},Loop at line 289] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.call_sortArrayList(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + list.length × log(list.length), O(list.length × log(list.length)), degree = 1 + 1⋅log,{list.length},call to void ArrayListTest.sortArrayList(ArrayList),Modeled call to Collections.sort,{list.length},call to void ArrayListTest.sortArrayList(ArrayList),Modeled call to Collections.sort] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_add_all(java.util.ArrayList,java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 10 + 5 ⋅ (l.length + list.length) + 3 ⋅ (l.length + list.length + 1), O((l.length + list.length)), degree = 1,{l.length + list.length + 1},Loop at line 244,{l.length + list.length},Loop at line 244] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_add_all_sym(java.util.ArrayList,java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 10 + 5 ⋅ (l.length + list.length) + 3 ⋅ (l.length + list.length + 1), O((l.length + list.length)), degree = 1,{l.length + list.length + 1},Loop at line 251,{l.length + list.length},Loop at line 251] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_linear(java.util.ArrayList):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 226,{list.length},Loop at line 226] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_modify(java.util.ArrayList):void, 8, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 18 + 5 ⋅ (list.length + 4) + 3 ⋅ (list.length + 5), O(list.length), degree = 1,{list.length + 5},Loop at line 237,{list.length + 4},Loop at line 237] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_add_all(java.util.ArrayList,java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 10 + 5 ⋅ (l.length + list.length) + 3 ⋅ (l.length + list.length + 1), O((l.length + list.length)), degree = 1,{l.length + list.length + 1},Loop at line 239,{l.length + list.length},Loop at line 239] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_add_all_sym(java.util.ArrayList,java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 10 + 5 ⋅ (l.length + list.length) + 3 ⋅ (l.length + list.length + 1), O((l.length + list.length)), degree = 1,{l.length + list.length + 1},Loop at line 246,{l.length + list.length},Loop at line 246] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_linear(java.util.ArrayList):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 221,{list.length},Loop at line 221] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.constructor_modify(java.util.ArrayList):void, 8, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 18 + 5 ⋅ (list.length + 4) + 3 ⋅ (list.length + 5), O(list.length), degree = 1,{list.length + 5},Loop at line 232,{list.length + 4},Loop at line 232] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.empty_list_constant(int):void, 3, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 5 + 5 ⋅ list.length, O(list.length), degree = 1,{list.length},Loop at line 14] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_shortcut_FP(java.util.ArrayList):boolean, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 11 ⋅ list.length + 2 ⋅ list.length × (11-max(10, list.elements)) + 3 ⋅ (list.length + 1) × (11-max(10, list.elements)), O(list.length × (-list.elements + 11)), degree = 2,{11-max(10, list.elements)},Loop at line 192,{list.length + 1},Loop at line 192,{11-max(10, list.elements)},Loop at line 192,{list.length},Loop at line 192] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_with_inner(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 7 + 11 ⋅ list1.length + 3 ⋅ (list1.length + 1), O(list1.length), degree = 1,{list1.length + 1},Loop at line 183,{list1.length},Loop at line 183] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_shortcut_FP(java.util.ArrayList):boolean, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 11 ⋅ list.length + 2 ⋅ list.length × (11-max(10, list.elements)) + 3 ⋅ (list.length + 1) × (11-max(10, list.elements)), O(list.length × (-list.elements + 11)), degree = 2,{11-max(10, list.elements)},Loop at line 187,{list.length + 1},Loop at line 187,{11-max(10, list.elements)},Loop at line 187,{list.length},Loop at line 187] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_with_inner(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 7 + 11 ⋅ list1.length + 3 ⋅ (list1.length + 1), O(list1.length), degree = 1,{list1.length + 1},Loop at line 178,{list1.length},Loop at line 178] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_local_arraylist(java.util.ArrayList):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 7 + 5 ⋅ list.length, O(list.length), degree = 1,{list.length},Loop at line 19] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 10 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 175,{list.length},Loop at line 175] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 8 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 169,{list.length},Loop at line 169] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.json_array_constructor_linear(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ arr.length + 3 ⋅ (arr.length + 1), O(arr.length), degree = 1,{arr.length + 1},Loop at line 271,{arr.length},Loop at line 271] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.linear(int,java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 9 ⋅ (-i + a.length + 1), O((-i + a.length)), degree = 1,{-i + a.length + 1},Loop at line 278] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 10 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 170,{list.length},Loop at line 170] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 8 ⋅ list.length + 3 ⋅ (list.length + 1), O(list.length), degree = 1,{list.length + 1},Loop at line 164,{list.length},Loop at line 164] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.json_array_constructor_linear(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ arr.length + 3 ⋅ (arr.length + 1), O(arr.length), degree = 1,{arr.length + 1},Loop at line 266,{arr.length},Loop at line 266] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.linear(int,java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 9 ⋅ (-i + a.length + 1), O((-i + a.length)), degree = 1,{-i + a.length + 1},Loop at line 273] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.max_linear(java.util.ArrayList):Person, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 8 + people.length, O(people.length), degree = 1,{people.length},Modeled call to Collections.max] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.remove_string_from_list(java.lang.String):boolean, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ this.list.length + 3 ⋅ (this.list.length + 1), O(this.list.length), degree = 1,{this.list.length + 1},Loop at line 215,{this.list.length},Loop at line 215] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.remove_string_from_list(java.lang.String):boolean, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ this.list.length + 3 ⋅ (this.list.length + 1), O(this.list.length), degree = 1,{this.list.length + 1},Loop at line 210,{this.list.length},Loop at line 210] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.sortArrayList(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + list.length × log(list.length), O(list.length × log(list.length)), degree = 1 + 1⋅log,{list.length},Modeled call to Collections.sort,{list.length},Modeled call to Collections.sort] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.sort_comparator_nlogn(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 8 + people.length × log(people.length), O(people.length × log(people.length)), degree = 1 + 1⋅log,{people.length},Modeled call to Collections.sort,{people.length},Modeled call to Collections.sort] codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_constant(int):int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 10 + 7 ⋅ p, O(p), degree = 1,{p},call to int Break.break_loop(int,int),Loop at line 12]