forked from OSchip/llvm-project
Make TypeSerializer's StringMap use the same allocator.
llvm-svn: 303576
This commit is contained in:
parent
fb31da1306
commit
12f8c31c04
|
@ -45,12 +45,13 @@ class TypeSerializer : public TypeVisitorCallbacks {
|
|||
}
|
||||
};
|
||||
|
||||
typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList;
|
||||
typedef SmallVector<MutableArrayRef<uint8_t>, 2> MutableRecordList;
|
||||
typedef SmallVector<ArrayRef<uint8_t>, 2> RecordList;
|
||||
|
||||
static constexpr uint8_t ContinuationLength = 8;
|
||||
BumpPtrAllocator &RecordStorage;
|
||||
RecordSegment CurrentSegment;
|
||||
RecordList FieldListSegments;
|
||||
MutableRecordList FieldListSegments;
|
||||
|
||||
TypeIndex LastTypeIndex;
|
||||
Optional<TypeLeafKind> TypeKind;
|
||||
|
@ -61,7 +62,7 @@ class TypeSerializer : public TypeVisitorCallbacks {
|
|||
TypeRecordMapping Mapping;
|
||||
|
||||
RecordList SeenRecords;
|
||||
StringMap<TypeIndex> HashedRecords;
|
||||
StringMap<TypeIndex, BumpPtrAllocator&> HashedRecords;
|
||||
|
||||
bool isInFieldList() const;
|
||||
TypeIndex calcNextTypeIndex() const;
|
||||
|
@ -69,9 +70,7 @@ class TypeSerializer : public TypeVisitorCallbacks {
|
|||
MutableArrayRef<uint8_t> getCurrentSubRecordData();
|
||||
MutableArrayRef<uint8_t> getCurrentRecordData();
|
||||
Error writeRecordPrefix(TypeLeafKind Kind);
|
||||
TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record);
|
||||
TypeIndex insertRecordBytesWithCopy(CVType &Record,
|
||||
MutableArrayRef<uint8_t> Data);
|
||||
TypeIndex insertRecordBytesPrivate(ArrayRef<uint8_t> &Record);
|
||||
|
||||
Expected<MutableArrayRef<uint8_t>>
|
||||
addPadding(MutableArrayRef<uint8_t> Record);
|
||||
|
@ -79,9 +78,9 @@ class TypeSerializer : public TypeVisitorCallbacks {
|
|||
public:
|
||||
explicit TypeSerializer(BumpPtrAllocator &Storage);
|
||||
|
||||
ArrayRef<MutableArrayRef<uint8_t>> records() const;
|
||||
ArrayRef<ArrayRef<uint8_t>> records() const;
|
||||
TypeIndex getLastTypeIndex() const;
|
||||
TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record);
|
||||
TypeIndex insertRecordBytes(ArrayRef<uint8_t> Record);
|
||||
Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);
|
||||
|
||||
Error visitTypeBegin(CVType &Record) override;
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
return *ExpectedIndex;
|
||||
}
|
||||
|
||||
TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
|
||||
TypeIndex writeSerializedRecord(ArrayRef<uint8_t> Record) {
|
||||
return Serializer.insertRecordBytes(Record);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
ArrayRef<MutableArrayRef<uint8_t>> records() const {
|
||||
ArrayRef<ArrayRef<uint8_t>> records() const {
|
||||
return Serializer.records();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace codeview {
|
|||
|
||||
class TypeTableCollection : public TypeCollection {
|
||||
public:
|
||||
explicit TypeTableCollection(ArrayRef<MutableArrayRef<uint8_t>> Records);
|
||||
explicit TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records);
|
||||
|
||||
Optional<TypeIndex> getFirst() override;
|
||||
Optional<TypeIndex> getNext(TypeIndex Prev) override;
|
||||
|
@ -33,7 +33,7 @@ private:
|
|||
bool hasCapacityFor(TypeIndex Index) const;
|
||||
void ensureTypeExists(TypeIndex Index);
|
||||
|
||||
ArrayRef<MutableArrayRef<uint8_t>> Records;
|
||||
ArrayRef<ArrayRef<uint8_t>> Records;
|
||||
TypeDatabase Database;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -52,45 +52,26 @@ Error TypeSerializer::writeRecordPrefix(TypeLeafKind Kind) {
|
|||
}
|
||||
|
||||
TypeIndex
|
||||
TypeSerializer::insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record) {
|
||||
TypeSerializer::insertRecordBytesPrivate(ArrayRef<uint8_t> &Record) {
|
||||
assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!");
|
||||
|
||||
StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size());
|
||||
|
||||
TypeIndex NextTypeIndex = calcNextTypeIndex();
|
||||
auto Result = HashedRecords.try_emplace(S, NextTypeIndex);
|
||||
|
||||
StringRef NewData = Result.first->getKey();
|
||||
Record = ArrayRef<uint8_t>(NewData.bytes_begin(), NewData.bytes_end());
|
||||
|
||||
if (Result.second) {
|
||||
// If this triggered an insert into the map, store the bytes.
|
||||
LastTypeIndex = NextTypeIndex;
|
||||
SeenRecords.push_back(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;
|
||||
|
@ -112,19 +93,19 @@ TypeSerializer::TypeSerializer(BumpPtrAllocator &Storage)
|
|||
: RecordStorage(Storage), LastTypeIndex(),
|
||||
RecordBuffer(MaxRecordLength * 2),
|
||||
Stream(RecordBuffer, llvm::support::little), Writer(Stream),
|
||||
Mapping(Writer) {
|
||||
Mapping(Writer), HashedRecords(Storage) {
|
||||
// RecordBuffer needs to be able to hold enough data so that if we are 1
|
||||
// byte short of MaxRecordLen, and then we try to write MaxRecordLen bytes,
|
||||
// we won't overflow.
|
||||
}
|
||||
|
||||
ArrayRef<MutableArrayRef<uint8_t>> TypeSerializer::records() const {
|
||||
ArrayRef<ArrayRef<uint8_t>> TypeSerializer::records() const {
|
||||
return SeenRecords;
|
||||
}
|
||||
|
||||
TypeIndex TypeSerializer::getLastTypeIndex() const { return LastTypeIndex; }
|
||||
|
||||
TypeIndex TypeSerializer::insertRecordBytes(MutableArrayRef<uint8_t> Record) {
|
||||
TypeIndex TypeSerializer::insertRecordBytes(ArrayRef<uint8_t> Record) {
|
||||
assert(!TypeKind.hasValue() && "Already in a type mapping!");
|
||||
assert(Writer.getOffset() == 0 && "Stream has data already!");
|
||||
|
||||
|
@ -163,8 +144,8 @@ Expected<TypeIndex> TypeSerializer::visitTypeEndGetIndex(CVType &Record) {
|
|||
Prefix->RecordLen = ThisRecordData.size() - sizeof(uint16_t);
|
||||
|
||||
Record.Type = *TypeKind;
|
||||
TypeIndex InsertedTypeIndex =
|
||||
insertRecordBytesWithCopy(Record, ThisRecordData);
|
||||
Record.RecordData = ThisRecordData;
|
||||
TypeIndex InsertedTypeIndex = insertRecordBytesPrivate(Record.RecordData);
|
||||
|
||||
// Write out each additional segment in reverse order, and update each
|
||||
// record's continuation index to point to the previous one.
|
||||
|
|
|
@ -25,7 +25,7 @@ static void error(Error &&EC) {
|
|||
}
|
||||
|
||||
TypeTableCollection::TypeTableCollection(
|
||||
ArrayRef<MutableArrayRef<uint8_t>> Records)
|
||||
ArrayRef<ArrayRef<uint8_t>> Records)
|
||||
: Records(Records), Database(Records.size()) {}
|
||||
|
||||
Optional<TypeIndex> TypeTableCollection::getFirst() {
|
||||
|
|
|
@ -878,11 +878,11 @@ static void mergePdbs() {
|
|||
auto &DestTpi = Builder.getTpiBuilder();
|
||||
auto &DestIpi = Builder.getIpiBuilder();
|
||||
MergedTpi.ForEachRecord(
|
||||
[&DestTpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {
|
||||
[&DestTpi](TypeIndex TI, ArrayRef<uint8_t> Data) {
|
||||
DestTpi.addTypeRecord(Data, None);
|
||||
});
|
||||
MergedIpi.ForEachRecord(
|
||||
[&DestIpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {
|
||||
[&DestIpi](TypeIndex TI, ArrayRef<uint8_t> Data) {
|
||||
DestIpi.addTypeRecord(Data, None);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue