As requested by @labath in https://reviews.llvm.org/D73206#1949516 (D73206) providing DWARF index callbacks refactorization.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
250 ms | LLVM.Other::Unknown Unit Message ("") |
Event Timeline
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
134 | Semantics of the callback is apparent - return true if the caller no longer needs any more data. Not sure where to document that, maybe it is simple enough in the code. | |
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp | ||
68–69 | DIEInfoArray is not callback-optimized in this patch. That could be done as an add-on patch. | |
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp | ||
84 | The meaning of return_implementation_only_if_available has changed here. The only caller was using it with true so now the only existing caller calls it twice - first with true and then with false as we can no longer do the original die_offsets.clear();. |
Thanks for doing this. This looks more-or-less like what I was expecting. The need for the "bool" return value from the index functions is unfortunate (I did not anticipate that), but it does seem unavoidable.
Since none of these functions (I guess) are storing the callback function, could you replace std::function with llvm::function_ref ?
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
130–163 | I'm not sure these functions are really needed. They have just one caller, and they'd be trivial if this class provided appropriate abstractions. Maybe just add begin/end/equal_range methods, so that one can write: for (value: map / map.equal_range(str)) stuff ? (ideally, I'd like to have iterators instead of callbacks for the index classes too, but iterators and class hierarchies don't mix very well) | |
lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h | ||
79–80 | Maybe rename this to ProcessEntry or something? |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
130–163 | Do you mean the standard iteration: for (std::pair<ConstString, DIERef> pair : map) stuff; or really for (DIERef ref : map) stuff; ? |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
130–163 | Implemented. IIUC for regexes it should be matched in a caller - or to make also an iterator for regexes? for (const auto &entry : m_map.equal_range(name)) if (callback(entry.value)) for (const auto &entry : m_map) if (regex.Execute(entry.cstring.GetCString())) { if (callback(entry.value)) |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
101 | /// |
I can't say I have tried this, but ummm.. why is there a need for a separate iterator class for this equal_range stuff? Couldn't this be implemented via an iterator_pair of the iterators of the underlying container (found via lower/upper_bound) ?
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
130–163 | Yes, that is correct. |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
101 | I am sorry but all comments in this file are // . I can make a conversion of the file to Doxygen in a separate file if you wish but I am not sure how much is Doxygen widespread in LLDB etc. | |
102 | This custom iterator has been now dropped upon advice by @labath the standard iterator is enough. | |
133 |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
208–213 | Looks better, but I have a feeling it could be simplified even further. Wouldn't a plain return llvm::make_range(std::equal_range(m_map.begin(), m_map.end(), Compare()); work just as well? (Sorry for taking you down the wrong path with the lower/upper_bound comment -- equal_range is basically a combination of lower_bound and upper_bound calls.) |
lldb/include/lldb/Core/UniqueCStringMap.h | ||
---|---|---|
208–213 | Yes, sorry, I was never using these functions before. |
I just had one more idea. The bool return value on all of these methods, is that here just to implement the fallback mechanism in DebugNamesDWARFIndex? Could it be avoided if debug_names index calls the "fallback" *after* it has done its own processing?
Most of them yes. There are still some functions needing to return bool to benefit from the early returns from callbacks. I hope I found the minimal set of such bool functions (none of those are in DWARFIndex).
Could it be avoided if debug_names index calls the "fallback" *after* it has done its own processing?
Yes. Done so now. I still do not understand what is DebugNamesDWARFIndex good for when it always calls ManualDWARFIndex anyway.
Cool. I am very sorry about the back-and-forth but I just noticed another issue. The normal semantics of callbacks like these is to return true when one wants to continue iterating (e.g. [[ https://github.com/llvm/llvm-project/blob/cdc514e4c67f268b07863bbac3d8d7e0d088186c/lldb/include/lldb/Core/MappedHash.h#L293 | here ]). This patch has the meanings reversed. I think it would be good to maintain the current convention.
Otherwise this looks good, and I really hope this will be the last iteration.
Could it be avoided if debug_names index calls the "fallback" *after* it has done its own processing?
Yes. Done so now. I still do not understand what is DebugNamesDWARFIndex good for when it always calls ManualDWARFIndex anyway.
One cannot guarantee that the debug_names section will cover all compilation units in a given file. So we still need to call the manual index to index the rest. However we pass it a list of units it should avoid (see DebugNamesDWARFIndex constructor), so we don't index everything twice.
Theoretically the calls to the fallback index could be guarded by an if (debug_names_really_covers_everything) check, but that wouldn't really help anything -- in that case the manual index would index an empty set of units and so all calls to it would be a quick no-op anyway.
OK, fixed, thanks for catching it.
One cannot guarantee that the debug_names section will cover all compilation units in a given file. So we still need to call the manual index to index the rest. However we pass it a list of units it should avoid (see DebugNamesDWARFIndex constructor), so we don't index everything twice.
OK, that llvm::DenseSet<dw_offset_t> units_to_avoid. Thanks for the explanation, it makes sense now.
I had to revert it: rG9289f34390da
It has caused a regression: lang/cpp/accelerator-table/TestCPPAccelerator.py
http://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/15323/consoleFull
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp | ||
---|---|---|
140 | I have found a bug/regression here, during the last check-in there was: if (!m_apple_types_up->FindByName(context[1].name, Just I cannot test it now myself without OSX. |
lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp | ||
---|---|---|
140 | Just tried that change on macOS, and this indeed fixes the regression. Just waiting for the test suite run to finish to make sure it didn't break something else. |
///