diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-07-22 11:27:06 -0700 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-02-08 14:00:20 +0000 |
commit | 847dfa77e9b5d93f7dbb6b78665f1f86d4431a02 (patch) | |
tree | cab24121ef391e1278b5b1866d49b0ad44fd78bd /src/3rdparty | |
parent | 319b5059d6b6ae3eaebfd302cfa7080ac77eef82 (diff) |
Add a feature to mark mmap-allocated pages on Linux too
We can't tag mmap anonymous segments, like Mach/Darwin can, but we can
use a memfd (which can take a name) and then its name will show in
/proc/PID/maps. For example, pmap shows for tst_qjsengine at an
arbitrary point I stopped execution at:
Address Kbytes RSS PSS Dirty Swap Mode Mapping
00007f9cc2db7000 2040 4 4 4 0 rw-p- /memfd:JSVMStack:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cc2fb7000 4344 4 4 4 0 rw-p- /memfd:JSVMStack:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cc33f6000 40 0 0 0 0 ---p- /memfd:JSGCHeap:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cc3400000 128 64 64 64 0 rw-p- /memfd:JSGCHeap:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cc3420000 3928 0 0 0 0 ---p- /memfd:JSGCHeap:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cd099e000 4 4 4 4 0 rw-p- /memfd:unknown-usage:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
00007f9cd099f000 4 4 4 4 0 r-xp- /memfd:JITCode:/home/tjmaciei/obj/qt/qt5/qtbase/lib/libQt5Qml.t.so.5 (deleted)
I suppose that before upstreaming this patch, we'd change the "QtQml"
name prefix or remove it.
Change-Id: I84e45059a888497fb55ffffd14d3ba60f9707051
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/3rdparty')
-rw-r--r-- | src/3rdparty/masm/masm.pri | 5 | ||||
-rw-r--r-- | src/3rdparty/masm/wtf/OSAllocatorPosix.cpp | 80 | ||||
-rw-r--r-- | src/3rdparty/masm/wtf/VMTags.h | 8 |
3 files changed, 91 insertions, 2 deletions
diff --git a/src/3rdparty/masm/masm.pri b/src/3rdparty/masm/masm.pri index 6c301fea38..aeb9babb05 100644 --- a/src/3rdparty/masm/masm.pri +++ b/src/3rdparty/masm/masm.pri @@ -127,3 +127,8 @@ QMAKE_EXTRA_COMPILERS += retgen } } } + +linux { + requires(qtConfig(dlopen)) + QMAKE_USE_PRIVATE += libdl +} diff --git a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp index 0c902c7172..17a5150de5 100644 --- a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp +++ b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp @@ -31,13 +31,75 @@ #include <cstdlib> #include "PageAllocation.h" +#include <dlfcn.h> #include <errno.h> #include <sys/mman.h> #include <wtf/Assertions.h> #include <wtf/UnusedParam.h> +#if OS(LINUX) +#include <sys/syscall.h> +#ifndef MFD_CLOEXEC +#define MFD_CLOEXEC 0x0001U +#endif +#endif + namespace WTF { +#ifdef SYS_memfd_create +static int memfdForUsage(size_t bytes, OSAllocator::Usage usage) +{ + const char *type = "unknown-usage:"; + switch (usage) { + case OSAllocator::UnknownUsage: + break; + case OSAllocator::FastMallocPages: + type = "fastmalloc:"; + break; + case OSAllocator::JSGCHeapPages: + type = "JSGCHeap:"; + break; + case OSAllocator::JSVMStackPages: + type = "JSVMStack:"; + break; + case OSAllocator::JSJITCodePages: + type = "JITCode:"; + break; + } + + // try to get our own library name by giving dladdr a pointer pointing to + // something we know to be in it (using a pointer to string data) + static const char *libname = [=]() { + Dl_info info; + if (dladdr(type, &info) == 0) + info.dli_fname = nullptr; + return info.dli_fname; + }(); + + char buf[PATH_MAX]; + strcpy(buf, type); + if (libname) + strcat(buf, libname); + else + strcat(buf, "QtQml"); + + int fd = syscall(SYS_memfd_create, buf, MFD_CLOEXEC); + if (fd != -1) { + if (ftruncate(fd, bytes) == 0) + return fd; + } + close(fd); + return -1; +} +#elif OS(LINUX) +static int memfdForUsage(size_t bytes, OSAllocator::Usage usage) +{ + UNUSED_PARAM(bytes); + UNUSED_PARAM(usage); + return -1; +} +#endif + void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable) { #if OS(QNX) @@ -46,14 +108,18 @@ void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, if (result == MAP_FAILED) CRASH(); #elif OS(LINUX) - UNUSED_PARAM(usage); UNUSED_PARAM(writable); UNUSED_PARAM(executable); + int fd = memfdForUsage(bytes, usage); - void* result = mmap(0, bytes, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0); + void* result = mmap(0, bytes, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | + (fd == -1 ? MAP_ANON : 0), fd, 0); if (result == MAP_FAILED) CRASH(); madvise(result, bytes, MADV_DONTNEED); + + if (fd != -1) + close(fd); #else void* result = reserveAndCommit(bytes, usage, writable, executable); #if HAVE(MADV_FREE_REUSE) @@ -83,6 +149,10 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo #if OS(DARWIN) int fd = usage; +#elif OS(LINUX) && defined(SYS_memfd_create) + int fd = memfdForUsage(bytes, usage); + if (fd != -1) + flags &= ~MAP_ANON; #else UNUSED_PARAM(usage); int fd = -1; @@ -126,6 +196,12 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo mmap(result, pageSize(), PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, fd, 0); mmap(static_cast<char*>(result) + bytes - pageSize(), pageSize(), PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, fd, 0); } + +#if OS(LINUX) + if (fd != -1) + close(fd); +#endif + return result; } diff --git a/src/3rdparty/masm/wtf/VMTags.h b/src/3rdparty/masm/wtf/VMTags.h index 117bc3721e..af5352e471 100644 --- a/src/3rdparty/masm/wtf/VMTags.h +++ b/src/3rdparty/masm/wtf/VMTags.h @@ -62,6 +62,14 @@ #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69) #endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) +#elif OS(LINUX) + +#define VM_TAG_FOR_TCMALLOC_MEMORY 0 +#define VM_TAG_FOR_COLLECTOR_MEMORY 1 +#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY 2 +#define VM_TAG_FOR_REGISTERFILE_MEMORY 3 +#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY 4 + #else // OS(DARWIN) #define VM_TAG_FOR_TCMALLOC_MEMORY -1 |