]> granicus.if.org Git - llvm/commitdiff
[CodeView] Reduce memory usage in TypeSerializer.
authorZachary Turner <zturner@google.com>
Fri, 19 May 2017 04:56:48 +0000 (04:56 +0000)
committerZachary Turner <zturner@google.com>
Fri, 19 May 2017 04:56:48 +0000 (04:56 +0000)
We were using a BumpPtrAllocator to allocate stable storage for
a record, then trying to insert that into a hash table.  If a
collision occurred, the bytes were never inserted and the
allocation was unnecessary.  At the cost of an extra hash
computation, check first if it exists, and only if it does do
we allocate and insert.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303407 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/CodeView/TypeSerializer.h
lib/DebugInfo/CodeView/TypeSerializer.cpp

index 1f4873c4f96938fb1616c98b0ccd15b2a2da7939..6dad98247136fb5fc7ed70da8f3d6911ef8c2706 100644 (file)
@@ -70,6 +70,8 @@ class TypeSerializer : public TypeVisitorCallbacks {
   MutableArrayRef<uint8_t> getCurrentRecordData();
   Error writeRecordPrefix(TypeLeafKind Kind);
   TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record);
+  TypeIndex insertRecordBytesWithCopy(CVType &Record,
+                                      MutableArrayRef<uint8_t> Data);
 
   Expected<MutableArrayRef<uint8_t>>
   addPadding(MutableArrayRef<uint8_t> Record);
index fd4d1853fa544f047c244a48925ffacaa9e86545..3b061e67e05ec6ced813848d6beb036142c70b1b 100644 (file)
@@ -66,6 +66,31 @@ TypeSerializer::insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record) {
   return Result.first->getValue();
 }
 
+TypeIndex
+TypeSerializer::insertRecordBytesWithCopy(CVType &Record,
+                                          MutableArrayRef<uint8_t> Data) {
+  assert(Data.size() % 4 == 0 && "Record is not aligned to 4 bytes!");
+
+  StringRef S(reinterpret_cast<const char *>(Data.data()), Data.size());
+
+  // Do a two state lookup / insert so that we don't have to allocate unless
+  // we're going
+  // to do an insert.  This is a big memory savings.
+  auto Iter = HashedRecords.find(S);
+  if (Iter != HashedRecords.end())
+    return Iter->second;
+
+  LastTypeIndex = calcNextTypeIndex();
+  uint8_t *Copy = RecordStorage.Allocate<uint8_t>(Data.size());
+  ::memcpy(Copy, Data.data(), Data.size());
+  Data = MutableArrayRef<uint8_t>(Copy, Data.size());
+  S = StringRef(reinterpret_cast<const char *>(Data.data()), Data.size());
+  HashedRecords.insert(std::make_pair(S, LastTypeIndex));
+  SeenRecords.push_back(Data);
+  Record.RecordData = Data;
+  return LastTypeIndex;
+}
+
 Expected<MutableArrayRef<uint8_t>>
 TypeSerializer::addPadding(MutableArrayRef<uint8_t> Record) {
   uint32_t Align = Record.size() % 4;
@@ -137,11 +162,9 @@ Expected<TypeIndex> TypeSerializer::visitTypeEndGetIndex(CVType &Record) {
       reinterpret_cast<RecordPrefix *>(ThisRecordData.data());
   Prefix->RecordLen = ThisRecordData.size() - sizeof(uint16_t);
 
-  uint8_t *Copy = RecordStorage.Allocate<uint8_t>(ThisRecordData.size());
-  ::memcpy(Copy, ThisRecordData.data(), ThisRecordData.size());
-  ThisRecordData = MutableArrayRef<uint8_t>(Copy, ThisRecordData.size());
-  Record = CVType(*TypeKind, ThisRecordData);
-  TypeIndex InsertedTypeIndex = insertRecordBytesPrivate(ThisRecordData);
+  Record.Type = *TypeKind;
+  TypeIndex InsertedTypeIndex =
+      insertRecordBytesWithCopy(Record, ThisRecordData);
 
   // Write out each additional segment in reverse order, and update each
   // record's continuation index to point to the previous one.