[CodeView] Add TypeCollection::replaceType to replace type records post-merging

The API is not called in this patch. This is to simply/support https://reviews.llvm.org/D80833
This commit is contained in:
Alexandre Ganea 2020-06-18 08:21:39 -04:00
parent a45409d885
commit 24eff42ba4
11 changed files with 100 additions and 6 deletions

View File

@ -38,7 +38,7 @@ public:
explicit AppendingTypeTableBuilder(BumpPtrAllocator &Storage);
~AppendingTypeTableBuilder();
// TypeTableCollection overrides
// TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@ -46,6 +46,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();

View File

@ -50,7 +50,7 @@ public:
explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage);
~GlobalTypeTableBuilder();
// TypeTableCollection overrides
// TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@ -58,6 +58,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();

View File

@ -79,6 +79,7 @@ public:
uint32_t capacity() override;
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
private:
Error ensureTypeExists(TypeIndex Index);

View File

@ -47,7 +47,7 @@ public:
explicit MergingTypeTableBuilder(BumpPtrAllocator &Storage);
~MergingTypeTableBuilder();
// TypeTableCollection overrides
// TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@ -55,6 +55,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();

View File

@ -30,6 +30,7 @@ public:
virtual bool contains(TypeIndex Index) = 0;
virtual uint32_t size() = 0;
virtual uint32_t capacity() = 0;
virtual bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) = 0;
template <typename TFunc> void ForEachRecord(TFunc Func) {
Optional<TypeIndex> Next = getFirst();

View File

@ -29,6 +29,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
private:
BumpPtrAllocator Allocator;

View File

@ -74,12 +74,17 @@ ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const {
void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); }
static ArrayRef<uint8_t> stabilize(BumpPtrAllocator &RecordStorage,
ArrayRef<uint8_t> Record) {
uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size());
memcpy(Stable, Record.data(), Record.size());
return ArrayRef<uint8_t>(Stable, Record.size());
}
TypeIndex
AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
TypeIndex NewTI = nextTypeIndex();
uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size());
memcpy(Stable, Record.data(), Record.size());
Record = ArrayRef<uint8_t>(Stable, Record.size());
Record = stabilize(RecordStorage, Record);
SeenRecords.push_back(Record);
return NewTI;
}
@ -93,3 +98,15 @@ AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
TI = insertRecordBytes(C.RecordData);
return TI;
}
bool AppendingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
bool Stabilize) {
assert(Index.toArrayIndex() < SeenRecords.size() &&
"This function cannot be used to insert records!");
ArrayRef<uint8_t> Record = Data.data();
if (Stabilize)
Record = stabilize(RecordStorage, Record);
SeenRecords[Index.toArrayIndex()] = Record;
return true;
}

View File

@ -84,6 +84,13 @@ void GlobalTypeTableBuilder::reset() {
SeenRecords.clear();
}
static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
ArrayRef<uint8_t> Data) {
uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
memcpy(Stable, Data.data(), Data.size());
return makeArrayRef(Stable, Data.size());
}
TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) {
GloballyHashedType GHT =
GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
@ -104,3 +111,30 @@ GlobalTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
TI = insertRecordBytes(C.RecordData);
return TI;
}
bool GlobalTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
bool Stabilize) {
assert(Index.toArrayIndex() < SeenRecords.size() &&
"This function cannot be used to insert records!");
ArrayRef<uint8_t> Record = Data.data();
assert(Record.size() < UINT32_MAX && "Record too big");
assert(Record.size() % 4 == 0 &&
"The type record size is not a multiple of 4 bytes which will cause "
"misalignment in the output TPI stream!");
GloballyHashedType Hash =
GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
auto Result = HashedRecords.try_emplace(Hash, Index.toArrayIndex());
if (!Result.second) {
Index = Result.first->second;
return false; // The record is already there, at a different location
}
if (Stabilize)
Record = stabilize(RecordStorage, Record);
SeenRecords[Index.toArrayIndex()] = Record;
SeenHashes[Index.toArrayIndex()] = Hash;
return true;
}

View File

@ -277,3 +277,8 @@ void LazyRandomTypeCollection::visitRange(TypeIndex Begin, uint32_t BeginOffset,
++RI;
}
}
bool LazyRandomTypeCollection::replaceType(TypeIndex &Index, CVType Data,
bool Stabilize) {
llvm_unreachable("Method cannot be called");
}

View File

@ -123,3 +123,30 @@ MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
TI = insertRecordBytes(C.RecordData);
return TI;
}
bool MergingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
bool Stabilize) {
assert(Index.toArrayIndex() < SeenRecords.size() &&
"This function cannot be used to insert records!");
ArrayRef<uint8_t> Record = Data.data();
assert(Record.size() < UINT32_MAX && "Record too big");
assert(Record.size() % 4 == 0 &&
"The type record size is not a multiple of 4 bytes which will cause "
"misalignment in the output TPI stream!");
LocallyHashedType WeakHash{hash_value(Record), Record};
auto Result = HashedRecords.try_emplace(WeakHash, Index.toArrayIndex());
if (!Result.second) {
Index = Result.first->second;
return false; // The record is already there, at a different location
}
if (Stabilize) {
Record = stabilize(RecordStorage, Record);
Result.first->first.RecordData = Record;
}
SeenRecords[Index.toArrayIndex()] = Record;
return true;
}

View File

@ -58,3 +58,8 @@ bool TypeTableCollection::contains(TypeIndex Index) {
uint32_t TypeTableCollection::size() { return Records.size(); }
uint32_t TypeTableCollection::capacity() { return Records.size(); }
bool TypeTableCollection::replaceType(TypeIndex &Index, CVType Data,
bool Stabilize) {
llvm_unreachable("Method cannot be called");
}