aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-10-15 08:36:17 +0200
committerLars Knoll <lars.knoll@qt.io>2018-11-02 09:10:59 +0000
commit19b87999580d596a3b14e38f44309f16307bfe0e (patch)
tree8f1c40ca296a6414246002519af64aa124ce240c
parentacd0882f818bf05677e3e117dbd4975674d9578b (diff)
Fix a crash when allocating huge memory segments
When allocating a huge item that requires it's own memory segment, we were actually not committing enough memory from the OS. Fixes: QTBUG-71501 Change-Id: Ic86a648bba4d7f1eeeded78d8de0f0fc1d3a251d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qml/memory/qv4mm.cpp5
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp12
2 files changed, 14 insertions, 3 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index fb6d9478db..97254b9172 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -666,11 +666,10 @@ HeapItem *HugeItemAllocator::allocate(size_t size) {
Chunk *c = nullptr;
if (size >= MemorySegment::SegmentSize/2) {
// too large to handle through the ChunkAllocator, let's get our own memory segement
- size_t segmentSize = size + Chunk::HeaderSize; // space required for the Chunk header
+ size += Chunk::HeaderSize; // space required for the Chunk header
size_t pageSize = WTF::pageSize();
- segmentSize = (segmentSize + pageSize - 1) & ~(pageSize - 1); // align to page sizes
- m = new MemorySegment(segmentSize);
size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ m = new MemorySegment(size);
c = m->allocate(size);
} else {
c = chunkAllocator->allocate(size);
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 8f388fcac6..2f110ed5a5 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -359,6 +359,7 @@ private slots:
void temporaryDeadZone();
void importLexicalVariables_data();
void importLexicalVariables();
+ void hugeObject();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -8846,6 +8847,17 @@ void tst_qqmlecmascript::importLexicalVariables()
QCOMPARE(result, QVariant(expected));
}
+void tst_qqmlecmascript::hugeObject()
+{
+ // mainly check that this doesn't crash
+ QJSEngine engine;
+ QJSValue v = engine.evaluate(QString::fromLatin1(
+ "var known = {}, prefix = 'x'\n"
+ "for (var i = 0; i < 150000; i++) known[prefix + i] = true;"
+ ));
+ QVERIFY(!v.isError());
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"