QDirListing: Extract Method next() from const_iterator::op++()

Having the actual const_iterator::operator++() as an out-of-line
member function means that the implicit this pointer forces the object
onto the stack (registers don't have addresses that could be
passed). Since const_iterator is now merely a thinly-disguised
pointer, that would cause terrible codegen.

So, apply a technique originally developed for QStringView and make
the operator an inline function that re-sets the member dirEntry using
a call to a QDirListing static function that takes and returns by
value. Passing by value enables passing in registers, which means the
iterator object can now be a register value and doesn't require
spilling to the stack to call the function.

Found in API-review.

Change-Id: I9f4d5be5b72249b368ef3dea9d857178ca7e16aa
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit aec8398d71d351e956683a695af51317fe65097e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2024-09-02 18:54:59 +02:00 committed by Qt Cherry-pick Bot
parent 46ec49894d
commit 892012e5d9
2 changed files with 15 additions and 4 deletions

View File

@ -723,14 +723,23 @@ QDirListing::const_iterator QDirListing::begin() const
*/
/*!
\fn QDirListing::const_iterator::operator++()
Advances the iterator and returns a reference to it.
*/
QDirListing::const_iterator &QDirListing::const_iterator::operator++()
/*!
\internal
Implements the actual advancing. Not a member function to avoid forcing
DirEntry objects (and therefore const_iterator ones) onto the stack.
*/
auto QDirListing::next(DirEntry dirEntry) -> DirEntry
{
dirEntry.dirListPtr->advance();
if (!dirEntry.dirListPtr->hasIterators())
*this = {}; // All done, make `this` equal to the end() iterator
return *this;
return {}; // All done, make `this` equal to the end() iterator
return dirEntry;
}
/*!

View File

@ -119,7 +119,7 @@ public:
reference operator*() const { return dirEntry; }
pointer operator->() const { return &dirEntry; }
Q_CORE_EXPORT const_iterator &operator++();
const_iterator &operator++() { dirEntry = next(dirEntry); return *this; }
void operator++(int) { ++*this; }; // [iterator.concept.winc]/14 not required to return sth
private:
bool atEnd() const noexcept { return dirEntry.dirListPtr == nullptr; }
@ -146,6 +146,8 @@ public:
private:
Q_DISABLE_COPY(QDirListing)
Q_CORE_EXPORT static DirEntry next(DirEntry);
// Private constructor that is used in deprecated code paths.
// `uint` instead of QDir::Filters and QDirIterator::IteratorFlags
// because qdir.h can't be included here; qdiriterator.h can't included