Inline the fast path of a few methods

No need to do function calls for the case where we return immediately
after checking a boolean.

Pick-to: dev 6.0.0
Change-Id: I3e449850a10fcf82acb843cce6da6dfd98de32ad
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Lars Knoll 2020-11-25 13:05:37 +01:00
parent b1be6e6e6f
commit e165f416a7
3 changed files with 37 additions and 18 deletions

View File

@ -123,10 +123,9 @@ void QPropertyBindingPrivate::markDirtyAndNotifyObservers()
staticObserverCallback(propertyDataPtr); staticObserverCallback(propertyDataPtr);
} }
bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged(const QUntypedPropertyData *data) bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged_helper(const QUntypedPropertyData *data, QBindingStatus *status)
{ {
if (!dirty) Q_ASSERT(dirty);
return false;
if (updating) { if (updating) {
error = QPropertyBindingError(QPropertyBindingError::BindingLoop); error = QPropertyBindingError(QPropertyBindingError::BindingLoop);
@ -144,7 +143,7 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged(const Q
QPropertyBindingPrivatePtr keepAlive {this}; QPropertyBindingPrivatePtr keepAlive {this};
QScopedValueRollback<bool> updateGuard(updating, true); QScopedValueRollback<bool> updateGuard(updating, true);
BindingEvaluationState evaluationFrame(this); BindingEvaluationState evaluationFrame(this, status);
bool changed = false; bool changed = false;
@ -288,22 +287,17 @@ QPropertyBindingData::QPropertyBindingData(QPropertyBindingData &&other) : d_ptr
d.fixupFirstObserverAfterMove(); d.fixupFirstObserverAfterMove();
} }
QPropertyBindingPrivate *QPropertyBindingData::binding() const
{
QPropertyBindingDataPointer d{this};
if (auto binding = d.bindingPtr())
return binding;
return nullptr;
}
static thread_local QBindingStatus bindingStatus; static thread_local QBindingStatus bindingStatus;
BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding) BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status)
: binding(binding) : binding(binding)
{ {
QBindingStatus *s = status;
if (!s)
s = &bindingStatus;
// store a pointer to the currentBindingEvaluationState to avoid a TLS lookup in // store a pointer to the currentBindingEvaluationState to avoid a TLS lookup in
// the destructor (as these come with a non zero cost) // the destructor (as these come with a non zero cost)
currentState = &bindingStatus.currentlyEvaluatingBinding; currentState = &s->currentlyEvaluatingBinding;
previousState = *currentState; previousState = *currentState;
*currentState = this; *currentState = this;
binding->clearDependencyObservers(); binding->clearDependencyObservers();
@ -352,7 +346,12 @@ void QPropertyBindingData::registerWithCurrentlyEvaluatingBinding() const
auto currentState = bindingStatus.currentlyEvaluatingBinding; auto currentState = bindingStatus.currentlyEvaluatingBinding;
if (!currentState) if (!currentState)
return; return;
registerWithCurrentlyEvaluatingBinding_helper(currentState);
}
void QPropertyBindingData::registerWithCurrentlyEvaluatingBinding_helper(BindingEvaluationState *currentState) const
{
QPropertyBindingDataPointer d{this}; QPropertyBindingDataPointer d{this};
QPropertyObserverPointer dependencyObserver = currentState->binding->allocateDependencyObserver(); QPropertyObserverPointer dependencyObserver = currentState->binding->allocateDependencyObserver();

View File

@ -123,7 +123,7 @@ namespace QtPrivate {
struct BindingEvaluationState struct BindingEvaluationState
{ {
BindingEvaluationState(QPropertyBindingPrivate *binding); BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status = nullptr);
~BindingEvaluationState() ~BindingEvaluationState()
{ {
*currentState = previousState; *currentState = previousState;
@ -277,7 +277,12 @@ public:
void unlinkAndDeref(); void unlinkAndDeref();
void markDirtyAndNotifyObservers(); void markDirtyAndNotifyObservers();
bool evaluateIfDirtyAndReturnTrueIfValueChanged(const QUntypedPropertyData *data); bool evaluateIfDirtyAndReturnTrueIfValueChanged(const QUntypedPropertyData *data, QBindingStatus *status = nullptr)
{
if (!dirty)
return false;
return evaluateIfDirtyAndReturnTrueIfValueChanged_helper(data, status);
}
static QPropertyBindingPrivate *get(const QUntypedPropertyBinding &binding) static QPropertyBindingPrivate *get(const QUntypedPropertyBinding &binding)
{ return static_cast<QPropertyBindingPrivate *>(binding.d.data()); } { return static_cast<QPropertyBindingPrivate *>(binding.d.data()); }
@ -307,6 +312,8 @@ public:
delete[] reinterpret_cast<std::byte *>(priv); delete[] reinterpret_cast<std::byte *>(priv);
} }
} }
private:
bool evaluateIfDirtyAndReturnTrueIfValueChanged_helper(const QUntypedPropertyData *data, QBindingStatus *status = nullptr);
}; };
inline void QPropertyBindingDataPointer::setFirstObserver(QPropertyObserver *observer) inline void QPropertyBindingDataPointer::setFirstObserver(QPropertyObserver *observer)

View File

@ -158,6 +158,7 @@ template <typename T>
class QPropertyData; class QPropertyData;
namespace QtPrivate { namespace QtPrivate {
struct BindingEvaluationState;
struct BindingFunctionVTable struct BindingFunctionVTable
{ {
@ -238,14 +239,26 @@ public:
QPropertyObserverCallback staticObserverCallback = nullptr, QPropertyObserverCallback staticObserverCallback = nullptr,
QPropertyBindingWrapper bindingWrapper = nullptr); QPropertyBindingWrapper bindingWrapper = nullptr);
QPropertyBindingPrivate *binding() const; QPropertyBindingPrivate *binding() const
{
if (d_ptr & BindingBit)
return reinterpret_cast<QPropertyBindingPrivate*>(d_ptr - BindingBit);
return nullptr;
}
void evaluateIfDirty(const QUntypedPropertyData *property) const; void evaluateIfDirty(const QUntypedPropertyData *property) const;
void removeBinding(); void removeBinding();
void registerWithCurrentlyEvaluatingBinding(QtPrivate::BindingEvaluationState *currentBinding) const
{
if (!currentBinding)
return;
registerWithCurrentlyEvaluatingBinding_helper(currentBinding);
}
void registerWithCurrentlyEvaluatingBinding() const; void registerWithCurrentlyEvaluatingBinding() const;
void registerWithCurrentlyEvaluatingBinding_helper(BindingEvaluationState *currentBinding) const;
void notifyObservers(QUntypedPropertyData *propertyDataPtr) const; void notifyObservers(QUntypedPropertyData *propertyDataPtr) const;
}; };
template <typename T, typename Tag> template <typename T, typename Tag>