aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2022-09-28 09:00:18 +0200
committerUlf Hermann <[email protected]>2022-10-06 20:38:02 +0200
commitffecc122d785de9c4c5defd8724526b8dd4982dc (patch)
tree1e53a45d9e919454a2dd101917fa0577ea8bfcbb /src
parent1e712c95cee58ae242a93c029a7f79cf65b43882 (diff)
masm: Treat Android as generic Posix regarding mmap and friends
Apparently we cannot rely on madvise() to work as we expect it on linux. Pick-to: 6.4 6.2 5.15 Fixes: QTBUG-106864 Fixes: QTBUG-106269 Change-Id: Ie488ad788386c1a8c493d6bba632787f5282baaa Reviewed-by: Fabian Kosmale <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorPosix.cpp23
-rw-r--r--src/qml/memory/qv4mm.cpp2
2 files changed, 17 insertions, 8 deletions
diff --git a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
index 868a101935..8ea6d7a3c2 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
@@ -36,7 +36,16 @@
#include <wtf/Assertions.h>
#include <wtf/UnusedParam.h>
-#if OS(LINUX)
+// Android does not really behave like linux here.
+// For example, madvise() randomly fails if we pass MADV_WILLNEED or MADV_DONTNEED.
+// Treat it as generic Posix.
+#if OS(LINUX) && !defined(__ANDROID__)
+#define NON_ANDROID_LINUX 1
+#else
+#define NON_ANDROID_LINUX 0
+#endif
+
+#if NON_ANDROID_LINUX
#include <sys/syscall.h>
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
@@ -85,7 +94,7 @@ static int memfdForUsage(size_t bytes, OSAllocator::Usage usage)
close(fd);
return -1;
}
-#elif OS(LINUX)
+#elif NON_ANDROID_LINUX
static int memfdForUsage(size_t bytes, OSAllocator::Usage usage)
{
UNUSED_PARAM(bytes);
@@ -104,7 +113,7 @@ void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable,
void* result = mmap(0, bytes, PROT_NONE, MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0);
if (result == MAP_FAILED)
CRASH();
-#elif OS(LINUX)
+#elif NON_ANDROID_LINUX
UNUSED_PARAM(writable);
UNUSED_PARAM(executable);
int fd = memfdForUsage(bytes, usage);
@@ -150,7 +159,7 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo
#if OS(DARWIN)
int fd = usage;
-#elif OS(LINUX)
+#elif NON_ANDROID_LINUX
int fd = memfdForUsage(bytes, usage);
if (fd != -1)
flags &= ~MAP_ANON;
@@ -198,7 +207,7 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo
mmap(static_cast<char*>(result) + bytes - pageSize(), pageSize(), PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, fd, 0);
}
-#if OS(LINUX)
+#if NON_ANDROID_LINUX
if (fd != -1)
close(fd);
#endif
@@ -216,7 +225,7 @@ void OSAllocator::commit(void* address, size_t bytes, bool writable, bool execut
protection |= PROT_EXEC;
if (MAP_FAILED == mmap(address, bytes, protection, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0))
CRASH();
-#elif OS(LINUX)
+#elif NON_ANDROID_LINUX
int protection = PROT_READ;
if (writable)
protection |= PROT_WRITE;
@@ -248,7 +257,7 @@ void OSAllocator::decommit(void* address, size_t bytes)
#if OS(QNX)
// Use PROT_NONE and MAP_LAZY to decommit the pages.
mmap(address, bytes, PROT_NONE, MAP_FIXED | MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0);
-#elif OS(LINUX)
+#elif NON_ANDROID_LINUX
while (madvise(address, bytes, MADV_DONTNEED)) {
if (errno != EAGAIN)
CRASH();
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 74829a21d9..717c59cb26 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -138,7 +138,7 @@ struct MemorySegment {
size_t pageSize = WTF::pageSize();
size = (size + pageSize - 1) & ~(pageSize - 1);
-#if !defined(Q_OS_LINUX) && !defined(Q_OS_WIN)
+#if (!defined(Q_OS_LINUX) && !defined(Q_OS_WIN)) || defined(Q_OS_ANDROID)
// Linux and Windows zero out pages that have been decommitted and get committed again.
// unfortunately that's not true on other OSes (e.g. BSD based ones), so zero out the
// memory before decommit, so that we can be sure that all chunks we allocate will be