added allocation

Reviewed By: mbouaziz

Differential Revision: D14322430

fbshipit-source-id: 5c27a37db
master
Dino Distefano 6 years ago committed by Facebook Github Bot
parent 34a9d36d31
commit 3b8782a6c1

@ -28,7 +28,10 @@ module ReportConfig = struct
, { name= "The execution time" , { name= "The execution time"
; threshold= Option.some_if Config.use_cost_threshold 200 ; threshold= Option.some_if Config.use_cost_threshold 200
; top_and_bottom= true } ) ; top_and_bottom= true } )
; (CostDomain.AllocationCost, {name= "The allocations"; threshold= None; top_and_bottom= false}) ; ( CostDomain.AllocationCost
, { name= "The allocations"
; threshold= Option.some_if Config.use_cost_threshold 3
; top_and_bottom= false } )
; (CostDomain.IOCost, {name= "The IOs"; threshold= None; top_and_bottom= false}) ] ; (CostDomain.IOCost, {name= "The IOs"; threshold= None; top_and_bottom= false}) ]
@ -551,30 +554,41 @@ module InstrBasicCost = struct
For example for basic operation we set it to 1 and for function call we take it from the spec of the function. For example for basic operation we set it to 1 and for function call we take it from the spec of the function.
*) *)
let allocation_functions = [BuiltinDecl.__new]
let is_allocation_function callee_pname =
List.exists allocation_functions ~f:(fun f -> Typ.Procname.equal callee_pname f)
let get_instr_cost_record extras instr_node instr = let get_instr_cost_record extras instr_node instr =
match instr with match instr with
| Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) -> ( | Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) ->
let {inferbo_invariant_map; integer_type_widths; get_callee_summary_and_formals} = let {inferbo_invariant_map; integer_type_widths; get_callee_summary_and_formals} =
extras extras
in in
match let operation_cost =
BufferOverrunAnalysis.extract_pre (InstrCFG.Node.id instr_node) inferbo_invariant_map match
with BufferOverrunAnalysis.extract_pre (InstrCFG.Node.id instr_node) inferbo_invariant_map
| None -> with
CostDomain.unit_cost_atomic_operation | None ->
| Some inferbo_mem -> ( CostDomain.unit_cost_atomic_operation
let loc = InstrCFG.Node.loc instr_node in | Some inferbo_mem -> (
match CostModels.Call.dispatch () callee_pname params with let loc = InstrCFG.Node.loc instr_node in
| Some model -> match CostModels.Call.dispatch () callee_pname params with
CostDomain.of_operation_cost (model loc inferbo_mem) | Some model ->
| None -> ( CostDomain.of_operation_cost (model loc inferbo_mem)
match get_callee_summary_and_formals callee_pname with | None -> (
| Some ({CostDomain.post= callee_cost_record}, callee_formals) -> match get_callee_summary_and_formals callee_pname with
CostDomain.map callee_cost_record ~f:(fun callee_cost -> | Some ({CostDomain.post= callee_cost_record}, callee_formals) ->
instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem CostDomain.map callee_cost_record ~f:(fun callee_cost ->
~callee_pname ~callee_formals ~params ~callee_cost ~loc ) instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem
| None -> ~callee_pname ~callee_formals ~params ~callee_cost ~loc )
CostDomain.unit_cost_atomic_operation ) ) ) | None ->
CostDomain.unit_cost_atomic_operation ) )
in
if is_allocation_function callee_pname then
CostDomain.plus CostDomain.unit_cost_allocation operation_cost
else operation_cost
| Sil.Load _ | Sil.Store _ | Sil.Call _ | Sil.Prune _ -> | Sil.Load _ | Sil.Store _ | Sil.Call _ | Sil.Prune _ ->
CostDomain.unit_cost_atomic_operation CostDomain.unit_cost_atomic_operation
| Sil.ExitScope _ -> ( | Sil.ExitScope _ -> (

@ -91,6 +91,9 @@ let plus cost_record1 cost_record2 =
(* Map representing cost record {OperationCost:1; AllocationCost:0; IOCost:0} *) (* Map representing cost record {OperationCost:1; AllocationCost:0; IOCost:0} *)
let unit_cost_atomic_operation = VariantCostMap.increment OperationCost zero_record let unit_cost_atomic_operation = VariantCostMap.increment OperationCost zero_record
(* Map representing cost record {OperationCost:0; AllocationCost:1; IOCost:0} *)
let unit_cost_allocation = VariantCostMap.increment AllocationCost zero_record
(* Map representing cost record {OperationCost:operation_cost; AllocationCost:0; IOCost:0} *) (* Map representing cost record {OperationCost:operation_cost; AllocationCost:0; IOCost:0} *)
let of_operation_cost operation_cost = let of_operation_cost operation_cost =
VariantCostMap.increase_by OperationCost operation_cost zero_record VariantCostMap.increase_by OperationCost operation_cost zero_record

@ -0,0 +1,21 @@
/*
* Copyright (c) 2019-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.
*/
public class A {}
class B {
void error() {
A a1 = new A();
A a2 = new A();
A a3 = new A();
A a4 = new A();
}
void ok() {
A a1 = new A();
}
}

@ -1,3 +1,4 @@
codetoanalyze/java/performance/A.java, B.error():void, 4, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 4, degree = 0]
codetoanalyze/java/performance/Array.java, codetoanalyze.java.performance.Array.array_access_overrun_bad():void, 4, BUFFER_OVERRUN_L2, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Assignment,Array access: Offset: [2, 8] Size: 8] codetoanalyze/java/performance/Array.java, codetoanalyze.java.performance.Array.array_access_overrun_bad():void, 4, BUFFER_OVERRUN_L2, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Assignment,Array access: Offset: [2, 8] Size: 8]
codetoanalyze/java/performance/Array.java, codetoanalyze.java.performance.Array.array_access_weird_ok(long[],int):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 15 ⋅ length, degree = 1,{length},Loop at line 28] codetoanalyze/java/performance/Array.java, codetoanalyze.java.performance.Array.array_access_weird_ok(long[],int):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 15 ⋅ length, degree = 1,{length},Loop at line 28]
codetoanalyze/java/performance/ArrayCost.java, ArrayCost.ArrayCost(int[]):void, 5, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ mag.length, degree = 1,{mag.length},Loop at line 15] codetoanalyze/java/performance/ArrayCost.java, ArrayCost.ArrayCost(int[]):void, 5, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ mag.length, degree = 1,{mag.length},Loop at line 15]

Loading…
Cancel
Save