xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp (revision 6df32b8db1f0b2f1c91f3dbb62a0ced07c314aa9)
1 //===----- SymbolStringPoolTest.cpp - Unit tests for SymbolStringPool -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
10 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace llvm::orc;
15 
16 namespace llvm::orc {
17 
18 class SymbolStringPoolTest : public testing::Test {
19 public:
20   size_t getRefCount(const SymbolStringPtrBase &S) const {
21     return SP.getRefCount(S);
22   }
23 
24 protected:
25   SymbolStringPool SP;
26 };
27 } // namespace llvm::orc
28 
29 namespace {
30 
31 TEST_F(SymbolStringPoolTest, UniquingAndComparisons) {
32   auto P1 = SP.intern("hello");
33 
34   std::string S("hel");
35   S += "lo";
36   auto P2 = SP.intern(S);
37 
38   auto P3 = SP.intern("goodbye");
39 
40   EXPECT_EQ(P1, P2) << "Failed to unique entries";
41   EXPECT_NE(P1, P3) << "Unequal pooled symbol strings comparing equal";
42 
43   // We want to test that less-than comparison of SymbolStringPtrs compiles,
44   // however we can't test the actual result as this is a pointer comparison and
45   // SymbolStringPtr doesn't expose the underlying address of the string.
46   (void)(P1 < P3);
47 }
48 
49 TEST_F(SymbolStringPoolTest, Dereference) {
50   auto Foo = SP.intern("foo");
51   EXPECT_EQ(*Foo, "foo") << "Equality on dereferenced string failed";
52 }
53 
54 TEST_F(SymbolStringPoolTest, ClearDeadEntries) {
55   {
56     auto P1 = SP.intern("s1");
57     SP.clearDeadEntries();
58     EXPECT_FALSE(SP.empty()) << "\"s1\" entry in pool should still be retained";
59   }
60   SP.clearDeadEntries();
61   EXPECT_TRUE(SP.empty()) << "pool should be empty";
62 }
63 
64 TEST_F(SymbolStringPoolTest, DebugDump) {
65   auto A1 = SP.intern("a");
66   auto A2 = A1;
67   auto B = SP.intern("b");
68 
69   std::string DumpString;
70   raw_string_ostream(DumpString) << SP;
71 
72   EXPECT_EQ(DumpString, "a: 2\nb: 1\n");
73 }
74 
75 TEST_F(SymbolStringPoolTest, NonOwningPointerBasics) {
76   auto A = SP.intern("a");
77   auto B = SP.intern("b");
78 
79   NonOwningSymbolStringPtr ANP1(A);    // Constuct from SymbolStringPtr.
80   NonOwningSymbolStringPtr ANP2(ANP1); // Copy-construct.
81   NonOwningSymbolStringPtr BNP(B);
82 
83   // Equality comparisons.
84   EXPECT_EQ(A, ANP1);
85   EXPECT_EQ(ANP1, ANP2);
86   EXPECT_NE(ANP1, BNP);
87 
88   EXPECT_EQ(*ANP1, "a"); // Dereference.
89 
90   // Assignment.
91   ANP2 = ANP1;
92   ANP2 = A;
93 
94   SymbolStringPtr S(ANP1); // Construct SymbolStringPtr from non-owning.
95   EXPECT_EQ(S, A);
96 
97   DenseMap<SymbolStringPtr, int> M;
98   M[A] = 42;
99   EXPECT_EQ(M.find_as(ANP1)->second, 42);
100   EXPECT_EQ(M.find_as(BNP), M.end());
101 }
102 
103 TEST_F(SymbolStringPoolTest, NonOwningPointerRefCounts) {
104   // Check that creating and destroying non-owning pointers doesn't affect
105   // ref-counts.
106   auto A = SP.intern("a");
107   EXPECT_EQ(getRefCount(A), 1U);
108 
109   NonOwningSymbolStringPtr ANP(A);
110   EXPECT_EQ(getRefCount(ANP), 1U)
111       << "Construction of NonOwningSymbolStringPtr from SymbolStringPtr "
112          "changed ref-count";
113 
114   {
115     NonOwningSymbolStringPtr ANP2(ANP);
116     EXPECT_EQ(getRefCount(ANP2), 1U)
117         << "Copy-construction of NonOwningSymbolStringPtr changed ref-count";
118   }
119 
120   EXPECT_EQ(getRefCount(ANP), 1U)
121       << "Destruction of NonOwningSymbolStringPtr changed ref-count";
122 
123   {
124     NonOwningSymbolStringPtr ANP2;
125     ANP2 = ANP;
126     EXPECT_EQ(getRefCount(ANP2), 1U)
127         << "Copy-assignment of NonOwningSymbolStringPtr changed ref-count";
128   }
129 
130   {
131     NonOwningSymbolStringPtr ANP2(ANP);
132     NonOwningSymbolStringPtr ANP3(std::move(ANP2));
133     EXPECT_EQ(getRefCount(ANP3), 1U)
134         << "Move-construction of NonOwningSymbolStringPtr changed ref-count";
135   }
136 
137   {
138     NonOwningSymbolStringPtr ANP2(ANP);
139     NonOwningSymbolStringPtr ANP3;
140     ANP3 = std::move(ANP2);
141     EXPECT_EQ(getRefCount(ANP3), 1U)
142         << "Copy-assignment of NonOwningSymbolStringPtr changed ref-count";
143   }
144 }
145 } // namespace
146