[cost] add more inferbo and cost analysis models for NSString

Summary: As title

Reviewed By: skcho

Differential Revision: D22663505

fbshipit-source-id: 61ee2d346
master
Qianyi Shu 5 years ago committed by Facebook GitHub Bot
parent 829c5da6b2
commit 2547a75b8b

@ -1365,6 +1365,8 @@ module JavaString = struct
end
module NSString = struct
let fn = JavaString.fn
let create_string_from_c_string src_exp =
let exec model_env ~ret mem =
let v = Sem.eval_string_len src_exp mem in
@ -1373,9 +1375,39 @@ module NSString = struct
{exec; check= no_check}
let substring_from_index = JavaString.substring_no_end
let length = JavaString.length
(** For cost analysis *)
let get_length = JavaString.get_length
let concat = JavaString.concat
let split exp =
let exec ({location} as model_env) ~ret:((id, _) as ret) mem =
let itv =
ArrObjCommon.eval_size model_env exp ~fn mem
|> JavaString.range_itv_one_max_one_mone |> Dom.Val.of_itv
in
let {exec} = malloc ~can_be_zero:false Exp.one in
let mem = exec model_env ~ret mem in
let dest_loc = Loc.of_id id |> PowLoc.singleton in
Dom.Mem.transform_mem ~f:(Dom.Val.set_array_length location ~length:itv) dest_loc mem
in
{exec; check= no_check}
let append_string str1_exp str2_exp =
let exec ({location} as model_env) ~ret:_ mem =
let to_add_len = JavaString.get_length model_env str2_exp mem |> Dom.Val.get_itv in
let arr_locs = JavaString.deref_of model_env str1_exp mem in
let mem = Dom.Mem.forget_size_alias arr_locs mem in
Dom.Mem.transform_mem
~f:(Dom.Val.transform_array_length location ~f:(Itv.plus to_add_len))
arr_locs mem
in
{exec; check= no_check}
end
module Preconditions = struct
@ -1543,6 +1575,11 @@ module Call = struct
; -"NSString" &:: "stringWithUTF8String:" <>$ capt_exp
$!--> NSString.create_string_from_c_string
; -"NSString" &:: "length" <>$ capt_exp $--> NSString.length
; -"NSString" &:: "stringByAppendingString:" <>$ capt_exp $+ capt_exp $!--> NSString.concat
; -"NSString" &:: "substringFromIndex:" <>$ capt_exp $+ capt_exp
$--> NSString.substring_from_index
; -"NSString" &:: "appendString:" <>$ capt_exp $+ capt_exp $--> NSString.append_string
; -"NSString" &:: "componentsSeparatedByString:" <>$ capt_exp $+ any_arg $--> NSString.split
; (* C++ models *)
-"boost" &:: "split"
$ capt_arg_of_typ (-"std" &:: "vector")

@ -141,14 +141,19 @@ module BoundsOfArray = BoundsOf (CostUtils.Array)
module BoundsOfCString = BoundsOf (CostUtils.CString)
module NSString = struct
let op_on_two_str cost_op ~of_function str1 str2 ({location} as model_env) ~ret:_ mem =
let get_length str =
let itv =
BufferOverrunModels.NSString.get_length model_env str mem |> BufferOverrunDomain.Val.get_itv
in
CostUtils.of_itv ~itv ~degree_kind:Polynomials.DegreeKind.Linear ~of_function location
let get_length str ~of_function ({location} as model_env) ~ret:_ mem =
let itv =
BufferOverrunModels.NSString.get_length model_env str mem |> BufferOverrunDomain.Val.get_itv
in
CostUtils.of_itv ~itv ~degree_kind:Polynomials.DegreeKind.Linear ~of_function location
let op_on_two_str cost_op ~of_function str1 str2 model_env ~ret mem =
let get_length str = get_length str ~of_function model_env ~ret mem in
cost_op (get_length str1) (get_length str2)
let substring_from_index = JavaString.substring_no_end
end
module ImmutableSet = struct
@ -167,6 +172,9 @@ module Call = struct
$--> BoundsOfCString.linear_length ~of_function:"google::StrLen"
; -"NSString" &:: "stringWithUTF8String:" <>$ capt_exp
$--> BoundsOfCString.linear_length ~of_function:"NSString.stringWithUTF8String:"
; -"NSString" &:: "stringByAppendingString:" <>$ capt_exp $+ capt_exp
$--> NSString.op_on_two_str BasicCost.plus
~of_function:"NSString.stringByAppendingString:"
; -"NSString" &:: "stringByAppendingPathComponent:" <>$ capt_exp $+ capt_exp
$--> NSString.op_on_two_str BasicCost.plus
~of_function:"NSString.stringByAppendingPathComponent:"
@ -175,6 +183,15 @@ module Call = struct
~of_function:"NSString.isEqualToString:"
; -"NSString" &:: "hasPrefix:" <>$ capt_exp $+ capt_exp
$--> NSString.op_on_two_str BasicCost.min_default_left ~of_function:"NSString.hasPrefix:"
; -"NSString" &:: "substringFromIndex:" <>$ capt_exp $+ capt_exp
$!--> NSString.substring_from_index
; -"NSString" &:: "rangeOfString:" <>$ capt_exp $+ capt_exp
$!--> NSString.op_on_two_str BasicCost.mult ~of_function:"NSString.rangeOfString:"
; -"NSMutableString" &:: "appendString:" <>$ any_arg $+ capt_exp
$--> NSString.get_length ~of_function:"NSMutableString.appendString:"
; -"NSString" &:: "componentsSeparatedByString:" <>$ capt_exp $+ capt_exp
$--> NSString.op_on_two_str BasicCost.mult
~of_function:"NSString.componentsSeparatedByString:"
; +PatternMatch.implements_collections
&:: "sort" $ capt_exp
$+...$--> BoundsOfCollection.n_log_n_length ~of_function:"Collections.sort"

@ -0,0 +1,21 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
void nsmstring_append_string_constant(NSMutableString* str) {
[str appendString:@"hello"];
for (int i = 0; i < str.length; i++) {
}
}
void nsmstring_append_string_linear(NSMutableString* str1, NSString* str2) {
[str1 appendString:str2];
for (int i = 0; i < str1.length; i++) {
}
}

@ -9,43 +9,48 @@
NSString* mId;
NSCharacterSet* characterSet;
NSString* string_by_appending_same_string_linear_FN(NSString* s) {
NSString* string_by_appending_same_string_linear(NSString* s) {
NSString* str = [s stringByAppendingString:@"me"];
for (int i = 0; i < str.length; i++) {
}
return str;
}
NSString* string_by_appending_string_linear_FN(NSString* s, NSString* m) {
NSString* string_by_appending_string_linear(NSString* s, NSString* m) {
NSString* str = [s stringByAppendingString:m];
for (int i = 0; i < str.length; i++) {
}
return str;
}
NSUInteger rangeof_character_from_set_linear_FN(NSString* m) {
NSUInteger rangeof_character_from_set_linear(NSString* m) {
return [m rangeOfString:@"_"].location;
}
NSUInteger rangeof_string_quadratic_FN(NSString* m, NSString* n) {
NSUInteger rangeof_string_quadratic(NSString* m, NSString* n) {
return [m rangeOfString:n].location;
}
NSString* substring_from_index_linear_FN() {
NSUInteger index = rangeof_character_from_set_linear_FN(mId);
return [mId substringToIndex:index];
}
NSString* has_prefix_constant() {
NSString* s = @"";
return [s hasPrefix:s] ? [s substringFromIndex:1] : s;
}
void component_seperated_by_string_linear_FP(NSString* m) {
void component_seperated_by_char_linear(NSString* m) {
NSArray* arrayOfComponents = [m componentsSeparatedByString:@","];
for (int i = 0; i < arrayOfComponents.count; i++) {
}
}
void call_component_separated_by_string_constant_FP() {
void component_seperated_by_string_linear(NSString* m, NSString* sep) {
NSArray* arrayOfComponents = [m componentsSeparatedByString:sep];
for (int i = 0; i < arrayOfComponents.count; i++) {
}
}
void call_component_separated_by_char_constant() {
NSString* s = @"hello";
component_seperated_by_string_linear_FP(s);
component_seperated_by_char_linear(s);
}
void init_with_bytes_linear_FP(const void* bytes,
@ -76,7 +81,7 @@ void call_init_with_string_constant_FP() {
init_with_string_linear_FP(s);
}
void substring_no_end_linear_FP(NSString* s, int x) {
void substring_no_end_linear(NSString* s, int x) {
NSString* sub = [s substringFromIndex:x];
for (int i = 0; i < sub.length; i++) {
}

@ -49,25 +49,27 @@ codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_constant, 4, OnUI
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_constant_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_linear, 3 + 11 ⋅ array.length + 3 ⋅ (array.length + 1), OnUIThread:false, [{array.length + 1},Loop,{array.length},Loop]
codetoanalyze/objc/performance/NSMutableDictionary.m, nsmutabledictionary_set_element_in_loop_linear_FN, 14, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, call_component_separated_by_string_constant_FP, , OnUIThread:false, [Call to component_seperated_by_string_linear_FP,Unbounded loop,Loop]
codetoanalyze/objc/performance/NSMutableString.m, nsmstring_append_string_constant, 14 + 3 ⋅ str.length.ub + 3 ⋅ (str.length.ub + 1), OnUIThread:false, [{str.length.ub + 1},Loop,{str.length.ub},Loop]
codetoanalyze/objc/performance/NSMutableString.m, nsmstring_append_string_linear, 5 + str2.length.ub + 3 ⋅ str1.length.ub + 3 ⋅ (str1.length.ub + 1), OnUIThread:false, [{str1.length.ub + 1},Loop,{str1.length.ub},Loop,{str2.length.ub},Modeled call to NSMutableString.appendString:]
codetoanalyze/objc/performance/NSString.m, call_component_separated_by_char_constant, 46, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, call_init_with_string_constant_FP, , OnUIThread:false, [Call to init_with_string_linear_FP,Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, component_seperated_by_string_linear_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, component_seperated_by_char_linear, 6 + m.length.ub + 3 ⋅ (-1+max(2, m.length.ub)) + 3 ⋅ (max(2, m.length.ub)), OnUIThread:false, [{max(2, m.length.ub)},Loop,{-1+max(2, m.length.ub)},Loop,{m.length.ub},Modeled call to NSString.componentsSeparatedByString:]
codetoanalyze/objc/performance/NSString.m, component_seperated_by_string_linear, 6 + sep.length.ub × m.length.ub + 3 ⋅ (-1+max(2, m.length.ub)) + 3 ⋅ (max(2, m.length.ub)), OnUIThread:false, [{max(2, m.length.ub)},Loop,{-1+max(2, m.length.ub)},Loop,{m.length.ub},Modeled call to NSString.componentsSeparatedByString:,{sep.length.ub},Modeled call to NSString.componentsSeparatedByString:]
codetoanalyze/objc/performance/NSString.m, has_prefix_constant, 13, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, init_with_bytes_linear_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, init_with_string_constant_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, init_with_string_linear_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, rangeof_character_from_set_linear_FN, 6, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, rangeof_string_quadratic_FN, 6, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, rangeof_character_from_set_linear, 5 + m.length.ub, OnUIThread:false, [{m.length.ub},Modeled call to NSString.rangeOfString:]
codetoanalyze/objc/performance/NSString.m, rangeof_string_quadratic, 5 + n.length.ub × m.length.ub, OnUIThread:false, [{m.length.ub},Modeled call to NSString.rangeOfString:,{n.length.ub},Modeled call to NSString.rangeOfString:]
codetoanalyze/objc/performance/NSString.m, replace_linear_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, string_by_appending_path_component_linear, 4 + path.length.ub + file.length.ub, OnUIThread:false, [{file.length.ub},Modeled call to NSString.stringByAppendingPathComponent:,{path.length.ub},Modeled call to NSString.stringByAppendingPathComponent:]
codetoanalyze/objc/performance/NSString.m, string_by_appending_same_string_linear_FN, 8, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, string_by_appending_string_linear_FN, 7, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, string_by_appending_same_string_linear, 11 + s.length.ub + 3 ⋅ (s.length.ub + 2) + 3 ⋅ (s.length.ub + 3), OnUIThread:false, [{s.length.ub + 3},Loop,{s.length.ub + 2},Loop,{s.length.ub},Modeled call to NSString.stringByAppendingString:]
codetoanalyze/objc/performance/NSString.m, string_by_appending_string_linear, 8 + m.length.ub + 3 ⋅ (m.length.ub + s.length.ub) + s.length.ub + 3 ⋅ (m.length.ub + s.length.ub + 1), OnUIThread:false, [{m.length.ub + s.length.ub + 1},Loop,{s.length.ub},Modeled call to NSString.stringByAppendingString:,{m.length.ub + s.length.ub},Loop,{m.length.ub},Modeled call to NSString.stringByAppendingString:]
codetoanalyze/objc/performance/NSString.m, string_has_prefix_linear, 4 + str.length.ub, OnUIThread:false, [{str.length.ub},Modeled call to NSString.hasPrefix:]
codetoanalyze/objc/performance/NSString.m, string_is_equal_to_string_linear, 4 + str1.length.ub, OnUIThread:false, [{str1.length.ub},Modeled call to NSString.isEqualToString:]
codetoanalyze/objc/performance/NSString.m, string_length_linear, 3 + 3 ⋅ s.length.ub + 4 ⋅ (s.length.ub + 1), OnUIThread:false, [{s.length.ub + 1},Loop,{s.length.ub},Loop]
codetoanalyze/objc/performance/NSString.m, string_with_utf8_string_linear, 7 + 3 ⋅ p->strlen.ub + p->strlen.ub + 4 ⋅ (p->strlen.ub + 1), OnUIThread:false, [{p->strlen.ub + 1},Loop,{p->strlen.ub},Modeled call to NSString.stringWithUTF8String:,{p->strlen.ub},Loop]
codetoanalyze/objc/performance/NSString.m, substring_from_index_linear_FN, 13, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, substring_no_end_linear_FP, , OnUIThread:false, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, substring_no_end_linear, 10 + 6 ⋅ (-x + s.length.ub), OnUIThread:false, [{-x + s.length.ub},Loop]
codetoanalyze/objc/performance/araii.m, Araii.buffer, 4, OnUIThread:false, []
codetoanalyze/objc/performance/araii.m, Araii.dealloc, 4, OnUIThread:false, []
codetoanalyze/objc/performance/araii.m, Araii.initWithBuffer, 15, OnUIThread:false, []

@ -22,10 +22,7 @@ codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_reomove_constant, 5, B
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_constant_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_constant_FP, 6, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_linear, 2, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSNumber.intValue,Binary operation: ([-oo, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSString.m, call_component_separated_by_string_constant_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Call to component_seperated_by_string_linear_FP,Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, call_init_with_string_constant_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Call to init_with_string_linear_FP,Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, component_seperated_by_string_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, component_seperated_by_string_linear_FP, 2, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSString.m, init_with_bytes_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, init_with_bytes_linear_FP, 6, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSString.initWithBytes:length:encoding:,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSString.m, init_with_string_constant_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
@ -34,8 +31,6 @@ codetoanalyze/objc/performance/NSString.m, init_with_string_linear_FP, 0, INFINI
codetoanalyze/objc/performance/NSString.m, init_with_string_linear_FP, 2, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSString.initWithString:,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSString.m, replace_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, replace_linear_FP, 2, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSString.stringByReplacingOccurrencesOfString:withString:,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/NSString.m, substring_no_end_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, substring_no_end_linear_FP, 2, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSString.substringFromIndex:,Binary operation: ([0, +oo] + 1):signed32]
codetoanalyze/objc/performance/block.m, objc_blockblock_multiply_array_linear_FN_1, 3, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Unknown value from: NSArray.nextObject,Assignment,Binary operation: ([-oo, +oo] + [-oo, +oo]):signed64]
codetoanalyze/objc/performance/compound_loop_guard.m, compound_while, 3, CONDITION_ALWAYS_TRUE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/compound_loop_guard.m, nested_while_and_or_constant, 3, CONDITION_ALWAYS_TRUE, no_bucket, WARNING, [Here]

Loading…
Cancel
Save