From 72393ac3b6a8231d1157c58fe049606dd6c95736 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 12 May 2016 19:15:23 -0700 Subject: Allow QDateTime to shrink back to short data mode on copy We won't shrink on manipulation when we have memory allocated, but it's a good idea to create a non-shared copy if we can. It's an unlikely scenario, though, because it requires the QDateTime object to have been set to a large state then manipulated back into a small state. Change-Id: I06bae9392f534e45b3f1ffff144dfee755bafa01 Reviewed-by: Edward Welbourne --- src/corelib/tools/qdatetime.cpp | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'src/corelib/tools/qdatetime.cpp') diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index a33f6daa66..4c19034bb1 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2482,6 +2482,11 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, } } +static inline bool specCanBeSmall(Qt::TimeSpec spec) +{ + return spec == Qt::LocalTime || spec == Qt::UTC; +} + static Q_DECL_CONSTEXPR inline QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status, Qt::TimeSpec spec) { @@ -2731,7 +2736,7 @@ static QPair getDateTime(const QDateTimeData &d) inline QDateTime::Data::Data(Qt::TimeSpec spec) { - if (CanBeSmall && Q_LIKELY(spec == Qt::LocalTime || spec == Qt::UTC)) { + if (CanBeSmall && Q_LIKELY(specCanBeSmall(spec))) { d = reinterpret_cast(int(mergeSpec(QDateTimePrivate::ShortData, spec))); } else { // the structure is too small, we need to detach @@ -2744,8 +2749,18 @@ inline QDateTime::Data::Data(Qt::TimeSpec spec) inline QDateTime::Data::Data(const Data &other) : d(other.d) { - if (!isShort()) - d->ref.ref(); + if (!isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(d->m_status)) && sd.msecs == d->m_msecs) { + sd.status = d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + d->ref.ref(); + } + } } inline QDateTime::Data &QDateTime::Data::operator=(const Data &other) @@ -2755,8 +2770,18 @@ inline QDateTime::Data &QDateTime::Data::operator=(const Data &other) auto x = d; d = other.d; - if (!other.isShort()) - other.d->ref.ref(); + if (!other.isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(other.d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(other.d->m_status)) && sd.msecs == other.d->m_msecs) { + sd.status = other.d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + other.d->ref.ref(); + } + } if (!(CanBeSmall && quintptr(x) & QDateTimePrivate::ShortData) && !x->ref.deref()) delete x; -- cgit v1.2.3