This is an archive of the discontinued LLVM Phabricator instance.

PDB: Add a class to create the /names stream contents.
ClosedPublic

Authored by ruiu on Jan 13 2017, 3:06 PM.

Details

Summary

This patch adds a new class NameHashTableBuilder which creates /names streams.
This patch contains a test to confirm that a stream created by
NameHashTableBuilder can be read by NameHashTable reader class.

Diff Detail

Repository
rL LLVM

Event Timeline

ruiu updated this revision to Diff 84394.Jan 13 2017, 3:06 PM
ruiu retitled this revision from to PDB: Add a class to create the /names stream contents..
ruiu updated this object.
ruiu added a reviewer: zturner.
ruiu added a subscriber: llvm-commits.
zturner edited edge metadata.Jan 13 2017, 3:40 PM

It seems like this would be more appropriate as a YAML test, since that is the way we're testing everything else.

ruiu added a comment.Jan 13 2017, 3:49 PM

I will eventually do that, but that's not doable at the moment. In order to test this output with YAM, we need to plug this in to other parts so that PDB files get this string table. Currently doing that doesn't make much sense because no one is using the string table, and we have no code for that.

Also I think this unit test is useful by itself. This is compact and does only what it should do.

zturner added inline comments.Jan 13 2017, 4:59 PM
llvm/lib/DebugInfo/PDB/Raw/NameHashTableBuilder.cpp
22 ↗(On Diff #84394)

NameHashTable has a structure for reading the header into. I think we should re-use that rather than hardcoding the number. Can you move the Header structure from NameHashTable.cpp into the .h file, and then re-use it here by filling out the fields and then just calling Writer.writeObject(H)?

33–34 ↗(On Diff #84394)

Nitpick: This looks like it's wrapped too soon, well before before 80 characters.

40 ↗(On Diff #84394)

Can you call this computeBucketCount? compute entries sounds like you might compute the actual values of some entries rather than the number of them.

49 ↗(On Diff #84394)

I would prefer if this method is called commit() and takes the same signature as the other methods. (i.e. a StreamWriter&). You will also need to add a calculateSerializedLength() method. If you want to write to a buffer and return it, you can do something like this:

std::vector<uint32_t> Buffer(Builder.calculateSerializedLength());
msf::MutableByteStream Stream(Buffer);
msf::StreamWriter Writer(Stream);
if (auto EC = Builder.commit(Writer))
  return EC;
// The bytes of `Buffer` should be filled out now.

This also makes the body of the method cleaner, because it gets rid of a lot of the offset bookkeeping and manual incrementing, and it handles endianness for you as well.

if (auto EC = Writer.writeObject(H)) return EC;
for (auto Pair : Strings) {
  Writer.setOffset(Pair.second);
  if (auto EC = Writer.writeFixedString(S))
    return EC;
}

Writer.setOffset(StringSize);
if (auto EC = Writer.writeInteger(NumEntries) return EC;

etc etc.

ruiu updated this revision to Diff 84415.Jan 13 2017, 6:40 PM
ruiu edited edge metadata.
  • Updated as per Zach's comments.
zturner accepted this revision.Jan 13 2017, 7:51 PM
zturner edited edge metadata.

lgtm aside from the mentioned changes

llvm/include/llvm/DebugInfo/PDB/Raw/NameHashTableBuilder.h
38 ↗(On Diff #84415)

How about StringMap, which is quite a bit more efficient than DenseMap when the keys are strings?

llvm/lib/DebugInfo/PDB/Raw/NameHashTableBuilder.cpp
96 ↗(On Diff #84415)

Is the conversion to ArrayRef necessary? It should get converted implicitly I think.

This revision is now accepted and ready to land.Jan 13 2017, 7:51 PM
ruiu added inline comments.Jan 14 2017, 4:45 PM
llvm/lib/DebugInfo/PDB/Raw/NameHashTableBuilder.cpp
96 ↗(On Diff #84415)

Seems like I need to convert to ArrayRef since writeArray is a overloaded function.

This revision was automatically updated to reflect the committed changes.
ruiu added a comment.Jan 14 2017, 6:55 PM

Sorry for not mentioning that in the previous message. I tried to use StringMap, but it seems that the class doesn't provide an iterator to iterate both keys and values at the same time, so it didn't work well. Also I think StringMap copies strings into a map, so it needs more memory.