[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