File: SymbolStringPool.h

package info (click to toggle)
llvm-toolchain-6.0 1%3A6.0.1-10
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 598,080 kB
  • sloc: cpp: 3,046,253; ansic: 595,057; asm: 271,965; python: 128,926; objc: 106,554; sh: 21,906; lisp: 10,191; pascal: 6,094; ml: 5,544; perl: 5,265; makefile: 2,227; cs: 2,027; xml: 686; php: 212; csh: 117
file content (136 lines) | stat: -rw-r--r-- 3,347 bytes parent folder | download
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Contains a multi-threaded string pool suitable for use with ORC.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
#define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H

#include "llvm/ADT/StringMap.h"
#include <atomic>
#include <mutex>

namespace llvm {
namespace orc {

class SymbolStringPtr;

/// @brief String pool for symbol names used by the JIT.
class SymbolStringPool {
  friend class SymbolStringPtr;
public:
  /// @brief Create a symbol string pointer from the given string.
  SymbolStringPtr intern(StringRef S);

  /// @brief Remove from the pool any entries that are no longer referenced.
  void clearDeadEntries();

  /// @brief Returns true if the pool is empty.
  bool empty() const;
private:
  using RefCountType = std::atomic<uint64_t>;
  using PoolMap = StringMap<RefCountType>;
  using PoolMapEntry = StringMapEntry<RefCountType>;
  mutable std::mutex PoolMutex;
  PoolMap Pool;
};

/// @brief Pointer to a pooled string representing a symbol name.
class SymbolStringPtr {
  friend class SymbolStringPool;
public:
  SymbolStringPtr() = default;
  SymbolStringPtr(const SymbolStringPtr &Other)
    : S(Other.S) {
    if (S)
      ++S->getValue();
  }

  SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
    if (S)
      --S->getValue();
    S = Other.S;
    if (S)
      ++S->getValue();
    return *this;
  }

  SymbolStringPtr(SymbolStringPtr &&Other) : S(nullptr) {
    std::swap(S, Other.S);
  }

  SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
    if (S)
      --S->getValue();
    S = nullptr;
    std::swap(S, Other.S);
    return *this;
  }

  ~SymbolStringPtr() {
    if (S)
      --S->getValue();
  }

  bool operator==(const SymbolStringPtr &Other) const {
    return S == Other.S;
  }

  bool operator!=(const SymbolStringPtr &Other) const {
    return !(*this == Other);
  }

  bool operator<(const SymbolStringPtr &Other) const {
    return S->getValue() < Other.S->getValue();
  }

private:

  SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
      : S(S) {
    if (S)
      ++S->getValue();
  }

  SymbolStringPool::PoolMapEntry *S = nullptr;
};

inline SymbolStringPtr SymbolStringPool::intern(StringRef S) {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  auto I = Pool.find(S);
  if (I != Pool.end())
    return SymbolStringPtr(&*I);

  bool Added;
  std::tie(I, Added) = Pool.try_emplace(S, 0);
  assert(Added && "Insert should always succeed here");
  return SymbolStringPtr(&*I);
}

inline void SymbolStringPool::clearDeadEntries() {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
    auto Tmp = std::next(I);
    if (I->second == 0)
      Pool.erase(I);
    I = Tmp;
  }
}

inline bool SymbolStringPool::empty() const {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  return Pool.empty();
}

} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H