Core: Use ilist_full_embedded_sentinel_traits for SimpleReference

Avoid custom code for sentinel traits in SimpleReference (the ilist node
for references to a SimpleDefinedAtom), since they'll soon/eventually
disappear from ilist entirely.

Rather than using a BumpPtrAllocator, this drops the lazy sentinel
characteristics and stores the sentinel directly in the ilist.  This
unconditionally allocates the sentinel.

At first glance, this looks like it might increase memory usage
slightly, since an unreferenced SimpleDefinedAtom pays for a
6-pointer-sized sentinel even when its list of references is empty.  In
practice, the sentinel was being lazily allocated at the first call to
DefinedAtom::begin/end anyway.  I don't expect any real memory effects
here.

Moreover, this is an intermediate state.  The ilist_*sentinel_traits are
being phased out.

As a preview of the final state: in lieu of a NodeTy sentinel, the ilist
will have a single, untemplated list_node_base that has next/prev
pointers.  This base node will serve both as a sentinel and as a pointer
to the head of the list (the same memory layout as
ilist_half_embedded_sentinel_traits, but without the UB).

llvm-svn: 278521
This commit is contained in:
Duncan P. N. Exon Smith 2016-08-12 16:19:34 +00:00
parent 87e4038a91
commit 4a1e87d9c6
1 changed files with 7 additions and 41 deletions

View File

@ -143,46 +143,14 @@ private:
} // end namespace lld
// ilist will lazily create a sentinal (so end() can return a node past the
// end of the list). We need this trait so that the sentinal is allocated
// via the BumpPtrAllocator.
// ilist will lazily create a sentinal (so end() can return a node past the end
// of the list). This trait embeds the sentinel in the ilist to avoid the lazy
// logic.
namespace llvm {
template <>
struct ilist_sentinel_traits<lld::SimpleReference> {
ilist_sentinel_traits() : _allocator(nullptr) { }
void setAllocator(llvm::BumpPtrAllocator *alloc) {
_allocator = alloc;
}
lld::SimpleReference *createSentinel() const {
return new (*_allocator) lld::SimpleReference();
}
static void destroySentinel(lld::SimpleReference*) {}
static lld::SimpleReference *provideInitialHead() { return nullptr; }
lld::SimpleReference *ensureHead(lld::SimpleReference *&head) const {
if (!head) {
head = createSentinel();
noteHead(head, head);
ilist_traits<lld::SimpleReference>::setNext(head, nullptr);
return head;
}
return ilist_traits<lld::SimpleReference>::getPrev(head);
}
void noteHead(lld::SimpleReference *newHead,
lld::SimpleReference *sentinel) const {
ilist_traits<lld::SimpleReference>::setPrev(newHead, sentinel);
}
private:
mutable llvm::BumpPtrAllocator *_allocator;
};
struct ilist_sentinel_traits<lld::SimpleReference>
: public ilist_full_embedded_sentinel_traits<lld::SimpleReference> {};
} // end namespace llvm
@ -191,9 +159,7 @@ namespace lld {
class SimpleDefinedAtom : public DefinedAtom {
public:
explicit SimpleDefinedAtom(const File &f)
: _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {
_references.setAllocator(&f.allocator());
}
: _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {}
~SimpleDefinedAtom() override {
_references.clearAndLeakNodesUnsafely();