[lld] r258725 - Use an ilist instead of std::list. NFC.
Pete Cooper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 25 13:50:54 PST 2016
Author: pete
Date: Mon Jan 25 15:50:54 2016
New Revision: 258725
URL: http://llvm.org/viewvc/llvm-project?rev=258725&view=rev
Log:
Use an ilist instead of std::list. NFC.
The TrieNode/TrieEdge data structures here are allocated in a bumpptrallocator.
Unfortunately, TrieNode contained a std::list<TrieEdge> and as the allocator doesn't
call the TrieNode destructor, we ended up leaking the memory allocated by the std::list
itself.
Instead we can use an intrusive list as then we save the extra allocations anyway.
Modified:
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=258725&r1=258724&r2=258725&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Mon Jan 25 15:50:54 2016
@@ -25,6 +25,8 @@
#include "MachONormalizedFileBinaryUtils.h"
#include "lld/Core/Error.h"
#include "lld/Core/LLVM.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -50,6 +52,112 @@ namespace lld {
namespace mach_o {
namespace normalized {
+class ByteBuffer {
+public:
+ ByteBuffer() : _ostream(_bytes) { }
+
+ void append_byte(uint8_t b) {
+ _ostream << b;
+ }
+ void append_uleb128(uint64_t value) {
+ llvm::encodeULEB128(value, _ostream);
+ }
+ void append_uleb128Fixed(uint64_t value, unsigned byteCount) {
+ unsigned min = llvm::getULEB128Size(value);
+ assert(min <= byteCount);
+ unsigned pad = byteCount - min;
+ llvm::encodeULEB128(value, _ostream, pad);
+ }
+ void append_sleb128(int64_t value) {
+ llvm::encodeSLEB128(value, _ostream);
+ }
+ void append_string(StringRef str) {
+ _ostream << str;
+ append_byte(0);
+ }
+ void align(unsigned alignment) {
+ while ( (_ostream.tell() % alignment) != 0 )
+ append_byte(0);
+ }
+ size_t size() {
+ return _ostream.tell();
+ }
+ const uint8_t *bytes() {
+ return reinterpret_cast<const uint8_t*>(_ostream.str().data());
+ }
+
+private:
+ SmallVector<char, 128> _bytes;
+ // Stream ivar must be after SmallVector ivar to construct properly.
+ llvm::raw_svector_ostream _ostream;
+};
+
+struct TrieNode; // Forward declaration.
+
+struct TrieEdge : public llvm::ilist_node<TrieEdge> {
+ TrieEdge(StringRef s, TrieNode *node) : _subString(s), _child(node) {}
+
+ StringRef _subString;
+ struct TrieNode *_child;
+};
+
+} // namespace normalized
+} // namespace mach_o
+} // namespace lld
+
+
+namespace llvm {
+ using lld::mach_o::normalized::TrieEdge;
+ template <>
+ struct ilist_traits<TrieEdge>
+ : public ilist_default_traits<TrieEdge> {
+ private:
+ mutable ilist_half_node<TrieEdge> Sentinel;
+ public:
+ TrieEdge *createSentinel() const {
+ return static_cast<TrieEdge*>(&Sentinel);
+ }
+ void destroySentinel(TrieEdge *) const {}
+
+ TrieEdge *provideInitialHead() const { return createSentinel(); }
+ TrieEdge *ensureHead(TrieEdge*) const { return createSentinel(); }
+ static void noteHead(TrieEdge*, TrieEdge*) {}
+ void deleteNode(TrieEdge *N) {}
+
+ private:
+ void createNode(const TrieEdge &);
+ };
+} // namespace llvm
+
+
+namespace lld {
+namespace mach_o {
+namespace normalized {
+
+struct TrieNode {
+ typedef llvm::ilist<TrieEdge> TrieEdgeList;
+
+ TrieNode(StringRef s)
+ : _cummulativeString(s), _address(0), _flags(0), _other(0),
+ _trieOffset(0), _hasExportInfo(false) {}
+ ~TrieNode() = default;
+
+ void addSymbol(const Export &entry, BumpPtrAllocator &allocator,
+ std::vector<TrieNode *> &allNodes);
+ bool updateOffset(uint32_t &offset);
+ void appendToByteBuffer(ByteBuffer &out);
+
+private:
+ StringRef _cummulativeString;
+ TrieEdgeList _children;
+ uint64_t _address;
+ uint64_t _flags;
+ uint64_t _other;
+ StringRef _importedName;
+ uint32_t _trieOffset;
+ bool _hasExportInfo;
+};
+
/// Utility class for writing a mach-o binary file given an in-memory
/// normalized file.
class MachOFileLayout {
@@ -116,77 +224,6 @@ private:
uint32_t pointerAlign(uint32_t value);
static StringRef dyldPath();
- class ByteBuffer {
- public:
- ByteBuffer() : _ostream(_bytes) { }
-
- void append_byte(uint8_t b) {
- _ostream << b;
- }
- void append_uleb128(uint64_t value) {
- llvm::encodeULEB128(value, _ostream);
- }
- void append_uleb128Fixed(uint64_t value, unsigned byteCount) {
- unsigned min = llvm::getULEB128Size(value);
- assert(min <= byteCount);
- unsigned pad = byteCount - min;
- llvm::encodeULEB128(value, _ostream, pad);
- }
- void append_sleb128(int64_t value) {
- llvm::encodeSLEB128(value, _ostream);
- }
- void append_string(StringRef str) {
- _ostream << str;
- append_byte(0);
- }
- void align(unsigned alignment) {
- while ( (_ostream.tell() % alignment) != 0 )
- append_byte(0);
- }
- size_t size() {
- return _ostream.tell();
- }
- const uint8_t *bytes() {
- return reinterpret_cast<const uint8_t*>(_ostream.str().data());
- }
-
- private:
- SmallVector<char, 128> _bytes;
- // Stream ivar must be after SmallVector ivar to construct properly.
- llvm::raw_svector_ostream _ostream;
- };
-
- struct TrieNode; // Forward declaration.
-
- struct TrieEdge {
- TrieEdge(StringRef s, TrieNode *node) : _subString(s), _child(node) {}
-
- StringRef _subString;
- struct TrieNode *_child;
- };
-
- struct TrieNode {
- TrieNode(StringRef s)
- : _cummulativeString(s), _address(0), _flags(0), _other(0),
- _trieOffset(0), _hasExportInfo(false) {}
- ~TrieNode() = default;
-
- void addSymbol(const Export &entry, BumpPtrAllocator &allocator,
- std::vector<TrieNode *> &allNodes);
- bool updateOffset(uint32_t &offset);
- void appendToByteBuffer(ByteBuffer &out);
-
- private:
- StringRef _cummulativeString;
- std::list<TrieEdge> _children;
- uint64_t _address;
- uint64_t _flags;
- uint64_t _other;
- StringRef _importedName;
- uint32_t _trieOffset;
- bool _hasExportInfo;
- };
-
struct SegExtraInfo {
uint32_t fileOffset;
uint32_t fileSize;
@@ -1077,9 +1114,9 @@ void MachOFileLayout::buildLazyBindInfo(
_lazyBindingInfo.align(_is64 ? 8 : 4);
}
-void MachOFileLayout::TrieNode::addSymbol(const Export& entry,
- BumpPtrAllocator &allocator,
- std::vector<TrieNode*> &allNodes) {
+void TrieNode::addSymbol(const Export& entry,
+ BumpPtrAllocator &allocator,
+ std::vector<TrieNode*> &allNodes) {
StringRef partialStr = entry.name.drop_front(_cummulativeString.size());
for (TrieEdge &edge : _children) {
StringRef edgeStr = edge._subString;
@@ -1108,7 +1145,7 @@ void MachOFileLayout::TrieNode::addSymbo
abEdge._subString = abEdgeStr;
abEdge._child = bNode;
auto *bcEdge = new (allocator) TrieEdge(bcEdgeStr, cNode);
- bNode->_children.push_back(std::move(*bcEdge));
+ bNode->_children.insert(bNode->_children.end(), bcEdge);
bNode->addSymbol(entry, allocator, allNodes);
return;
}
@@ -1123,7 +1160,7 @@ void MachOFileLayout::TrieNode::addSymbo
// No commonality with any existing child, make a new edge.
auto *newNode = new (allocator) TrieNode(entry.name.copy(allocator));
auto *newEdge = new (allocator) TrieEdge(partialStr, newNode);
- _children.push_back(std::move(*newEdge));
+ _children.insert(_children.end(), newEdge);
DEBUG_WITH_TYPE("trie-builder", llvm::dbgs()
<< "new TrieNode('" << entry.name << "') with edge '"
<< partialStr << "' from node='"
@@ -1137,7 +1174,7 @@ void MachOFileLayout::TrieNode::addSymbo
allNodes.push_back(newNode);
}
-bool MachOFileLayout::TrieNode::updateOffset(uint32_t& offset) {
+bool TrieNode::updateOffset(uint32_t& offset) {
uint32_t nodeSize = 1; // Length when no export info
if (_hasExportInfo) {
if (_flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
@@ -1169,7 +1206,7 @@ bool MachOFileLayout::TrieNode::updateOf
return result;
}
-void MachOFileLayout::TrieNode::appendToByteBuffer(ByteBuffer &out) {
+void TrieNode::appendToByteBuffer(ByteBuffer &out) {
if (_hasExportInfo) {
if (_flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
if (!_importedName.empty()) {
More information about the llvm-commits
mailing list