<div dir="ltr">Hmm, what's supposed to happen is that it creates the StringMap using an allocator that should outlive any of this code. So we can then re-use the key value that the StringMap allocated since the storage should stay around. It's storing the allocator by reference too so the StringMap should be getting the same one.<div><br></div><div>In any case, apparently something isn't working. I'm not in a position to revert right now so unless you can do it for me, I can get to it tomorrow :-/ Sorry</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, May 22, 2017 at 8:53 PM Richard Trieu <<a href="mailto:rtrieu@google.com">rtrieu@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Zach,<div><br></div><div>I think this patch is causing a memory leak. Removing the function <span style="font-size:12.8px">TypeSerializer::</span><span style="font-size:12.8px">insertRecordBytesWithCopy and not making the copy will cause the memory backing the array to be deleted before it is used.</span> This has been detected by the sanitizer bot.</div><div><br></div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5121" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5121</a><br></div></div><div dir="ltr"><div><br></div><div>Richard</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 22, 2017 at 2:07 PM, Zachary Turner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br>
Date: Mon May 22 16:07:14 2017<br>
New Revision: 303576<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=303576&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=303576&view=rev</a><br>
Log:<br>
Make TypeSerializer's StringMap use the same allocator.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h<br>
llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h<br>
llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h<br>
llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp<br>
llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp<br>
llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h Mon May 22 16:07:14 2017<br>
@@ -45,12 +45,13 @@ class TypeSerializer : public TypeVisito<br>
}<br>
};<br>
<br>
- typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList;<br>
+ typedef SmallVector<MutableArrayRef<uint8_t>, 2> MutableRecordList;<br>
+ typedef SmallVector<ArrayRef<uint8_t>, 2> RecordList;<br>
<br>
static constexpr uint8_t ContinuationLength = 8;<br>
BumpPtrAllocator &RecordStorage;<br>
RecordSegment CurrentSegment;<br>
- RecordList FieldListSegments;<br>
+ MutableRecordList FieldListSegments;<br>
<br>
TypeIndex LastTypeIndex;<br>
Optional<TypeLeafKind> TypeKind;<br>
@@ -61,7 +62,7 @@ class TypeSerializer : public TypeVisito<br>
TypeRecordMapping Mapping;<br>
<br>
RecordList SeenRecords;<br>
- StringMap<TypeIndex> HashedRecords;<br>
+ StringMap<TypeIndex, BumpPtrAllocator&> HashedRecords;<br>
<br>
bool isInFieldList() const;<br>
TypeIndex calcNextTypeIndex() const;<br>
@@ -69,9 +70,7 @@ class TypeSerializer : public TypeVisito<br>
MutableArrayRef<uint8_t> getCurrentSubRecordData();<br>
MutableArrayRef<uint8_t> getCurrentRecordData();<br>
Error writeRecordPrefix(TypeLeafKind Kind);<br>
- TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record);<br>
- TypeIndex insertRecordBytesWithCopy(CVType &Record,<br>
- MutableArrayRef<uint8_t> Data);<br>
+ TypeIndex insertRecordBytesPrivate(ArrayRef<uint8_t> &Record);<br>
<br>
Expected<MutableArrayRef<uint8_t>><br>
addPadding(MutableArrayRef<uint8_t> Record);<br>
@@ -79,9 +78,9 @@ class TypeSerializer : public TypeVisito<br>
public:<br>
explicit TypeSerializer(BumpPtrAllocator &Storage);<br>
<br>
- ArrayRef<MutableArrayRef<uint8_t>> records() const;<br>
+ ArrayRef<ArrayRef<uint8_t>> records() const;<br>
TypeIndex getLastTypeIndex() const;<br>
- TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record);<br>
+ TypeIndex insertRecordBytes(ArrayRef<uint8_t> Record);<br>
Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);<br>
<br>
Error visitTypeBegin(CVType &Record) override;<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h Mon May 22 16:07:14 2017<br>
@@ -64,7 +64,7 @@ public:<br>
return *ExpectedIndex;<br>
}<br>
<br>
- TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {<br>
+ TypeIndex writeSerializedRecord(ArrayRef<uint8_t> Record) {<br>
return Serializer.insertRecordBytes(Record);<br>
}<br>
<br>
@@ -77,7 +77,7 @@ public:<br>
}<br>
}<br>
<br>
- ArrayRef<MutableArrayRef<uint8_t>> records() const {<br>
+ ArrayRef<ArrayRef<uint8_t>> records() const {<br>
return Serializer.records();<br>
}<br>
};<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h Mon May 22 16:07:14 2017<br>
@@ -18,7 +18,7 @@ namespace codeview {<br>
<br>
class TypeTableCollection : public TypeCollection {<br>
public:<br>
- explicit TypeTableCollection(ArrayRef<MutableArrayRef<uint8_t>> Records);<br>
+ explicit TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records);<br>
<br>
Optional<TypeIndex> getFirst() override;<br>
Optional<TypeIndex> getNext(TypeIndex Prev) override;<br>
@@ -33,7 +33,7 @@ private:<br>
bool hasCapacityFor(TypeIndex Index) const;<br>
void ensureTypeExists(TypeIndex Index);<br>
<br>
- ArrayRef<MutableArrayRef<uint8_t>> Records;<br>
+ ArrayRef<ArrayRef<uint8_t>> Records;<br>
TypeDatabase Database;<br>
};<br>
}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp Mon May 22 16:07:14 2017<br>
@@ -52,43 +52,24 @@ Error TypeSerializer::writeRecordPrefix(<br>
}<br>
<br>
TypeIndex<br>
-TypeSerializer::insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record) {<br>
+TypeSerializer::insertRecordBytesPrivate(ArrayRef<uint8_t> &Record) {<br>
assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!");<br>
<br>
StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size());<br>
<br>
TypeIndex NextTypeIndex = calcNextTypeIndex();<br>
auto Result = HashedRecords.try_emplace(S, NextTypeIndex);<br>
+<br>
+ StringRef NewData = Result.first->getKey();<br>
+ Record = ArrayRef<uint8_t>(NewData.bytes_begin(), NewData.bytes_end());<br>
+<br>
if (Result.second) {<br>
+ // If this triggered an insert into the map, store the bytes.<br>
LastTypeIndex = NextTypeIndex;<br>
SeenRecords.push_back(Record);<br>
}<br>
- return Result.first->getValue();<br>
-}<br>
<br>
-TypeIndex<br>
-TypeSerializer::insertRecordBytesWithCopy(CVType &Record,<br>
- MutableArrayRef<uint8_t> Data) {<br>
- assert(Data.size() % 4 == 0 && "Record is not aligned to 4 bytes!");<br>
-<br>
- StringRef S(reinterpret_cast<const char *>(Data.data()), Data.size());<br>
-<br>
- // Do a two state lookup / insert so that we don't have to allocate unless<br>
- // we're going<br>
- // to do an insert. This is a big memory savings.<br>
- auto Iter = HashedRecords.find(S);<br>
- if (Iter != HashedRecords.end())<br>
- return Iter->second;<br>
-<br>
- LastTypeIndex = calcNextTypeIndex();<br>
- uint8_t *Copy = RecordStorage.Allocate<uint8_t>(Data.size());<br>
- ::memcpy(Copy, Data.data(), Data.size());<br>
- Data = MutableArrayRef<uint8_t>(Copy, Data.size());<br>
- S = StringRef(reinterpret_cast<const char *>(Data.data()), Data.size());<br>
- HashedRecords.insert(std::make_pair(S, LastTypeIndex));<br>
- SeenRecords.push_back(Data);<br>
- Record.RecordData = Data;<br>
- return LastTypeIndex;<br>
+ return Result.first->getValue();<br>
}<br>
<br>
Expected<MutableArrayRef<uint8_t>><br>
@@ -112,19 +93,19 @@ TypeSerializer::TypeSerializer(BumpPtrAl<br>
: RecordStorage(Storage), LastTypeIndex(),<br>
RecordBuffer(MaxRecordLength * 2),<br>
Stream(RecordBuffer, llvm::support::little), Writer(Stream),<br>
- Mapping(Writer) {<br>
+ Mapping(Writer), HashedRecords(Storage) {<br>
// RecordBuffer needs to be able to hold enough data so that if we are 1<br>
// byte short of MaxRecordLen, and then we try to write MaxRecordLen bytes,<br>
// we won't overflow.<br>
}<br>
<br>
-ArrayRef<MutableArrayRef<uint8_t>> TypeSerializer::records() const {<br>
+ArrayRef<ArrayRef<uint8_t>> TypeSerializer::records() const {<br>
return SeenRecords;<br>
}<br>
<br>
TypeIndex TypeSerializer::getLastTypeIndex() const { return LastTypeIndex; }<br>
<br>
-TypeIndex TypeSerializer::insertRecordBytes(MutableArrayRef<uint8_t> Record) {<br>
+TypeIndex TypeSerializer::insertRecordBytes(ArrayRef<uint8_t> Record) {<br>
assert(!TypeKind.hasValue() && "Already in a type mapping!");<br>
assert(Writer.getOffset() == 0 && "Stream has data already!");<br>
<br>
@@ -163,8 +144,8 @@ Expected<TypeIndex> TypeSerializer::visi<br>
Prefix->RecordLen = ThisRecordData.size() - sizeof(uint16_t);<br>
<br>
Record.Type = *TypeKind;<br>
- TypeIndex InsertedTypeIndex =<br>
- insertRecordBytesWithCopy(Record, ThisRecordData);<br>
+ Record.RecordData = ThisRecordData;<br>
+ TypeIndex InsertedTypeIndex = insertRecordBytesPrivate(Record.RecordData);<br>
<br>
// Write out each additional segment in reverse order, and update each<br>
// record's continuation index to point to the previous one.<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp Mon May 22 16:07:14 2017<br>
@@ -25,7 +25,7 @@ static void error(Error &&EC) {<br>
}<br>
<br>
TypeTableCollection::TypeTableCollection(<br>
- ArrayRef<MutableArrayRef<uint8_t>> Records)<br>
+ ArrayRef<ArrayRef<uint8_t>> Records)<br>
: Records(Records), Database(Records.size()) {}<br>
<br>
Optional<TypeIndex> TypeTableCollection::getFirst() {<br>
<br>
Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=303576&r1=303575&r2=303576&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=303576&r1=303575&r2=303576&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)<br>
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Mon May 22 16:07:14 2017<br>
@@ -878,11 +878,11 @@ static void mergePdbs() {<br>
auto &DestTpi = Builder.getTpiBuilder();<br>
auto &DestIpi = Builder.getIpiBuilder();<br>
MergedTpi.ForEachRecord(<br>
- [&DestTpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {<br>
+ [&DestTpi](TypeIndex TI, ArrayRef<uint8_t> Data) {<br>
DestTpi.addTypeRecord(Data, None);<br>
});<br>
MergedIpi.ForEachRecord(<br>
- [&DestIpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {<br>
+ [&DestIpi](TypeIndex TI, ArrayRef<uint8_t> Data) {<br>
DestIpi.addTypeRecord(Data, None);<br>
});<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</blockquote></div>