diff options
author | Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com> | 2014-10-28 12:21:13 +0100 |
---|---|---|
committer | Jędrzej Nowacki <jedrzej.nowacki@digia.com> | 2014-10-30 16:41:39 +0100 |
commit | 053e8c41d7f87a07cb1a74cd95bd030ac138dc4e (patch) | |
tree | 935142c0b5058421aade79b3f1000da7439bac19 /src/tools/moc | |
parent | 8c77a7f77a8111bcbe51532f788679777910ebd5 (diff) |
Use file mapping in moc.
The change reduces heap allocations by using file mapping instead of
reading a whole file into memory just to create a slightly modified
copy of it.
For this small test case:
moc <<EOF
class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };
EOF
massif shows improvement from:
peak cost: "26,8 KB" heap "2,1 KB" heap extra "0 B" stacks
to:
peak cost: "11,3 KB" heap "2,2 KB" heap extra "0 B" stacks
In general, depending on source file high peak memory usage is reduced
from few to few hundreds KB, especially that the allocation used to
happen for each include file too.
Change-Id: I9c1c848be848444156af25a991b67161fb9d8b29
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/preprocessor.cpp | 26 | ||||
-rw-r--r-- | src/tools/moc/preprocessor.h | 4 |
2 files changed, 20 insertions, 10 deletions
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 087b064c0f..ff435085b4 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -52,11 +52,12 @@ static QByteArray cleaned(const QByteArray &input) QByteArray result; result.reserve(input.size()); const char *data = input.constData(); + const char *end = input.constData() + input.size(); char *output = result.data(); int newlines = 0; - while (*data) { - while (*data && is_space(*data)) + while (data != end) { + while (data != end && is_space(*data)) ++data; bool takeLine = (*data == '#'); if (*data == '%' && *(data+1) == ':') { @@ -66,15 +67,15 @@ static QByteArray cleaned(const QByteArray &input) if (takeLine) { *output = '#'; ++output; - do ++data; while (*data && is_space(*data)); + do ++data; while (data != end && is_space(*data)); } - while (*data) { + while (data != end) { // handle \\\n, \\\r\n and \\\r if (*data == '\\') { if (*(data + 1) == '\r') { ++data; } - if (*data && (*(data + 1) == '\n' || (*data) == '\r')) { + if (data != end && (*(data + 1) == '\n' || (*data) == '\r')) { ++newlines; data += 1; if (*data != '\r') @@ -964,6 +965,13 @@ int Preprocessor::evaluateCondition() return expression.value(); } +static QByteArray readOrMapFile(QFile *file) +{ + const qint64 size = file->size(); + char *rawInput = reinterpret_cast<char*>(file->map(0, size)); + return rawInput ? QByteArray::fromRawData(rawInput, size) : file->readAll(); +} + void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); @@ -1020,7 +1028,8 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) if (!file.open(QFile::ReadOnly)) continue; - QByteArray input = file.readAll(); + QByteArray input = readOrMapFile(&file); + file.close(); if (input.isEmpty()) continue; @@ -1157,9 +1166,10 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) currentFilenames.pop(); } -Symbols Preprocessor::preprocessed(const QByteArray &filename, QIODevice *file) +Symbols Preprocessor::preprocessed(const QByteArray &filename, QFile *file) { - QByteArray input = file->readAll(); + QByteArray input = readOrMapFile(file); + if (input.isEmpty()) return symbols; diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index fc86781be8..77f3a30ac0 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -57,7 +57,7 @@ typedef SubArray MacroName; #endif typedef QHash<MacroName, Macro> Macros; -class QIODevice; +class QFile; class Preprocessor : public Parser { @@ -67,7 +67,7 @@ public: QList<QByteArray> frameworks; QSet<QByteArray> preprocessedIncludes; Macros macros; - Symbols preprocessed(const QByteArray &filename, QIODevice *device); + Symbols preprocessed(const QByteArray &filename, QFile *device); void parseDefineArguments(Macro *m); |