Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(794)

Side by Side Diff: src/IceStringPool.h

Issue 1838753002: Subzero: Remove IceString. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceRegistersARM32.h ('k') | src/IceSwitchLowering.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- subzero/src/IceStringPool.h - String pooling -------------*- C++ -*-===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief Defines unique pooled strings with short unique IDs. This makes
12 /// hashing, equality testing, and ordered comparison faster, and avoids a lot
13 /// of memory allocation compared to directly using std::string.
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #ifndef SUBZERO_SRC_ICESTRINGPOOL_H
18 #define SUBZERO_SRC_ICESTRINGPOOL_H
19
20 #include <cstdint> // uintptr_t
21 #include <string>
22
23 namespace Ice {
24
25 class StringPool {
26 StringPool(const StringPool &) = delete;
27 StringPool &operator=(const StringPool &) = delete;
28
29 public:
30 using IDType = uintptr_t;
31
32 StringPool() = default;
33 ~StringPool() = default;
34 IDType getNewID() {
35 // TODO(stichnot): Make it so that the GlobalString ctor doesn't have to
36 // grab the lock, and instead does an atomic increment of NextID.
37 auto NewID = NextID;
38 NextID += IDIncrement;
39 return NewID;
40 }
41 IDType getOrAddString(const std::string &Value) {
42 auto Iter = StringToId.find(Value);
43 if (Iter == StringToId.end()) {
44 auto *NewStr = new std::string(Value);
45 auto ID = reinterpret_cast<IDType>(NewStr);
46 StringToId[Value].reset(NewStr);
47 return ID;
48 }
49 return reinterpret_cast<IDType>(Iter->second.get());
50 }
51 void dump(Ostream &Str) const {
52 if (StringToId.empty())
53 return;
54 Str << "String pool (NumStrings=" << StringToId.size()
55 << " NumIDs=" << ((NextID - FirstID) / IDIncrement) << "):";
56 for (const auto &Tuple : StringToId) {
57 Str << " " << Tuple.first;
58 }
59 Str << "\n";
60 }
61
62 private:
63 static constexpr IDType FirstID = 1;
64 static constexpr IDType IDIncrement = 2;
65 IDType NextID = FirstID;
66 std::unordered_map<std::string, std::unique_ptr<std::string>> StringToId;
67 };
68
69 template <typename Traits> class StringID {
70 public:
71 using IDType = StringPool::IDType;
72
73 StringID() = default; // Create a default, invalid StringID.
74 StringID(const StringID &) = default;
75 StringID &operator=(const StringID &) = default;
76
77 /// Create a unique StringID without an actual string, by grabbing the next
78 /// unique integral ID from the Owner.
79 static StringID createWithoutString(const typename Traits::OwnerType *Owner) {
80 return StringID(Owner);
81 }
82 /// Create a unique StringID that holds an actual string, by fetching or
83 /// adding the string from the Owner's pool.
84 static StringID createWithString(const typename Traits::OwnerType *Owner,
85 const std::string &Value) {
86 return StringID(Owner, Value);
87 }
88
89 /// Tests whether the StringID was initialized with respect to an actual
90 /// std::string value, i.e. via StringID::createWithString().
91 bool hasStdString() const { return isValid() && ((ID & 0x1) == 0); }
92
93 IDType getID() const {
94 assert(isValid());
95 return ID;
96 }
97 const std::string &toString() const {
98 if (!hasStdString())
99 llvm::report_fatal_error(
100 "toString() called when hasStdString() is false");
101 return *reinterpret_cast<std::string *>(ID);
102 }
103 std::string toStringOrEmpty() const {
104 if (hasStdString())
105 return toString();
106 return "";
107 }
108
109 bool operator==(const StringID &Other) const { return ID == Other.ID; }
110 bool operator!=(const StringID &Other) const { return !(*this == Other); }
111 bool operator<(const StringID &Other) const {
112 const bool ThisHasString = hasStdString();
113 const bool OtherHasString = Other.hasStdString();
114 // Do a normal string comparison if both have strings.
115 if (ThisHasString && OtherHasString)
116 return this->toString() < Other.toString();
117 // Use the ID as a tiebreaker if neither has a string.
118 if (!ThisHasString && !OtherHasString)
119 return ID < Other.ID;
120 // If exactly one has a string, then that one comes first.
121 assert(!OtherHasString);
122 return ThisHasString;
123 }
124
125 private:
126 static constexpr IDType InvalidID = 0;
127 IDType ID = InvalidID;
128
129 explicit StringID(const typename Traits::OwnerType *Owner)
130 : ID(Traits::getStrings(Owner)->getNewID()) {}
131 StringID(const typename Traits::OwnerType *Owner, const std::string &Value)
132 : ID(Traits::getStrings(Owner)->getOrAddString(Value)) {
133 assert(hasStdString());
134 }
135 bool isValid() const { return ID != InvalidID; }
136 };
137
138 // TODO(stichnot, jpp): Move GlobalStringPoolTraits definition into
139 // IceGlobalContext.h, once the include order issues are solved.
140 struct GlobalStringPoolTraits {
141 using OwnerType = GlobalContext;
142 static LockedPtr<StringPool> getStrings(const OwnerType *Owner);
143 };
144
145 using GlobalString = StringID<struct GlobalStringPoolTraits>;
146
147 template <typename T>
148 Ostream &operator<<(Ostream &Str, const StringID<T> &Name) {
149 return Str << Name.toString();
150 }
151
152 template <typename T>
153 std::string operator+(const std::string &A, const StringID<T> &B) {
154 return A + B.toString();
155 }
156
157 template <typename T>
158 std::string operator+(const StringID<T> &A, const std::string &B) {
159 return A.toString() + B;
160 }
161
162 } // end of namespace Ice
163
164 namespace std {
165 template <typename T> struct hash<Ice::StringID<T>> {
166 size_t operator()(const Ice::StringID<T> &Key) const {
167 if (Key.hasStdString())
168 return hash<std::string>()(Key.toString());
169 return hash<Ice::StringPool::IDType>()(Key.getID());
170 }
171 };
172 } // end of namespace std
173
174 #endif // SUBZERO_SRC_ICESTRINGPOOL_H
OLDNEW
« no previous file with comments | « src/IceRegistersARM32.h ('k') | src/IceSwitchLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698