proxygen
UninitializedMemoryHacksTest.cpp File Reference
#include <folly/memory/UninitializedMemoryHacks.h>
#include <algorithm>
#include <string>
#include <vector>
#include <folly/Memory.h>
#include <folly/Random.h>
#include <folly/portability/GTest.h>
#include <glog/logging.h>

Go to the source code of this file.

Functions

void describePlatform ()
 
template<typename T >
T validData (T const &target, std::vector< bool > const &valid)
 
template<typename T >
void doResizeWithoutInit (T &target, std::vector< bool > &valid, std::size_t newSize)
 
template<typename T >
void doOverwrite (T &target, std::vector< bool > &valid, std::size_t b, std::size_t e)
 
template<typename T >
void doResize (T &target, std::vector< bool > &valid, std::size_t newSize)
 
template<typename T >
void doClear (T &target, std::vector< bool > &valid)
 
template<typename T >
void doInsert (T &target, std::vector< bool > &valid, std::size_t i)
 
template<typename T >
void doErase (T &target, std::vector< bool > &valid, std::size_t i)
 
template<typename T >
void doPushBack (T &target, std::vector< bool > &valid)
 
template<typename T >
void genericCheck (T &target)
 
template<typename T >
void check (T &target)
 
template<>
void check< std::string > (std::string &target)
 
template<typename T >
void testSimple ()
 
template<typename T >
void testRandom (size_t numSteps=10000)
 
 TEST (UninitializedMemoryHacks, simpleString)
 
 TEST (UninitializedMemoryHacks, simpleVectorChar)
 
 TEST (UninitializedMemoryHacks, simpleVectorByte)
 
 TEST (UninitializedMemoryHacks, simpleVectorInt)
 
 TEST (UninitializedMemoryHacks, randomString)
 
 TEST (UninitializedMemoryHacks, randomVectorChar)
 
 TEST (UninitializedMemoryHacks, randomVectorByte)
 
 TEST (UninitializedMemoryHacks, randomVectorInt)
 

Function Documentation

template<typename T >
void check ( T target)

Definition at line 164 of file UninitializedMemoryHacksTest.cpp.

References genericCheck().

Referenced by testRandom(), and testSimple().

164  {
165  genericCheck(target);
166 }
void genericCheck(T &target)
template<>
void check< std::string > ( std::string target)

Definition at line 169 of file UninitializedMemoryHacksTest.cpp.

References EXPECT_EQ, and genericCheck().

169  {
170  genericCheck(target);
171  EXPECT_EQ(target.c_str(), target.data());
172  EXPECT_EQ(target.c_str()[target.size()], '\0');
173 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
void genericCheck(T &target)
void describePlatform ( )

Definition at line 28 of file UninitializedMemoryHacksTest.cpp.

References string.

Referenced by testRandom(), and testSimple().

28  {
29  LOG(INFO) << "sizeof(void*) = " << sizeof(void*);
30 
31  LOG(INFO) << "sizeof(std::string) = " << sizeof(std::string);
32 #if defined(_LIBCPP_STRING)
33  LOG(INFO) << "std::string from libc++";
34 #elif defined(_STLP_STRING)
35  LOG(INFO) << "std::string from STLport";
36 #elif defined(_GLIBCXX_USE_FB)
37  LOG(INFO) << "std::string from FBString";
38 #elif defined(_GLIBCXX_STRING) && _GLIBCXX_USE_CXX11_ABI
39  LOG(INFO) << "std::string from libstdc++ with SSO";
40 #elif defined(_GLIBCXX_STRING)
41  LOG(INFO) << "std::string from old libstdc++";
42 #elif defined(_MSC_VER)
43  LOG(INFO) << "std::string from MSVC";
44 #else
45  LOG(INFO) << "UNKNOWN std::string implementation";
46 #endif
47 
48  LOG(INFO) << "sizeof(std::vector<char>) = " << sizeof(std::vector<char>);
49 #if defined(_LIBCPP_VECTOR)
50  LOG(INFO) << "std::vector from libc++";
51 #elif defined(_STLP_VECTOR)
52  LOG(INFO) << "std::vector from STLport";
53 #elif defined(_GLIBCXX_VECTOR)
54  LOG(INFO) << "std::vector from libstdc++";
55 #elif defined(_MSC_VER)
56  LOG(INFO) << "std::vector from MSVC";
57 #else
58  LOG(INFO) << "UNKNOWN std::vector implementation";
59 #endif
60 }
const char * string
Definition: Conv.cpp:212
template<typename T >
void doClear ( T target,
std::vector< bool > &  valid 
)

Definition at line 127 of file UninitializedMemoryHacksTest.cpp.

Referenced by testRandom().

127  {
128  target.clear();
129  valid.clear();
130 }
template<typename T >
void doErase ( T target,
std::vector< bool > &  valid,
std::size_t  i 
)

Definition at line 139 of file UninitializedMemoryHacksTest.cpp.

References i.

Referenced by testRandom().

139  {
140  target.erase(target.begin() + i);
141  valid.erase(valid.begin() + i);
142 }
template<typename T >
void doInsert ( T target,
std::vector< bool > &  valid,
std::size_t  i 
)

Definition at line 133 of file UninitializedMemoryHacksTest.cpp.

References i.

Referenced by testRandom().

133  {
134  target.insert(target.begin() + i, 'I');
135  valid.insert(valid.begin() + i, true);
136 }
template<typename T >
void doOverwrite ( T target,
std::vector< bool > &  valid,
std::size_t  b,
std::size_t  e 
)

Definition at line 94 of file UninitializedMemoryHacksTest.cpp.

References i.

Referenced by testRandom(), and testSimple().

98  {
99  for (auto i = b; i < e && i < target.size(); ++i) {
100  target[i] = '0' + (i % 10);
101  valid[i] = true;
102  }
103 }
char b
template<typename T >
void doPushBack ( T target,
std::vector< bool > &  valid 
)

Definition at line 145 of file UninitializedMemoryHacksTest.cpp.

Referenced by testRandom().

145  {
146  target.push_back('P');
147  valid.push_back(true);
148 }
template<typename T >
void doResize ( T target,
std::vector< bool > &  valid,
std::size_t  newSize 
)

Definition at line 106 of file UninitializedMemoryHacksTest.cpp.

References EXPECT_EQ, EXPECT_GE, EXPECT_LT, EXPECT_TRUE, i, and validData().

Referenced by testRandom(), and testSimple().

106  {
107  auto oldSize = target.size();
108  auto before = validData(target, valid);
109  target.resize(newSize);
110  valid.resize(newSize);
111  for (auto i = oldSize; i < newSize; ++i) {
112  valid[i] = true;
113  }
114  auto after = validData(target, valid);
115  if (oldSize == newSize) {
116  EXPECT_EQ(before, after);
117  } else if (oldSize < newSize) {
118  EXPECT_LT(before.size(), after.size());
119  EXPECT_TRUE(std::equal(before.begin(), before.end(), after.begin()));
120  } else {
121  EXPECT_GE(before.size(), after.size());
122  EXPECT_TRUE(std::equal(after.begin(), after.end(), before.begin()));
123  }
124 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
T validData(T const &target, std::vector< bool > const &valid)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_LT(val1, val2)
Definition: gtest.h:1930
template<typename T >
void doResizeWithoutInit ( T target,
std::vector< bool > &  valid,
std::size_t  newSize 
)

Definition at line 76 of file UninitializedMemoryHacksTest.cpp.

References EXPECT_EQ, EXPECT_GE, EXPECT_TRUE, folly::resizeWithoutInitialization(), and validData().

Referenced by testRandom(), and testSimple().

79  {
80  auto oldSize = target.size();
81  auto before = validData(target, valid);
82  folly::resizeWithoutInitialization(target, newSize);
83  valid.resize(newSize);
84  auto after = validData(target, valid);
85  if (oldSize <= newSize) {
86  EXPECT_EQ(before, after);
87  } else {
88  EXPECT_GE(before.size(), after.size());
89  EXPECT_TRUE(std::equal(after.begin(), after.end(), before.begin()));
90  }
91 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
T validData(T const &target, std::vector< bool > const &valid)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void resizeWithoutInitialization(std::string &s, std::size_t n)
template<typename T >
void genericCheck ( T target)

Definition at line 151 of file UninitializedMemoryHacksTest.cpp.

References EXPECT_EQ, and EXPECT_LE.

Referenced by check(), and check< std::string >().

151  {
152  EXPECT_LE(target.size(), target.capacity());
153  EXPECT_EQ(target.size() == 0, target.empty());
154  EXPECT_EQ(target.size(), target.end() - target.begin());
155  EXPECT_EQ(target.size(), target.cend() - target.cbegin());
156  if (!target.empty()) {
157  EXPECT_EQ(target.data(), &target[0]);
158  EXPECT_EQ(target.data(), &target.front());
159  EXPECT_EQ(target.data() + target.size() - 1, &target.back());
160  }
161 }
#define EXPECT_LE(val1, val2)
Definition: gtest.h:1928
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST ( UninitializedMemoryHacks  ,
simpleString   
)

Definition at line 283 of file UninitializedMemoryHacksTest.cpp.

283  {
284  testSimple<std::string>();
285 }
TEST ( UninitializedMemoryHacks  ,
simpleVectorChar   
)

Definition at line 287 of file UninitializedMemoryHacksTest.cpp.

287  {
288  testSimple<std::vector<char>>();
289 }
TEST ( UninitializedMemoryHacks  ,
simpleVectorByte   
)

Definition at line 291 of file UninitializedMemoryHacksTest.cpp.

291  {
292  testSimple<std::vector<uint8_t>>();
293 }
TEST ( UninitializedMemoryHacks  ,
simpleVectorInt   
)

Definition at line 295 of file UninitializedMemoryHacksTest.cpp.

295  {
296  testSimple<std::vector<int>>();
297 }
TEST ( UninitializedMemoryHacks  ,
randomString   
)

Definition at line 299 of file UninitializedMemoryHacksTest.cpp.

299  {
300  testRandom<std::string>();
301 }
TEST ( UninitializedMemoryHacks  ,
randomVectorChar   
)

Definition at line 303 of file UninitializedMemoryHacksTest.cpp.

303  {
304  testRandom<std::vector<char>>();
305 }
TEST ( UninitializedMemoryHacks  ,
randomVectorByte   
)

Definition at line 307 of file UninitializedMemoryHacksTest.cpp.

307  {
308  testRandom<std::vector<uint8_t>>();
309 }
TEST ( UninitializedMemoryHacks  ,
randomVectorInt   
)

Definition at line 311 of file UninitializedMemoryHacksTest.cpp.

311  {
312  testRandom<std::vector<int>>();
313 }
template<typename T >
void testRandom ( size_t  numSteps = 10000)

Definition at line 221 of file UninitializedMemoryHacksTest.cpp.

References check(), folly::copy(), describePlatform(), doClear(), doErase(), doInsert(), doOverwrite(), doPushBack(), doResize(), doResizeWithoutInit(), i, max, min, folly::gen::move, folly::Random::rand32(), folly::resizeWithoutInitialization(), folly::f14::swap(), T, and uint32_t.

221  {
223 
224  auto target = folly::make_unique<T>();
225  std::vector<bool> valid;
226 
227  for (size_t step = 0; step < numSteps; ++step) {
228  auto pct = folly::Random::rand32(100);
230 
231  if (pct < 5) {
232  doClear(*target, valid);
233  } else if (pct < 30) {
234  T copy;
235  folly::resizeWithoutInitialization(copy, target->size());
236  for (size_t i = 0; i < copy.size(); ++i) {
237  if (valid[i]) {
238  copy[i] = target->at(i);
239  }
240  }
241  if (pct < 10) {
242  std::swap(copy, *target);
243  } else if (pct < 15) {
244  *target = std::move(copy);
245  } else if (pct < 20) {
246  *target = copy;
247  } else if (pct < 25) {
248  target = folly::make_unique<T>(std::move(copy));
249  } else {
250  target = folly::make_unique<T>(copy);
251  }
252  } else if (pct < 35) {
253  target->reserve(v);
254  } else if (pct < 40) {
255  target->shrink_to_fit();
256  } else if (pct < 45) {
257  doResize(*target, valid, v);
258  } else if (pct < 50) {
259  doInsert(*target, valid, v % (target->size() + 1));
260  } else if (pct < 55) {
261  if (!target->empty()) {
262  doErase(*target, valid, v % target->size());
263  }
264  } else if (pct < 60) {
265  doPushBack(*target, valid);
266  } else if (pct < 65) {
267  target = folly::make_unique<T>();
268  valid.clear();
269  } else if (pct < 80) {
271  doOverwrite(*target, valid, std::min(v, v2), std::max(v, v2));
272  } else {
273  doResizeWithoutInit(*target, valid, v);
274  }
275 
276  // don't check every time in implementation does lazy work
277  if (folly::Random::rand32(100) < 50) {
278  check(*target);
279  }
280  }
281 }
#define T(v)
Definition: http_parser.c:233
void describePlatform()
LogLevel max
Definition: LogLevel.cpp:31
void doPushBack(T &target, std::vector< bool > &valid)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void doResize(T &target, std::vector< bool > &valid, std::size_t newSize)
void doResizeWithoutInit(T &target, std::vector< bool > &valid, std::size_t newSize)
void doOverwrite(T &target, std::vector< bool > &valid, std::size_t b, std::size_t e)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
void doClear(T &target, std::vector< bool > &valid)
void doErase(T &target, std::vector< bool > &valid, std::size_t i)
LogLevel min
Definition: LogLevel.cpp:30
void check(T &target)
void doInsert(T &target, std::vector< bool > &valid, std::size_t i)
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
Definition: F14TestUtil.h:414
static uint32_t rand32()
Definition: Random.h:213
void resizeWithoutInitialization(std::string &s, std::size_t n)
template<typename T >
void testSimple ( )

Definition at line 176 of file UninitializedMemoryHacksTest.cpp.

References check(), describePlatform(), doOverwrite(), doResize(), doResizeWithoutInit(), i, sizes, and T.

Referenced by proxygen::RFC1867Base::parse(), proxygen::TEST_F(), and proxygen::TEST_P().

176  {
178 
179  auto sizes = {0, 1, 10, 14, 15, 16, 17, 22, 23, 24, 32, 95, 100, 10000};
180  for (auto i : sizes) {
181  for (auto j : sizes) {
182  {
183  T target;
184  std::vector<bool> valid;
185  doResize(target, valid, i);
186  doResizeWithoutInit(target, valid, j);
187  check(target);
188  }
189 
190  {
191  T target;
192  std::vector<bool> valid;
193  doResize(target, valid, i);
194  doResizeWithoutInit(target, valid, j);
195  doOverwrite(target, valid, i, j);
196  check(target);
197  }
198 
199  {
200  T target;
201  std::vector<bool> valid;
202  doResizeWithoutInit(target, valid, i);
203  doResize(target, valid, j);
204  doOverwrite(target, valid, i / 2, i / 2);
205  check(target);
206  }
207 
208  {
209  T target;
210  std::vector<bool> valid;
211  doResizeWithoutInit(target, valid, i);
212  doResize(target, valid, j);
213  doOverwrite(target, valid, i, j);
214  check(target);
215  }
216  }
217  }
218 }
#define T(v)
Definition: http_parser.c:233
void describePlatform()
void doResize(T &target, std::vector< bool > &valid, std::size_t newSize)
void doResizeWithoutInit(T &target, std::vector< bool > &valid, std::size_t newSize)
void doOverwrite(T &target, std::vector< bool > &valid, std::size_t b, std::size_t e)
const int sizes[]
void check(T &target)
template<typename T >
T validData ( T const &  target,
std::vector< bool > const &  valid 
)

Definition at line 64 of file UninitializedMemoryHacksTest.cpp.

References EXPECT_EQ, i, and T.

Referenced by doResize(), and doResizeWithoutInit().

64  {
65  EXPECT_EQ(target.size(), valid.size());
66  T rv;
67  for (std::size_t i = 0; i < valid.size(); ++i) {
68  if (valid[i]) {
69  rv.push_back(target[i]);
70  }
71  }
72  return rv;
73 }
#define T(v)
Definition: http_parser.c:233
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922