|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
|
|
|
|
NSString* mId;
|
|
|
|
NSCharacterSet* characterSet;
|
|
|
|
|
|
|
|
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(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(NSString* m) {
|
|
|
|
return [m rangeOfString:@"_"].location;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSUInteger rangeof_string_quadratic(NSString* m, NSString* n) {
|
|
|
|
return [m rangeOfString:n].location;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSString* has_prefix_constant() {
|
|
|
|
NSString* s = @"";
|
|
|
|
return [s hasPrefix:s] ? [s substringFromIndex:1] : s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void component_seperated_by_char_linear(NSString* m) {
|
|
|
|
NSArray* arrayOfComponents = [m componentsSeparatedByString:@","];
|
|
|
|
for (int i = 0; i < arrayOfComponents.count; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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_char_linear(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_with_bytes_linear(const void* bytes,
|
|
|
|
NSUInteger length,
|
|
|
|
NSStringEncoding encoding) {
|
|
|
|
NSString* s = [[NSString alloc] initWithBytes:bytes
|
|
|
|
length:length
|
|
|
|
encoding:encoding];
|
|
|
|
for (int i = 0; i < s.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_string_constant() {
|
|
|
|
NSString* str = [[NSString alloc] init];
|
|
|
|
for (int i = 0; i < str.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_with_string_constant() {
|
|
|
|
NSString* s = @"abcd";
|
|
|
|
NSString* str = [[NSString alloc] initWithString:s];
|
|
|
|
for (int i = 0; i < str.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_with_string_linear(NSString* s) {
|
|
|
|
NSString* str = [[NSString alloc] initWithString:s];
|
|
|
|
for (int i = 0; i < str.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void call_init_with_string_constant() {
|
|
|
|
NSString* s = [[NSString alloc] init];
|
|
|
|
init_with_string_linear(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void substring_no_end_linear(NSString* s, int x) {
|
|
|
|
NSString* sub = [s substringFromIndex:x];
|
|
|
|
for (int i = 0; i < sub.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void replace_linear_FP(NSString* s) {
|
|
|
|
NSString* r = [s stringByReplacingOccurrencesOfString:@"." withString:@","];
|
|
|
|
for (int i = 0; i < r.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NSString* string_with_utf8_string_linear(const char* p) {
|
|
|
|
NSString* s = [NSString stringWithUTF8String:p];
|
|
|
|
for (int i = 0; i < [s.length integerValue]; i++) {
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void string_length_linear(NSString* s) {
|
|
|
|
for (int i = 0; i < [s.length integerValue]; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool string_is_equal_to_string_linear(NSString* str1, NSString* str2) {
|
|
|
|
return [str1 isEqualToString:str2];
|
|
|
|
}
|
|
|
|
|
|
|
|
NSString* string_by_appending_path_component_linear(NSString* path,
|
|
|
|
NSString* file) {
|
|
|
|
return [path stringByAppendingPathComponent:file];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool string_has_prefix_linear(NSString* str, NSString* prefix) {
|
|
|
|
return [str hasPrefix:prefix];
|
|
|
|
}
|
|
|
|
|
|
|
|
void attributedstring_length_linear(NSAttributedString* s) {
|
|
|
|
for (int i = 0; i < s.length; i++) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void call_string_length_linear(NSAttributedString* s) {
|
|
|
|
string_length_linear(s.string);
|
|
|
|
}
|
|
|
|
|
|
|
|
void enumerateAttribute_quadratic(NSAttributedString* attributedString,
|
|
|
|
NSString* kCTFontAttributeName,
|
|
|
|
int x) {
|
|
|
|
[attributedString
|
|
|
|
enumerateAttribute:kCTFontAttributeName
|
|
|
|
inRange:NSMakeRange(0, [attributedString length])
|
|
|
|
options:
|
|
|
|
NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
|
|
|
usingBlock:^(id value, NSRange range, BOOL* stop) {
|
|
|
|
for (int i = 0; i <= x; i++) {
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
void enumerateAttribute_linear(NSAttributedString* attributedString,
|
|
|
|
NSString* kCTFontAttributeName,
|
|
|
|
int x) {
|
|
|
|
[attributedString
|
|
|
|
enumerateAttribute:kCTFontAttributeName
|
|
|
|
inRange:NSMakeRange(0, [attributedString length])
|
|
|
|
options:
|
|
|
|
NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
|
|
|
usingBlock:^(id value, NSRange range, BOOL* stop) {
|
|
|
|
int p = 0;
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
// FN because captured block variable is added as last argument which our model
|
|
|
|
// cannot recognize
|
|
|
|
void enumerateAttribute_via_block_captured_linear_FN(NSArray* array, int x) {
|
|
|
|
__block BOOL answer = NO;
|
|
|
|
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL* stop) {
|
|
|
|
answer = YES;
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
@interface DummyClass : NSObject
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation DummyClass
|
|
|
|
|
[cost] If the modeled cost is Top, underestimate the cost
Summary:
**Existing heuristic**: If we have a call `foo(n)` that has no model and summary for `foo`, we underestimate its cost as constant[1].
However, if we have a model for `foo` (e.g.with modeled cost O(n)) but applying the model to arguments causes the cost to be Top (e.g if `n` has Top size), then we could have Top-poisoning where all the callers up the call chain will have Top costs [2].
To prevent these unintended Top-poisioning when adding models, this diff applies *the same heuristic* to modeled calls with Top cost and gives them constant cost. This way, when adding models, we wouldn't be introducing more Tops than if we were to have no models in the first place.
[1] This is problematic in itself and causes many FPs at diff time, but otherwise we would be getting Tops everywhere and would not be able to give any meaningful cost. E.g. for fblite, if we were to give unknown calls Top cost, #procedures with Top cost increases form 5% to 38% and #procedures with linear cost reduces by 99.75%.
[2] This was observed for `containsValue` for Instagram where %Tops increased by 88% :(
Reviewed By: skcho
Differential Revision: D26174644
fbshipit-source-id: 232354923
4 years ago
|
|
|
+ (void)call_string_by_appending_string_constant {
|
|
|
|
NSString* s = [NSStringFromClass(self) stringByAppendingString:@"abc"];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|