summaryrefslogtreecommitdiff
path: root/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp
blob: 02bb95001acd42427f145cb35bd31a10ebe04ebd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//===- llvm/unittest/DWARFLinkerParallel/StringTableTest.cpp --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/DWARFLinkerParallel/StringTable.h"
#include "llvm/Support/Parallel.h"
#include "gtest/gtest.h"
#include <cstdlib>

using namespace llvm;
using namespace dwarflinker_parallel;

namespace {

TEST(StringPoolTest, TestStringTable) {
  struct StringDescription {
    const char *Str = nullptr;
    uint64_t Idx = 0;
    uint64_t Offset = 0;
  };

  SmallVector<StringDescription> InputStrings = {
      {"first", 0, 0}, {"second", 1, 6}, {"third", 2, 13}};

  StringPool Strings;
  StringTable OutStrings(Strings, nullptr);

  // StringPool uses PerThreadBumpPtrAllocator which should be accessed from
  // threads created by ThreadPoolExecutor. Use TaskGroup to run on
  // ThreadPoolExecutor threads.
  parallel::TaskGroup tg;

  tg.spawn([&]() {
    // Check string insertion.
    StringEntry *FirstPtr = Strings.insert(InputStrings[0].Str).first;
    StringEntry *SecondPtr = Strings.insert(InputStrings[1].Str).first;
    StringEntry *ThirdPtr = Strings.insert(InputStrings[2].Str).first;

    FirstPtr = OutStrings.add(FirstPtr);
    SecondPtr = OutStrings.add(SecondPtr);
    ThirdPtr = OutStrings.add(ThirdPtr);

    // Check fields of inserted strings.
    EXPECT_TRUE(FirstPtr->getKey() == InputStrings[0].Str);
    EXPECT_TRUE(FirstPtr->getValue()->Offset == InputStrings[0].Offset);
    EXPECT_TRUE(FirstPtr->getValue()->Index == InputStrings[0].Idx);

    EXPECT_TRUE(SecondPtr->getKey() == InputStrings[1].Str);
    EXPECT_TRUE(SecondPtr->getValue()->Offset == InputStrings[1].Offset);
    EXPECT_TRUE(SecondPtr->getValue()->Index == InputStrings[1].Idx);

    EXPECT_TRUE(ThirdPtr->getKey() == InputStrings[2].Str);
    EXPECT_TRUE(ThirdPtr->getValue()->Offset == InputStrings[2].Offset);
    EXPECT_TRUE(ThirdPtr->getValue()->Index == InputStrings[2].Idx);

    // Check order enumerated strings.
    uint64_t CurIdx = 0;
    std::function<void(DwarfStringPoolEntryRef)> checkStr =
        [&](DwarfStringPoolEntryRef Entry) {
          EXPECT_TRUE(Entry.getEntry().isIndexed());
          EXPECT_TRUE(Entry.getIndex() == CurIdx);
          EXPECT_TRUE(Entry.getOffset() == InputStrings[CurIdx].Offset);
          EXPECT_TRUE(Entry.getString() == InputStrings[CurIdx].Str);

          CurIdx++;
        };

    OutStrings.forEach(checkStr);
  });
}

TEST(StringPoolTest, TestStringTableWithTranslator) {
  std::string Word;
  std::function<StringRef(StringRef)> TranslatorFunc =
      [&](StringRef InputString) -> StringRef {
    Word.clear();
    for (auto Sym : InputString)
      Word.insert(Word.begin(), Sym);
    Word += '0';
    return Word;
  };

  StringPool Strings;
  StringTable OutStrings(Strings, TranslatorFunc);

  // StringPool uses PerThreadBumpPtrAllocator which should be accessed from
  // threads created by ThreadPoolExecutor. Use TaskGroup to run on
  // ThreadPoolExecutor threads.
  parallel::TaskGroup tg;

  tg.spawn([&]() {
    StringEntry *FirstPtr = Strings.insert("first").first;
    StringEntry *SecondPtr = Strings.insert("second").first;
    StringEntry *ThirdPtr = Strings.insert("third").first;

    FirstPtr = OutStrings.add(FirstPtr);
    SecondPtr = OutStrings.add(SecondPtr);
    ThirdPtr = OutStrings.add(ThirdPtr);

    EXPECT_TRUE(FirstPtr->getKey() == "tsrif0");
    EXPECT_TRUE(FirstPtr->getValue()->Offset == 0);
    EXPECT_TRUE(FirstPtr->getValue()->Index == 0);

    EXPECT_TRUE(SecondPtr->getKey() == "dnoces0");
    EXPECT_TRUE(SecondPtr->getValue()->Offset == 7);
    EXPECT_TRUE(SecondPtr->getValue()->Index == 1);

    EXPECT_TRUE(ThirdPtr->getKey() == "driht0");
    EXPECT_TRUE(ThirdPtr->getValue()->Offset == 15);
    EXPECT_TRUE(ThirdPtr->getValue()->Index == 2);
  });
}

} // anonymous namespace