llvm.org GIT mirror llvm / c6b38ee
shared_ptrify ownershp of PoolEntries in PBQP's CostPool Leveraging both intrusive shared_ptr-ing (std::enable_shared_from_this) and shared_ptr<T>-owning-U (to allow external users to hold std::shared_ptr<CostT> while keeping the underlying PoolEntry alive). The intrusiveness could be removed if we had a weak_set that implicitly removed items from the set when their underlying data went away. This /might/ fix an existing memory leak reported by LeakSanitizer in r217504. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217563 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 6 years ago
1 changed file(s) with 10 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
1717 #ifndef LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
1818 #define LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
1919
20 #include
2021 #include
2122 #include
2223
2627 typename CostKeyTComparator>
2728 class CostPool {
2829 public:
29
30 class PoolEntry {
30 class PoolEntry : public std::enable_shared_from_this {
3131 public:
3232 template
3333 PoolEntry(CostPool &pool, CostKeyT cost)
34 : pool(pool), cost(std::move(cost)), refCount(0) {}
34 : pool(pool), cost(std::move(cost)) {}
3535 ~PoolEntry() { pool.removeEntry(this); }
36 void incRef() { ++refCount; }
37 bool decRef() { --refCount; return (refCount == 0); }
3836 CostT& getCost() { return cost; }
3937 const CostT& getCost() const { return cost; }
4038 private:
4139 CostPool &pool;
4240 CostT cost;
43 std::size_t refCount;
4441 };
4542
46 class PoolRef {
47 public:
48 PoolRef(PoolEntry *entry) : entry(entry) {
49 this->entry->incRef();
50 }
51 PoolRef(const PoolRef &r) {
52 entry = r.entry;
53 entry->incRef();
54 }
55 PoolRef& operator=(const PoolRef &r) {
56 assert(entry != nullptr && "entry should not be null.");
57 PoolEntry *temp = r.entry;
58 temp->incRef();
59 entry->decRef();
60 entry = temp;
61 return *this;
62 }
63
64 ~PoolRef() {
65 if (entry->decRef())
66 delete entry;
67 }
68 void reset(PoolEntry *entry) {
69 entry->incRef();
70 this->entry->decRef();
71 this->entry = entry;
72 }
73 CostT& operator*() { return entry->getCost(); }
74 const CostT& operator*() const { return entry->getCost(); }
75 CostT* operator->() { return &entry->getCost(); }
76 const CostT* operator->() const { return &entry->getCost(); }
77 private:
78 PoolEntry *entry;
79 };
43 typedef std::shared_ptr PoolRef;
8044
8145 private:
8246 class EntryComparator {
10367 void removeEntry(PoolEntry *p) { entrySet.erase(p); }
10468
10569 public:
106
10770 template
108 PoolRef getCost(CostKeyT costKey) {
71 std::shared_ptr getCost(CostKeyT costKey) {
10972 typename EntrySet::iterator itr =
11073 std::lower_bound(entrySet.begin(), entrySet.end(), costKey,
11174 EntryComparator());
11275
11376 if (itr != entrySet.end() && costKey == (*itr)->getCost())
114 return PoolRef(*itr);
77 return std::shared_ptr((*itr)->shared_from_this(),
78 &(*itr)->getCost());
11579
116 PoolEntry *p = new PoolEntry(*this, std::move(costKey));
117 entrySet.insert(itr, p);
118 return PoolRef(p);
80 auto p = std::make_shared(*this, std::move(costKey));
81 entrySet.insert(itr, p.get());
82 return std::shared_ptr(std::move(p), &p->getCost());
11983 }
12084 };
12185