This is an archive of the discontinued LLVM Phabricator instance.

[AppleTables] Implement iterator over all entries in table
ClosedPublic

Authored by fdeazeve on Jun 15 2023, 12:15 PM.

Details

Summary

This commit adds functionality to the Apple Accelerator table allowing iteration
over all elements in the table.

Our iterators look like streaming iterators: when we increment the iterator we
check if there is still enough data in the "stream" (in our case, the blob of
data of the accelerator table) and extract the next entry. If any failures
occur, we immediately set the iterator to be the end iterator.

Since the ultimate user of this functionality is LLDB, there are roughly two
iteration methods we want support: one that also loads the name of each entry,
and one which does not. Loading names is measurably slower (one order the
magnitude) than only loading DIEs, so we used some template metaprograming to
implement both iteration methods.

Diff Detail

Event Timeline

fdeazeve created this revision.Jun 15 2023, 12:15 PM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: cmtice. · View Herald Transcript
fdeazeve requested review of this revision.Jun 15 2023, 12:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 12:15 PM
fdeazeve updated this revision to Diff 531873.Jun 15 2023, 12:17 PM

Add review dependency

aprantl accepted this revision.Jun 15 2023, 12:38 PM
aprantl added inline comments.
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
260

should this be default initialized?

This revision is now accepted and ready to land.Jun 15 2023, 12:38 PM
dblaikie added inline comments.
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
256

Can you use any of the iterator helpers we have to ensure the whole iterator contract is implemented easily?

294–300

Rather than template metaprogramming - could this be done lazily? (store StrOffset as a member of some Entry type (either the current one, or some wrapper) and a member function of that entry could do the work on-request?

325–328

I don't think it's valid for forward iterators to return by value - I think yo uhave to create a pair as a member and return a reference to that. So that op-> can be implemented (since it needs to return a pointer).

fdeazeve added inline comments.Jun 16 2023, 5:18 AM
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
256

Oh I didn't know these exist, I'll have a look!

260

I'm not sure I follow the suggestion: the one and only constructor of the class ensures it is initialized properly. Is there some concern about initialization here?

294–300

That's an interesting one. Note that this *is* done lazily: we only do it if someone calls all_entries_with_names (instead of all_entries) which presumably means they are interested in the name.

That said we could add an extra member to the Entry class which would substantially simplify code and also enable me to address the other concern you had about operator ->! I'll give this a try.

325–328

Good point, let me give this a try

fdeazeve updated this revision to Diff 532179.Jun 16 2023, 8:49 AM

Address review comments

dblaikie added inline comments.Jun 16 2023, 10:56 AM
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
248

Ah, sorry, I probably wouldn't complicate this by deriving, needing a virtual dtor, etc.

Maybe composition? EntryWithName could be closer to the std::pair (but, yeah, it needs to be a bit smarter) than this - contains an Entry, the offset and a function to get the name.

fdeazeve updated this revision to Diff 532261.Jun 16 2023, 12:09 PM

Use composition instead of inheritance

llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
248

It seems that composition leaks a lot of the implementation to users of this class. For example, they will need to do Entry.BaseEntry.getDIESectionOffset instead of just Entry.getDIESectionOffset. To avoid this, we would need to copy all public methods of Entry and implement them by calling the corresponding method on the Entry member... but that's just re-implementing inheritance manually.

Note that the base class Entry still derives from a pure virtual class, even if we remove this new inheritance; the only reason the compiler was not giving a dtor warning before is because Entry was marked as final.

IMO the more artificial part of this hierarchy is the pure virtual class, which AFAICT is not taken advantage of (I couldn't find any virtual uses of them). I believe the original goal was that Apple tables and the Dwarf 5 tables could share an interface, but maybe it doesn't have to be a virtual interface, instead some sort of CRTP.

All that said, for now I have moved to composition instead of inheritance. If we feel like this becomes too cumbersome, we can re-evaluate.

dblaikie added inline comments.Jun 16 2023, 12:52 PM
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
248

Fair enough - I still tend a bit towards composition, though perhaps if you want to cleanup the virtual base, if it turns out it hasn't been useful - then maybe derivation isn't so bad?

252

If StrOffset is going to be public, probably could skip the accessor and mutate it directly?

260

yeah, I'd second the suggestion - I'd tend towards a member initializer over an init list, seems to simplify things a bit - if another ctor is added, if it's a clear default state for the member, etc

fdeazeve updated this revision to Diff 532389.Jun 17 2023, 6:04 AM

Remove accessor methods, use member initialization.

llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
252

Good point!

260

Sounds good, I'll initialize this to the end marker.

I can see why that is appealing, but personally believe it gives the false security that things are initialized properly. To use your example of a new ctor, consider the case someone forgets to initialize the member: no tool will catch this when member initialization was used. But tools exist to catch use of uninitialized variables/members (e.g. -Wuninitialized)

Hopefully I've addressed all the major concerns here, so I'll go ahead and merge this; happy to address any other suggestions afterwards!

MaskRay added inline comments.Jul 19 2023, 7:49 PM
llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
466

This relies on the iteration order of StringMap and SmallSet, which is not good. I'll fix this to use MapVector.