mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-09 13:41:47 +00:00
[CodeView] Reduce memory usage in TypeSerializer.
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
This commit is contained in:
parent
bd8c7210cd
commit
ac2e785519
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user