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

Unified Diff: src/IceStringPool.h

Issue 1838753002: Subzero: Remove IceString. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: More cleanup Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceRegistersARM32.h ('k') | src/IceSwitchLowering.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceStringPool.h
diff --git a/src/IceStringPool.h b/src/IceStringPool.h
new file mode 100644
index 0000000000000000000000000000000000000000..bd1c76b6da69da6a3a2a19294aa359b54c0faaca
--- /dev/null
+++ b/src/IceStringPool.h
@@ -0,0 +1,164 @@
+//===- subzero/src/IceStringPool.h - String pooling -------------*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines unique pooled strings with short unique IDs. This makes
+/// hashing, equality testing, and ordered comparison faster, and avoids a lot
+/// of memory allocation compared to directly using std::string.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICESTRINGPOOL_H
+#define SUBZERO_SRC_ICESTRINGPOOL_H
+
+#include <cstdint> // uintptr_t
+#include <string>
+
+namespace Ice {
+
+class StringPool {
+ StringPool(const StringPool &) = delete;
+ StringPool &operator=(const StringPool &) = delete;
+
+public:
+ using IDType = uintptr_t;
+
+ StringPool() = default;
+ ~StringPool() = default;
+ IDType getNewID() {
+ // TODO(stichnot): Make it so that the GlobalString ctor doesn't have to
+ // grab the lock, and instead does an atomic increment of NextID.
+ auto NewID = NextID;
+ NextID += IDIncrement;
+ return NewID;
+ }
+ IDType getOrAddString(const std::string &Value) {
+ auto Iter = StringToId.find(Value);
+ if (Iter == StringToId.end()) {
+ auto *NewStr = new std::string(Value);
+ auto ID = reinterpret_cast<IDType>(NewStr);
+ assert(StringToId.find(Value) == StringToId.end());
+ StringToId[Value].reset(NewStr);
+ return ID;
+ }
+ return reinterpret_cast<IDType>(Iter->second.get());
+ }
+ void dump(Ostream &Str) {
+ if (StringToId.empty())
+ return;
+ Str << "String pool (NumStrings=" << StringToId.size()
+ << " NumIDs=" << ((NextID - FirstID) / IDIncrement) << "):";
+ for (auto &Tuple : StringToId) {
+ Str << " " << Tuple.first;
+ }
+ Str << "\n";
+ }
+
+private:
+ static constexpr IDType FirstID = 1;
+ static constexpr IDType IDIncrement = 2;
+ IDType NextID = FirstID;
+ std::unordered_map<std::string, std::unique_ptr<std::string>> StringToId;
+};
+
+template <typename Traits> class StringID {
+public:
+ using IDType = StringPool::IDType;
+
+ StringID(const StringID &) = default;
+ StringID &operator=(const StringID &) = default;
+ // Create a default, invalid StringID.
+ StringID() = default;
+ /// Create a unique StringID without an actual string, by grabbing the next
+ /// unique integral ID from the Owner.
+ explicit StringID(const typename Traits::OwnerType *Owner)
+ : ID(Traits::getStrings(Owner)->getNewID()) {}
+ /// Create a unique StringID that holds an actual string, by fetching or
+ /// adding the string from the Owner's pool.
+ StringID(const typename Traits::OwnerType *Owner, const std::string &Value)
+ : ID(Traits::getStrings(Owner)->getOrAddString(Value)) {
+ assert(hasString());
+ }
+
+ static bool hasString(IDType ID) { return isValid(ID) && ((ID & 0x1) == 0); }
+ bool hasString() const { return hasString(ID); }
+
+ IDType getID() const {
+ assert(isValid());
+ return ID;
+ }
+ const std::string &toString() const {
+ assert(hasString());
+ return *reinterpret_cast<std::string *>(ID);
+ }
+ std::string toStringOrEmpty() const {
+ if (hasString())
+ return toString();
+ return "";
+ }
+
+ bool operator==(const StringID &Other) const { return ID == Other.ID; }
+ bool operator!=(const StringID &Other) const { return !(*this == Other); }
+ bool operator<(const StringID &Other) const {
+ const bool ThisHasString = hasString();
+ const bool OtherHasString = Other.hasString();
+ // Do a normal string comparison if both have strings.
+ if (ThisHasString && OtherHasString)
+ return this->toString() < Other.toString();
+ // Use the ID as a tiebreaker if neither has a string.
+ if (!ThisHasString && !OtherHasString)
+ return ID < Other.ID;
+ // If exactly one has a string, then that one comes first.
+ assert(!OtherHasString);
+ return ThisHasString;
+ }
+
+private:
+ static constexpr IDType InvalidID = 0;
+ IDType ID = InvalidID;
+
+ static bool isValid(IDType ID) { return ID != InvalidID; }
+ bool isValid() const { return isValid(ID); }
+};
+
+struct GlobalStringPoolTraits {
+ using OwnerType = GlobalContext;
+ static LockedPtr<StringPool> getStrings(const OwnerType *Owner);
+};
+
+using GlobalString = StringID<struct GlobalStringPoolTraits>;
+
+template <typename T>
+Ostream &operator<<(Ostream &Str, const StringID<T> &Name) {
+ return Str << Name.toString();
+}
+
+template <typename T>
+std::string operator+(const std::string &A, const StringID<T> &B) {
+ return A + B.toString();
+}
+
+template <typename T>
+std::string operator+(const StringID<T> &A, const std::string &B) {
+ return A.toString() + B;
+}
+
+} // end of namespace Ice
+
+namespace std {
+template <typename T> struct hash<Ice::StringID<T>> {
+ size_t operator()(const Ice::StringID<T> &Key) const {
+ if (Key.hasString())
+ return hash<std::string>()(Key.toString());
+ return hash<Ice::StringPool::IDType>()(Key.getID());
+ }
+};
+} // end of namespace std
+
+#endif // SUBZERO_SRC_ICESTRINGPOOL_H
« 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