debugger: speed up QDate, QTime, QDateTime dumpers

Change-Id: I9ed3961d047738bd3add87b1f00d548df1fb01d8
Reviewed-on: http://codereview.qt.nokia.com/3609
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
hjk
2011-08-19 15:47:34 +02:00
committed by hjk
parent 9fa409cbd9
commit 8d936cec6e
7 changed files with 96 additions and 68 deletions

View File

@@ -66,8 +66,11 @@ Hex2EncodedUtf8, \
Hex8EncodedBigEndian, \ Hex8EncodedBigEndian, \
Hex4EncodedBigEndian, \ Hex4EncodedBigEndian, \
Hex4EncodedLittleEndianWithoutQuotes, \ Hex4EncodedLittleEndianWithoutQuotes, \
Hex2EncodedLocal8Bit \ Hex2EncodedLocal8Bit, \
= range(14) JulianDate, \
MillisecondsSinceMidnight, \
JulianDateAndMillisecondsSinceMidnight \
= range(17)
# Display modes # Display modes
StopDisplay, \ StopDisplay, \

View File

@@ -139,14 +139,10 @@ def qdump__QModelIndex(d, value):
def qdump__QDate(d, value): def qdump__QDate(d, value):
if int(value["jd"]) == 0: d.putValue(value["jd"], JulianDate)
d.putValue("(null)")
d.putNumChild(0)
return
qt = d.ns + "Qt::"
d.putStringValue(call(value, "toString", qt + "TextDate"))
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
qt = d.ns + "Qt::"
# FIXME: This improperly uses complex return values. # FIXME: This improperly uses complex return values.
with Children(d): with Children(d):
d.putCallItem("toString", value, "toString", qt + "TextDate") d.putCallItem("toString", value, "toString", qt + "TextDate")
@@ -157,14 +153,10 @@ def qdump__QDate(d, value):
def qdump__QTime(d, value): def qdump__QTime(d, value):
if int(value["mds"]) == -1: d.putValue(value["mds"], MillisecondsSinceMidnight)
d.putValue("(null)")
d.putNumChild(0)
return
qt = d.ns + "Qt::"
d.putStringValue(call(value, "toString", qt + "TextDate"))
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
qt = d.ns + "Qt::"
# FIXME: This improperly uses complex return values. # FIXME: This improperly uses complex return values.
with Children(d): with Children(d):
d.putCallItem("toString", value, "toString", qt + "TextDate") d.putCallItem("toString", value, "toString", qt + "TextDate")
@@ -178,19 +170,17 @@ def qdump__QTime(d, value):
def qdump__QDateTime(d, value): def qdump__QDateTime(d, value):
try: try:
# Fails without debug info. # Fails without debug info.
if int(value["d"]["d"].dereference()["time"]["mds"]) == -1: p = value["d"]["d"].dereference()
d.putValue("(null)")
d.putNumChild(0)
return
except: except:
d.putPlainChildren(value) d.putPlainChildren(value)
return return
qt = d.ns + "Qt::" d.putValue("%s/%s" % (p["date"]["jd"], p["time"]["mds"]),
d.putStringValue(call(value, "toString", qt + "TextDate")) JulianDateAndMillisecondsSinceMidnight)
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
# FIXME: This improperly uses complex return values. # FIXME: This improperly uses complex return values.
with Children(d): with Children(d):
qt = d.ns + "Qt::"
d.putCallItem("toTime_t", value, "toTime_t") d.putCallItem("toTime_t", value, "toTime_t")
d.putCallItem("toString", value, "toString", qt + "TextDate") d.putCallItem("toString", value, "toString", qt + "TextDate")
d.putCallItem("(ISO)", value, "toString", qt + "ISODate") d.putCallItem("(ISO)", value, "toString", qt + "ISODate")

View File

@@ -274,25 +274,25 @@ static QString niceTypeHelper(const QByteArray &typeIn)
return simplified; return simplified;
} }
static QString removeNamespaces(QString str, const QByteArray &ns) QString WatchModel::removeNamespaces(QString str) const
{ {
if (!debuggerCore()->boolSetting(ShowStdNamespace)) if (!debuggerCore()->boolSetting(ShowStdNamespace))
str.remove(QLatin1String("std::")); str.remove(QLatin1String("std::"));
if (!debuggerCore()->boolSetting(ShowQtNamespace)) { if (!debuggerCore()->boolSetting(ShowQtNamespace)) {
const QString qtNamespace = QString::fromLatin1(ns); const QString qtNamespace = QString::fromLatin1(engine()->qtNamespace());
if (!qtNamespace.isEmpty()) if (!qtNamespace.isEmpty())
str.remove(qtNamespace); str.remove(qtNamespace);
} }
return str; return str;
} }
static QString removeInitialNamespace(QString str, const QByteArray &ns) QString WatchModel::removeInitialNamespace(QString str) const
{ {
if (str.startsWith(QLatin1String("std::")) if (str.startsWith(QLatin1String("std::"))
&& debuggerCore()->boolSetting(ShowStdNamespace)) && debuggerCore()->boolSetting(ShowStdNamespace))
str = str.mid(5); str = str.mid(5);
if (!debuggerCore()->boolSetting(ShowQtNamespace)) { if (!debuggerCore()->boolSetting(ShowQtNamespace)) {
const QString qtNamespace = QString::fromLatin1(ns); const QByteArray qtNamespace = engine()->qtNamespace();
if (!qtNamespace.isEmpty() && str.startsWith(qtNamespace)) if (!qtNamespace.isEmpty() && str.startsWith(qtNamespace))
str = str.mid(qtNamespace.size()); str = str.mid(qtNamespace.size());
} }
@@ -395,41 +395,45 @@ static QString quoteUnprintable(const QString &str)
return encoded; return encoded;
} }
static QString formattedValue(const WatchData &data, int format) QString WatchModel::formattedValue(const WatchData &data) const
{ {
const QByteArray qtNamespace = engine()->qtNamespace();
const QString &value = data.value;
int format = itemFormat(data);
if (isIntType(data.type)) { if (isIntType(data.type)) {
if (data.value.isEmpty()) if (value.isEmpty())
return data.value; return value;
// Do not reformat booleans (reported as 'true, false'). // Do not reformat booleans (reported as 'true, false').
const QChar firstChar = data.value.at(0); const QChar firstChar = value.at(0);
if (!firstChar.isDigit() && firstChar != QLatin1Char('-')) if (!firstChar.isDigit() && firstChar != QLatin1Char('-'))
return data.value; return value;
// Append quoted, printable character also for decimal. // Append quoted, printable character also for decimal.
if (data.type.endsWith("char")) { if (data.type.endsWith("char")) {
bool ok; bool ok;
const int code = data.value.toInt(&ok); const int code = value.toInt(&ok);
return ok ? reformatCharacter(code, format) : data.value; return ok ? reformatCharacter(code, format) : value;
} }
// Rest: Leave decimal as is // Rest: Leave decimal as is
if (format <= 0) if (format <= 0)
return data.value; return value;
// Evil hack, covers 'unsigned' as well as quint64. // Evil hack, covers 'unsigned' as well as quint64.
if (data.type.contains('u')) if (data.type.contains('u'))
return reformatInteger(data.value.toULongLong(0, 0), format); return reformatInteger(value.toULongLong(0, 0), format);
return reformatInteger(data.value.toLongLong(), format); return reformatInteger(value.toLongLong(), format);
} }
if (data.type == "va_list") if (data.type == "va_list")
return data.value; return value;
if (!isPointerType(data.type) && !isVTablePointer(data.type)) { if (!isPointerType(data.type) && !isVTablePointer(data.type)) {
bool ok = false; bool ok = false;
qulonglong integer = data.value.toULongLong(&ok, 0); qulonglong integer = value.toULongLong(&ok, 0);
if (ok) if (ok)
return reformatInteger(integer, format); return reformatInteger(integer, format);
} }
QString result = data.value; QString result = value;
if (result.startsWith(QLatin1Char('<'))) { if (result.startsWith(QLatin1Char('<'))) {
if (result == QLatin1String("<Edit>")) if (result == QLatin1String("<Edit>"))
result = WatchHandler::tr("<Edit>"); result = WatchHandler::tr("<Edit>");
@@ -446,7 +450,8 @@ static QString formattedValue(const WatchData &data, int format)
bool ok; bool ok;
const bool moreThan = result.at(1) == QLatin1Char('>'); const bool moreThan = result.at(1) == QLatin1Char('>');
const int numberPos = moreThan ? 2 : 1; const int numberPos = moreThan ? 2 : 1;
const int size = result.mid(numberPos, result.indexOf(' ') - numberPos).toInt(&ok); const int len = result.indexOf(' ') - numberPos;
const int size = result.mid(numberPos, len).toInt(&ok);
QTC_ASSERT(ok, qWarning("WatchHandler: Invalid item count '%s'", QTC_ASSERT(ok, qWarning("WatchHandler: Invalid item count '%s'",
qPrintable(result))) qPrintable(result)))
result = moreThan ? result = moreThan ?
@@ -629,8 +634,8 @@ void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex)
emitDataChanged(column, index(i, 0, parentIndex)); emitDataChanged(column, index(i, 0, parentIndex));
} }
// Truncate value for item view, maintaining quotes // Truncate value for item view, maintaining quotes.
static inline QString truncateValue(QString v) static QString truncateValue(QString v)
{ {
enum { maxLength = 512 }; enum { maxLength = 512 };
if (v.size() < maxLength) if (v.size() < maxLength)
@@ -699,7 +704,6 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
} }
case Qt::DisplayRole: { case Qt::DisplayRole: {
const QByteArray qtNameSpace = engine()->qtNamespace();
QString result; QString result;
switch (idx.column()) { switch (idx.column()) {
case 0: case 0:
@@ -708,18 +712,18 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
else if (data.name == QLatin1String("*") && item->parent) else if (data.name == QLatin1String("*") && item->parent)
result = QLatin1Char('*') + item->parent->name; result = QLatin1Char('*') + item->parent->name;
else else
result = removeInitialNamespace(data.name, qtNameSpace); result = removeInitialNamespace(data.name);
break; break;
case 1: case 1:
result = removeInitialNamespace(truncateValue( result = removeInitialNamespace(
formattedValue(data, itemFormat(data))), qtNameSpace); truncateValue(formattedValue(data)));
if (data.referencingAddress) { if (data.referencingAddress) {
result += QLatin1String(" @"); result += QLatin1String(" @");
result += QString::fromLatin1(data.hexAddress()); result += QString::fromLatin1(data.hexAddress());
} }
break; break;
case 2: case 2:
result = removeNamespaces(displayType(data), qtNameSpace); result = removeNamespaces(displayType(data));
break; break;
default: default:
break; break;
@@ -787,7 +791,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return m_handler->m_reportedTypeFormats.value(type); return m_handler->m_reportedTypeFormats.value(type);
} }
case LocalsTypeRole: case LocalsTypeRole:
return removeNamespaces(displayType(data), engine()->qtNamespace()); return removeNamespaces(displayType(data));
case LocalsRawTypeRole: case LocalsRawTypeRole:
return QString::fromLatin1(data.type); return QString::fromLatin1(data.type);
case LocalsTypeFormatRole: case LocalsTypeFormatRole:

View File

@@ -121,6 +121,9 @@ signals:
private: private:
QString displayType(const WatchData &typeIn) const; QString displayType(const WatchData &typeIn) const;
QString formattedValue(const WatchData &data) const;
QString removeInitialNamespace(QString str) const;
QString removeNamespaces(QString str) const;
void formatRequests(QByteArray *out, const WatchItem *item) const; void formatRequests(QByteArray *out, const WatchItem *item) const;
DebuggerEngine *engine() const; DebuggerEngine *engine() const;
int itemFormat(const WatchData &data) const; int itemFormat(const WatchData &data) const;

View File

@@ -55,12 +55,13 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <QtCore/QDebug>
#include <QtCore/QTime>
#include <QtCore/QStringList>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QTextStream> #include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
#include <QtCore/QTime>
#include <QtGui/QTextCursor> #include <QtGui/QTextCursor>
#include <QtGui/QPlainTextEdit> #include <QtGui/QPlainTextEdit>
@@ -518,6 +519,16 @@ QString quoteUnprintableLatin1(const QByteArray &ba)
return res; return res;
} }
static QDate dateFromData(int jd)
{
return jd ? QDate::fromJulianDay(jd) : QDate();
}
static QTime timeFromData(int ms)
{
return ms == -1 ? QTime() : QTime(0, 0, 0, 0).addMSecs(ms);
}
QString decodeData(const QByteArray &ba, int encoding) QString decodeData(const QByteArray &ba, int encoding)
{ {
switch (encoding) { switch (encoding) {
@@ -613,6 +624,20 @@ QString decodeData(const QByteArray &ba, int encoding)
const QByteArray decodedBa = QByteArray::fromHex(ba); const QByteArray decodedBa = QByteArray::fromHex(ba);
return doubleQuote + QString::fromLocal8Bit(decodedBa) + doubleQuote; return doubleQuote + QString::fromLocal8Bit(decodedBa) + doubleQuote;
} }
case JulianDate: { // 14, an integer count
const QDate date = dateFromData(ba.toInt());
return date.toString(Qt::TextDate);
}
case MillisecondsSinceMidnight: {
const QTime time = timeFromData(ba.toInt());
return time.toString(Qt::TextDate);
}
case JulianDateAndMillisecondsSinceMidnight: {
const int p = ba.indexOf('/');
const QDate date = dateFromData(ba.left(p).toInt());
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
return QDateTime(date, time).toString(Qt::TextDate);
}
} }
qDebug() << "ENCODING ERROR: " << encoding; qDebug() << "ENCODING ERROR: " << encoding;
return QCoreApplication::translate("Debugger", "<Encoding error>"); return QCoreApplication::translate("Debugger", "<Encoding error>");

View File

@@ -56,20 +56,23 @@ class GdbMi;
// Keep in sync with dumper.py // Keep in sync with dumper.py
enum DebuggerEncoding enum DebuggerEncoding
{ {
Unencoded8Bit = 0, Unencoded8Bit = 0,
Base64Encoded8BitWithQuotes = 1, Base64Encoded8BitWithQuotes = 1,
Base64Encoded16BitWithQuotes = 2, Base64Encoded16BitWithQuotes = 2,
Base64Encoded32BitWithQuotes = 3, Base64Encoded32BitWithQuotes = 3,
Base64Encoded16Bit = 4, Base64Encoded16Bit = 4,
Base64Encoded8Bit = 5, Base64Encoded8Bit = 5,
Hex2EncodedLatin1WithQuotes = 6, Hex2EncodedLatin1WithQuotes = 6,
Hex4EncodedLittleEndianWithQuotes = 7, Hex4EncodedLittleEndianWithQuotes = 7,
Hex8EncodedLittleEndianWithQuotes = 8, Hex8EncodedLittleEndianWithQuotes = 8,
Hex2EncodedUtf8WithQuotes = 9, Hex2EncodedUtf8WithQuotes = 9,
Hex8EncodedBigEndian = 10, Hex8EncodedBigEndian = 10,
Hex4EncodedBigEndianWithQuotes = 11, Hex4EncodedBigEndianWithQuotes = 11,
Hex4EncodedLittleEndianWithoutQuotes = 12, Hex4EncodedLittleEndianWithoutQuotes = 12,
Hex2EncodedLocal8BitWithQuotes = 13 Hex2EncodedLocal8BitWithQuotes = 13,
JulianDate = 14,
MillisecondsSinceMidnight = 15,
JulianDateAndMillisecondsSinceMidnight = 16
}; };
bool isEditorDebuggable(Core::IEditor *editor); bool isEditorDebuggable(Core::IEditor *editor);

View File

@@ -40,13 +40,13 @@
// lines containing the BREAK_HERE macro. This should be enabled // lines containing the BREAK_HERE macro. This should be enabled
// during manual testing. // during manual testing.
// Default: 1 // Default: 1
#define USE_AUTOBREAK 1 #define USE_AUTOBREAK 0
// With USE_UNINITIALIZE_AUTOBREAK, the debugger will stop automatically // With USE_UNINITIALIZE_AUTOBREAK, the debugger will stop automatically
// on all lines containing the BREAK_UNINITIALIZED_HERE macro. // on all lines containing the BREAK_UNINITIALIZED_HERE macro.
// This should be enabled during manual testing. // This should be enabled during manual testing.
// Default: 1 // Default: 1
#define USE_UNINITIALIZED_AUTOBREAK 1 #define USE_UNINITIALIZED_AUTOBREAK 0
// With USE_PRIVATE tests that require private headers are enabled. // With USE_PRIVATE tests that require private headers are enabled.
// Default: 1 // Default: 1
@@ -2758,7 +2758,7 @@ namespace basic {
QDateTime time = QDateTime::currentDateTime(); QDateTime time = QDateTime::currentDateTime();
const int N = 10000; const int N = 10000;
QDateTime bigv[N]; QDateTime bigv[N];
for (int i = 0; i < N; ++i) { for (int i = 0; i < 10000; ++i) {
bigv[i] = time; bigv[i] = time;
time.addDays(1); time.addDays(1);
} }
@@ -2772,7 +2772,7 @@ namespace basic {
{ {
const int N = 10000; const int N = 10000;
int bigv[N]; int bigv[N];
for (int i = 0; i < N; ++i) for (int i = 0; i < 10000; ++i)
bigv[i] = i; bigv[i] = i;
BREAK_HERE; BREAK_HERE;
// Expand bigv. // Expand bigv.