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