[compiler-rt] r344880 - [XRay] Handle allocator exhaustion in segmented array

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 21 19:11:27 PDT 2018


Author: dberris
Date: Sun Oct 21 19:11:27 2018
New Revision: 344880

URL: http://llvm.org/viewvc/llvm-project?rev=344880&view=rev
Log:
[XRay] Handle allocator exhaustion in segmented array

Summary:
This change allows us to handle allocator exhaustion properly in the
segmented array implementation. Before this change, we relied on the
caller of the `trim` function to provide a valid number of elements to
trim. This change allows us to do the right thing in case the elements
to trim is greater than the size of the container.

Reviewers: mboerger, eizan

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D53484

Modified:
    compiler-rt/trunk/lib/xray/tests/unit/segmented_array_test.cc
    compiler-rt/trunk/lib/xray/tests/unit/test_helpers.h
    compiler-rt/trunk/lib/xray/xray_segmented_array.h

Modified: compiler-rt/trunk/lib/xray/tests/unit/segmented_array_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/tests/unit/segmented_array_test.cc?rev=344880&r1=344879&r2=344880&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/tests/unit/segmented_array_test.cc (original)
+++ compiler-rt/trunk/lib/xray/tests/unit/segmented_array_test.cc Sun Oct 21 19:11:27 2018
@@ -1,9 +1,13 @@
+#include "test_helpers.h"
 #include "xray_segmented_array.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 namespace __xray {
 namespace {
 
+using ::testing::SizeIs;
+
 struct TestData {
   s64 First;
   s64 Second;
@@ -12,6 +16,10 @@ struct TestData {
   TestData(s64 F, s64 S) : First(F), Second(S) {}
 };
 
+void PrintTo(const TestData &D, std::ostream *OS) {
+  *OS << "{ " << D.First << ", " << D.Second << " }";
+}
+
 TEST(SegmentedArrayTest, ConstructWithAllocators) {
   using AllocatorType = typename Array<TestData>::AllocatorType;
   AllocatorType A(1 << 4);
@@ -161,6 +169,23 @@ TEST(SegmentedArrayTest, IteratorTrimBeh
   EXPECT_EQ(Data.size(), SegmentX2);
 }
 
+TEST(SegmentedArrayTest, HandleExhaustedAllocator) {
+  using AllocatorType = typename Array<TestData>::AllocatorType;
+  constexpr auto Segment = Array<TestData>::SegmentSize;
+  constexpr auto MaxElements = Array<TestData>::ElementsPerSegment;
+  AllocatorType A(Segment);
+  Array<TestData> Data(A);
+  for (auto i = MaxElements; i > 0u; --i)
+    EXPECT_NE(Data.AppendEmplace(static_cast<s64>(i), static_cast<s64>(i)),
+              nullptr);
+  EXPECT_EQ(Data.AppendEmplace(0, 0), nullptr);
+  EXPECT_THAT(Data, SizeIs(MaxElements));
+
+  // Trimming more elements than there are in the container should be fine.
+  Data.trim(MaxElements + 1);
+  EXPECT_THAT(Data, SizeIs(0u));
+}
+
 struct ShadowStackEntry {
   uint64_t EntryTSC = 0;
   uint64_t *NodePtr = nullptr;

Modified: compiler-rt/trunk/lib/xray/tests/unit/test_helpers.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/tests/unit/test_helpers.h?rev=344880&r1=344879&r2=344880&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/tests/unit/test_helpers.h (original)
+++ compiler-rt/trunk/lib/xray/tests/unit/test_helpers.h Sun Oct 21 19:11:27 2018
@@ -14,8 +14,9 @@
 #define COMPILER_RT_LIB_XRAY_TESTS_TEST_HELPERS_H_
 
 #include "xray_buffer_queue.h"
-#include "llvm/XRay/XRayRecord.h"
+#include "xray_segmented_array.h"
 #include "llvm/XRay/Trace.h"
+#include "llvm/XRay/XRayRecord.h"
 #include "gmock/gmock.h"
 
 // TODO: Move these to llvm/include/Testing/XRay/...
@@ -54,6 +55,19 @@ namespace __xray {
 
 std::string serialize(BufferQueue &Buffers, int32_t Version);
 
+template <class T> void PrintTo(const Array<T> &A, std::ostream *OS) {
+  *OS << "[";
+  bool first = true;
+  for (const auto &E : A) {
+    if (!first) {
+      *OS << ", ";
+    }
+    PrintTo(E, OS);
+    first = false;
+  }
+  *OS << "]";
+}
+
 } // namespace __xray
 
 #endif // COMPILER_RT_LIB_XRAY_TESTS_TEST_HELPERS_H_

Modified: compiler-rt/trunk/lib/xray/xray_segmented_array.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_segmented_array.h?rev=344880&r1=344879&r2=344880&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_segmented_array.h (original)
+++ compiler-rt/trunk/lib/xray/xray_segmented_array.h Sun Oct 21 19:11:27 2018
@@ -78,6 +78,8 @@ public:
 
   static SegmentBase SentinelSegment;
 
+  using size_type = size_t;
+
 private:
   AllocatorType *Alloc;
   SegmentBase *Head = &SentinelSegment;
@@ -334,9 +336,8 @@ public:
     if (Elements == 0)
       return;
 
-    DCHECK_LE(Elements, Size);
-    DCHECK_GT(Size, 0);
     auto OldSize = Size;
+    Elements = Elements >= Size ? Size : Elements;
     Size -= Elements;
 
     DCHECK_NE(Head, &SentinelSegment);
@@ -346,8 +347,11 @@ public:
                                 nearest_boundary(Size, ElementsPerSegment)) /
                                ElementsPerSegment;
          SegmentsToTrim > 0; --SegmentsToTrim) {
-      DCHECK_NE(Head, &SentinelSegment);
-      DCHECK_NE(Tail, &SentinelSegment);
+
+      // We want to short-circuit if the trace is already empty.
+      if (Head == &SentinelSegment && Head == Tail)
+        return;
+
       // Put the tail into the Freelist.
       auto *FreeSegment = Tail;
       Tail = Tail->Prev;




More information about the llvm-commits mailing list