You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.3 KiB

/*
* 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.
*/
#include <stdlib.h>
// Caricature of folly::basic_fbstring without the union between small
// and medium/large data representations, and with an explicit field
// for category_ instead of bitmasking part of the data value.
// ref:
// https://github.com/facebook/folly/blob/72850c2ebfb94d87bea74d89fcf79f3aaa91a627/folly/FBString.h
enum category {
small = 0, // ignore small strings for now
medium = 1,
large = 2,
};
void* checkedMalloc(size_t size) {
void* ptr = malloc(size);
if (ptr == nullptr) {
exit(1);
}
return ptr;
}
struct LikeFBString {
int category_;
char* buffer_;
size_t size_;
unsigned int refcount;
LikeFBString() {}
LikeFBString(const LikeFBString& src) {
category_ = src.category();
switch (src.category_) {
case medium:
copyMedium(src);
break;
case large:
copyLarge(src);
break;
default:
exit(2);
}
}
~LikeFBString() {
if (category() == medium) {
free(buffer_);
} else {
decr_ref_count();
}
}
void copySmall(const LikeFBString& src) {}
void copyMedium(const LikeFBString& src) {
buffer_ = (char*)checkedMalloc(src.size_);
size_ = src.size_;
}
void copyLarge(const LikeFBString& src) {
refcount++;
buffer_ = src.buffer_;
size_ = src.size_;
}
int category() const { return category_; }
void incr_ref_count() { refcount++; }
void decr_ref_count() {
refcount--;
if (refcount == 0) {
free(buffer_);
}
}
};
void copy_fbstring(LikeFBString& s) {
// this might alias the underlying buffers if the string is large in
// that case the destruction of t does not de-allocate its buffer
// but pulse might think it does if it fails to remember which
// category t belongs to and follows impossibly control flow
LikeFBString t = s;
}
void FP_pass_to_copy_ok() {
// Currently pulse follows impossible control flow and thinks the
// underlying buffer of s is freed twice: once per copy. That is
// caused by manual ref-counting in the case of large strings.
LikeFBString s;
copy_fbstring(s);
}