summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2016-05-12 19:15:23 -0700
committerThiago Macieira <thiago.macieira@intel.com>2016-06-10 17:57:13 +0000
commit72393ac3b6a8231d1157c58fe049606dd6c95736 (patch)
tree9f17ac162a1a6fe2ed4a2f8236bc34519e422b1b /src
parentd1395b76cfb7207ccd8a8df4a613bed07acedf69 (diff)
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 <edward.welbourne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qdatetime.cpp35
1 files changed, 30 insertions, 5 deletions
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<QDate, QTime> 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<QDateTimePrivate *>(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;