summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/xray/tests/unit/segmented_array_test.cc
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2018-12-07 03:19:13 +0000
committerDean Michael Berris <dberris@google.com>2018-12-07 03:19:13 +0000
commit190c49bc8fd73dab0412dce3b85f50949184d5b5 (patch)
tree48d96905bb1adae78bab4a37f0e28946d242769a /compiler-rt/lib/xray/tests/unit/segmented_array_test.cc
parentb2a6f8e505b105c733d931e1ed0513d7ea94f6c8 (diff)
downloadbcm5719-llvm-190c49bc8fd73dab0412dce3b85f50949184d5b5.tar.gz
bcm5719-llvm-190c49bc8fd73dab0412dce3b85f50949184d5b5.zip
Re-land "[XRay] Move-only Allocator, FunctionCallTrie, and Array"
This reverts commit r348455, with some additional changes: - Work-around deficiency of gcc-4.8 by duplicating the implementation of `AppendEmplace` in `Append`, but instead of using brace-init for the copy construction, use a placement new explicitly calling the copy constructor. llvm-svn: 348563
Diffstat (limited to 'compiler-rt/lib/xray/tests/unit/segmented_array_test.cc')
-rw-r--r--compiler-rt/lib/xray/tests/unit/segmented_array_test.cc86
1 files changed, 86 insertions, 0 deletions
diff --git a/compiler-rt/lib/xray/tests/unit/segmented_array_test.cc b/compiler-rt/lib/xray/tests/unit/segmented_array_test.cc
index 80991b1b97a..73120aafc8e 100644
--- a/compiler-rt/lib/xray/tests/unit/segmented_array_test.cc
+++ b/compiler-rt/lib/xray/tests/unit/segmented_array_test.cc
@@ -221,5 +221,91 @@ TEST(SegmentedArrayTest, SimulateStackBehaviour) {
}
}
+TEST(SegmentedArrayTest, PlacementNewOnAlignedStorage) {
+ using AllocatorType = typename Array<ShadowStackEntry>::AllocatorType;
+ typename std::aligned_storage<sizeof(AllocatorType),
+ alignof(AllocatorType)>::type AllocatorStorage;
+ new (&AllocatorStorage) AllocatorType(1 << 10);
+ auto *A = reinterpret_cast<AllocatorType *>(&AllocatorStorage);
+ typename std::aligned_storage<sizeof(Array<ShadowStackEntry>),
+ alignof(Array<ShadowStackEntry>)>::type
+ ArrayStorage;
+ new (&ArrayStorage) Array<ShadowStackEntry>(*A);
+ auto *Data = reinterpret_cast<Array<ShadowStackEntry> *>(&ArrayStorage);
+
+ static uint64_t Dummy = 0;
+ constexpr uint64_t Max = 9;
+
+ for (uint64_t i = 0; i < Max; ++i) {
+ auto P = Data->Append({i, &Dummy});
+ ASSERT_NE(P, nullptr);
+ ASSERT_EQ(P->NodePtr, &Dummy);
+ auto &Back = Data->back();
+ ASSERT_EQ(Back.NodePtr, &Dummy);
+ ASSERT_EQ(Back.EntryTSC, i);
+ }
+
+ // Simulate a stack by checking the data from the end as we're trimming.
+ auto Counter = Max;
+ ASSERT_EQ(Data->size(), size_t(Max));
+ while (!Data->empty()) {
+ const auto &Top = Data->back();
+ uint64_t *TopNode = Top.NodePtr;
+ EXPECT_EQ(TopNode, &Dummy) << "Counter = " << Counter;
+ Data->trim(1);
+ --Counter;
+ ASSERT_EQ(Data->size(), size_t(Counter));
+ }
+
+ // Once the stack is exhausted, we re-use the storage.
+ for (uint64_t i = 0; i < Max; ++i) {
+ auto P = Data->Append({i, &Dummy});
+ ASSERT_NE(P, nullptr);
+ ASSERT_EQ(P->NodePtr, &Dummy);
+ auto &Back = Data->back();
+ ASSERT_EQ(Back.NodePtr, &Dummy);
+ ASSERT_EQ(Back.EntryTSC, i);
+ }
+
+ // We re-initialize the storage, by calling the destructor and
+ // placement-new'ing again.
+ Data->~Array();
+ A->~AllocatorType();
+ new (A) AllocatorType(1 << 10);
+ new (Data) Array<ShadowStackEntry>(*A);
+
+ // Then re-do the test.
+ for (uint64_t i = 0; i < Max; ++i) {
+ auto P = Data->Append({i, &Dummy});
+ ASSERT_NE(P, nullptr);
+ ASSERT_EQ(P->NodePtr, &Dummy);
+ auto &Back = Data->back();
+ ASSERT_EQ(Back.NodePtr, &Dummy);
+ ASSERT_EQ(Back.EntryTSC, i);
+ }
+
+ // Simulate a stack by checking the data from the end as we're trimming.
+ Counter = Max;
+ ASSERT_EQ(Data->size(), size_t(Max));
+ while (!Data->empty()) {
+ const auto &Top = Data->back();
+ uint64_t *TopNode = Top.NodePtr;
+ EXPECT_EQ(TopNode, &Dummy) << "Counter = " << Counter;
+ Data->trim(1);
+ --Counter;
+ ASSERT_EQ(Data->size(), size_t(Counter));
+ }
+
+ // Once the stack is exhausted, we re-use the storage.
+ for (uint64_t i = 0; i < Max; ++i) {
+ auto P = Data->Append({i, &Dummy});
+ ASSERT_NE(P, nullptr);
+ ASSERT_EQ(P->NodePtr, &Dummy);
+ auto &Back = Data->back();
+ ASSERT_EQ(Back.NodePtr, &Dummy);
+ ASSERT_EQ(Back.EntryTSC, i);
+ }
+}
+
} // namespace
} // namespace __xray
OpenPOWER on IntegriCloud