Chromium Code Reviews| Index: src/IceGlobalContext.h |
| diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h |
| index 6c6c22248c6fafd2cf5490c0c82cc545f9060484..ac04ab0a9433954e3e8582d69da1a7d217bba1f9 100644 |
| --- a/src/IceGlobalContext.h |
| +++ b/src/IceGlobalContext.h |
| @@ -20,6 +20,7 @@ |
| #include "IceClFlags.h" |
| #include "IceIntrinsics.h" |
| #include "IceRNG.h" |
| +#include "IceStringPool.h" |
| #include "IceSwitchLowering.h" |
| #include "IceTargetLowering.def" |
| #include "IceThreading.h" |
| @@ -53,30 +54,6 @@ enum class RuntimeHelper { |
| H_Num |
| }; |
| -/// LockedPtr is a way to provide automatically locked access to some object. |
| -template <typename T> class LockedPtr { |
| - LockedPtr() = delete; |
| - LockedPtr(const LockedPtr &) = delete; |
| - LockedPtr &operator=(const LockedPtr &) = delete; |
| - |
| -public: |
| - LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) { |
| - Lock->lock(); |
| - } |
| - LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) { |
| - Other.Value = nullptr; |
| - Other.Lock = nullptr; |
| - } |
| - ~LockedPtr() { Lock->unlock(); } |
| - T *operator->() const { return Value; } |
| - T &operator*() const { return *Value; } |
| - T *get() { return Value; } |
| - |
| -private: |
| - T *Value; |
| - GlobalLockType *Lock; |
| -}; |
| - |
| class GlobalContext { |
| GlobalContext() = delete; |
| GlobalContext(const GlobalContext &) = delete; |
| @@ -113,7 +90,7 @@ class GlobalContext { |
| for (uint32_t i = 0; i < Stats.size(); ++i) |
| Stats[i] += Other.Stats[i]; |
| } |
| - void dump(const IceString &Name, GlobalContext *Ctx); |
| + void dump(const std::string &Name, GlobalContext *Ctx); |
| private: |
| std::array<uint32_t, CS_NUM> Stats; |
| @@ -172,6 +149,7 @@ public: |
| ELFStreamer *ELFStreamer); |
| ~GlobalContext(); |
| + void dumpStrings(); |
| /// |
| /// The dump, error, and emit streams need to be used by only one |
| /// thread at a time. This is done by exclusively reserving the |
| @@ -247,11 +225,12 @@ public: |
| Constant *getConstantFloat(float Value); |
| Constant *getConstantDouble(double Value); |
| /// Returns a symbolic constant. |
| - Constant *getConstantSym(const RelocOffsetT Offset, |
| - const RelocOffsetArray &OffsetExpr, |
| - const IceString &Name, const IceString &EmitString); |
| - Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name); |
| - Constant *getConstantExternSym(const IceString &Name); |
| + Constant *getConstantSymWithEmitString(const RelocOffsetT Offset, |
| + const RelocOffsetArray &OffsetExpr, |
| + GlobalString Name, |
| + const std::string &EmitString); |
| + Constant *getConstantSym(RelocOffsetT Offset, GlobalString Name); |
| + Constant *getConstantExternSym(GlobalString Name); |
| /// Returns an undef. |
| Constant *getConstantUndef(Type Ty); |
| /// Returns a zero value. |
| @@ -268,11 +247,12 @@ public: |
| assert(Result != nullptr && "No such runtime helper function"); |
| return Result; |
| } |
| + GlobalString getGlobalString(const std::string &Name); |
| /// Return a locked pointer to the registered jump tables. |
| JumpTableDataList getJumpTables(); |
| /// Create a new jump table entry and return a reference to it. |
| - JumpTableData &addJumpTable(const IceString &FuncName, SizeT Id, |
| + JumpTableData &addJumpTable(GlobalString FuncName, SizeT Id, |
| const JumpTableData::TargetList &TargetList); |
| static const ClFlags &getFlags() { return Flags; } |
| @@ -305,7 +285,7 @@ public: |
| if (BuildDefs::dump()) |
| ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); |
| } |
| - void dumpStats(const IceString &Name, bool Final = false); |
| + void dumpStats(const std::string &Name, bool Final = false); |
| void statsUpdateEmitted(uint32_t InstCount) { |
| if (!getFlags().getDumpStats()) |
| return; |
| @@ -356,24 +336,24 @@ public: |
| /// newTimerStackID() creates a new TimerStack in the global space. It does |
| /// not affect any TimerStack objects in TLS. |
| - TimerStackIdT newTimerStackID(const IceString &Name); |
| + TimerStackIdT newTimerStackID(const std::string &Name); |
| /// dumpTimers() dumps the global timer data. As such, one probably wants to |
| /// call mergeTimerStacks() as a prerequisite. |
| void dumpTimers(TimerStackIdT StackID = TSK_Default, |
| bool DumpCumulative = true); |
| /// The following methods affect only the calling thread's TLS timer data. |
| - TimerIdT getTimerID(TimerStackIdT StackID, const IceString &Name); |
| + TimerIdT getTimerID(TimerStackIdT StackID, const std::string &Name); |
| void pushTimer(TimerIdT ID, TimerStackIdT StackID); |
| void popTimer(TimerIdT ID, TimerStackIdT StackID); |
| void resetTimer(TimerStackIdT StackID); |
| - void setTimerName(TimerStackIdT StackID, const IceString &NewName); |
| + void setTimerName(TimerStackIdT StackID, const std::string &NewName); |
| /// This is the first work item sequence number that the parser produces, and |
| /// correspondingly the first sequence number that the emitter thread will |
| /// wait for. Start numbering at 1 to leave room for a sentinel, in case e.g. |
| /// we wish to inject items with a special sequence number that may be |
| /// executed out of order. |
| - static uint32_t getFirstSequenceNumber() { return 1; } |
| + static constexpr uint32_t getFirstSequenceNumber() { return 1; } |
| /// Adds a newly parsed and constructed function to the Cfg work queue. |
| /// Notifies any idle workers that a new function is available for |
| /// translating. May block if the work queue is too large, in order to control |
| @@ -474,7 +454,7 @@ public: |
| /// Uses DataLowering to lower Globals. Side effects: |
| /// - discards the initializer list for the global variable in Globals. |
| /// - clears the Globals array. |
| - void lowerGlobals(const IceString &SectionSuffix); |
| + void lowerGlobals(const std::string &SectionSuffix); |
| /// Lowers the profile information. |
| void lowerProfileData(); |
| @@ -486,10 +466,8 @@ public: |
| /// function or symbol based on a command-line argument, such as changing the |
| /// verbose level for a particular function. An empty Match argument means |
| /// match everything. Returns true if there is a match. |
| - static bool matchSymbolName(const IceString &SymbolName, |
| - const IceString &Match) { |
| - return Match.empty() || Match == SymbolName; |
| - } |
| + static bool matchSymbolName(const GlobalString &SymbolName, |
| + const std::string &Match); |
| static ClFlags Flags; |
| @@ -505,6 +483,10 @@ public: |
| } |
| /// @} |
| + LockedPtr<StringPool> getStrings() const { |
| + return LockedPtr<StringPool>(Strings.get(), &StringsLock); |
| + } |
| + |
| private: |
| // Try to ensure mutexes are allocated on separate cache lines. |
| @@ -526,7 +508,12 @@ private: |
| DestructorArray Destructors; |
| ICE_CACHELINE_BOUNDARY; |
| - // Managed by getConstantPool() |
| + // Managed by getStrings() |
| + mutable GlobalLockType StringsLock; |
|
John
2016/03/29 14:23:15
I would either make all Locks mutable, or none Mut
Jim Stichnoth
2016/03/29 21:40:49
Done - mutable in this file.
|
| + std::unique_ptr<StringPool> Strings; |
| + |
| + ICE_CACHELINE_BOUNDARY; |
| + // Managed by getConstPool() |
| GlobalLockType ConstPoolLock; |
| std::unique_ptr<ConstantPool> ConstPool; |
| @@ -663,7 +650,7 @@ public: |
| if (BuildDefs::timers()) |
| pushCfg(Func); |
| } |
| - TimerMarker(GlobalContext *Ctx, const IceString &FuncName) |
| + TimerMarker(GlobalContext *Ctx, const std::string &FuncName) |
| : ID(getTimerIdFromFuncName(Ctx, FuncName)), Ctx(Ctx), |
| StackID(GlobalContext::TSK_Funcs) { |
| if (BuildDefs::timers()) |
| @@ -679,7 +666,7 @@ private: |
| void push(); |
| void pushCfg(const Cfg *Func); |
| static TimerIdT getTimerIdFromFuncName(GlobalContext *Ctx, |
| - const IceString &FuncName); |
| + const std::string &FuncName); |
| const TimerIdT ID; |
| GlobalContext *Ctx; |
| const TimerStackIdT StackID; |