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