aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h5
-rw-r--r--src/3rdparty/masm/wtf/OSAllocator.h2
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorPosix.cpp5
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorWin.cpp5
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp104
5 files changed, 111 insertions, 10 deletions
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index 578a944bf9..1ddad01de9 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -33,6 +33,11 @@
#ifndef MASM_EXECUTABLEALLOCATOR_H
#define MASM_EXECUTABLEALLOCATOR_H
+// Defined via mkspec
+#if _MSC_VER >= 1900
+#include <windows.h>
+#endif
+
#include <RefPtr.h>
#include <RefCounted.h>
#include <wtf/PageBlock.h>
diff --git a/src/3rdparty/masm/wtf/OSAllocator.h b/src/3rdparty/masm/wtf/OSAllocator.h
index 494f8bc3c7..933b3cda0a 100644
--- a/src/3rdparty/masm/wtf/OSAllocator.h
+++ b/src/3rdparty/masm/wtf/OSAllocator.h
@@ -71,6 +71,8 @@ public:
// This interface is provided since it may be possible to optimize this operation on some platforms.
template<typename T>
static T* reallocateCommitted(T*, size_t oldSize, size_t newSize, Usage = UnknownUsage, bool writable = true, bool executable = false);
+
+ static bool canAllocateExecutableMemory();
};
inline void* OSAllocator::reserveAndCommit(size_t reserveSize, size_t commitSize, Usage usage, bool writable, bool executable)
diff --git a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
index f52c22f7fa..bbf11e4488 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
@@ -189,6 +189,11 @@ void OSAllocator::releaseDecommitted(void* address, size_t bytes)
CRASH();
}
+bool OSAllocator::canAllocateExecutableMemory()
+{
+ return true;
+}
+
} // namespace WTF
#endif // OS(UNIX)
diff --git a/src/3rdparty/masm/wtf/OSAllocatorWin.cpp b/src/3rdparty/masm/wtf/OSAllocatorWin.cpp
index 259fc67324..bb934264ab 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorWin.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorWin.cpp
@@ -90,6 +90,11 @@ void OSAllocator::releaseDecommitted(void* address, size_t bytes)
CRASH();
}
+bool OSAllocator::canAllocateExecutableMemory()
+{
+ return true;
+}
+
} // namespace WTF
#endif // OS(WINDOWS)
diff --git a/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp b/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
index d684367ec6..b7ad723f07 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
@@ -25,12 +25,27 @@
#include "config.h"
#include "OSAllocator.h"
+#include "PageBlock.h"
#if OS(WINRT)
#include "windows.h"
#include <wtf/Assertions.h>
+#if _MSC_VER >= 1900
+// Try to use JIT by default and fallback to non-JIT on first error
+static bool qt_winrt_use_jit = true;
+#else // _MSC_VER < 1900
+# define PAGE_EXECUTE 0x10
+# define PAGE_EXECUTE_READ 0x20
+# define PAGE_EXECUTE_READWRITE 0x40
+# define MEM_RELEASE 0x8000
+inline void* VirtualAllocFromApp(void*, size_t, int, int) { return 0; }
+inline bool VirtualProtectFromApp(void *, size_t, int, DWORD*) { return false; }
+inline bool VirtualFree(void *, size_t, DWORD) { return false; }
+static bool qt_winrt_use_jit = false;
+#endif // _MSC_VER < 1900
+
namespace WTF {
inline size_t getPageSize()
@@ -40,19 +55,58 @@ inline size_t getPageSize()
return info.dwPageSize;
}
-void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool, bool)
+static inline DWORD protection(bool writable, bool executable)
{
- static const size_t pageSize = getPageSize();
- void* result = _aligned_malloc(bytes, pageSize);
- if (!result)
- CRASH();
- memset(result, 0, bytes);
+ if (writable && executable)
+ qFatal("read/write executable areas are not allowed on WinRT");
+ return executable ?
+ (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
+ (writable ? PAGE_READWRITE : PAGE_READONLY);
+}
+
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool writable, bool executable)
+{
+ void *result;
+ if (qt_winrt_use_jit) {
+ result = VirtualAllocFromApp(0, bytes, MEM_RESERVE, protection(writable, executable));
+ if (!result) {
+ qt_winrt_use_jit = false;
+ return reserveUncommitted(bytes, UnknownUsage, writable, executable);
+ }
+ } else {
+ static const size_t pageSize = getPageSize();
+ result = _aligned_malloc(bytes, pageSize);
+ if (!result)
+ CRASH();
+ memset(result, 0, bytes);
+ }
return result;
}
-void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool)
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool includesGuardPages)
{
- return reserveUncommitted(bytes, usage, writable, executable);
+ void *result;
+ if (qt_winrt_use_jit) {
+ result = VirtualAllocFromApp(0, bytes, MEM_RESERVE | MEM_COMMIT,
+ protection(writable, executable));
+ if (!result) {
+ qt_winrt_use_jit = false;
+ return reserveAndCommit(bytes, usage, writable, executable, includesGuardPages);
+ }
+
+ if (includesGuardPages) {
+ size_t guardSize = pageSize();
+ DWORD oldProtect;
+ if (!VirtualProtectFromApp(result, guardSize, protection(false, false), &oldProtect) ||
+ !VirtualProtectFromApp(static_cast<char*>(result) + bytes - guardSize, guardSize,
+ protection(false, false), &oldProtect)) {
+ CRASH();
+ }
+ }
+ } else {
+ result = reserveUncommitted(bytes, usage, writable, executable);
+ }
+ return result;
}
void OSAllocator::commit(void*, size_t, bool, bool)
@@ -62,14 +116,44 @@ void OSAllocator::commit(void*, size_t, bool, bool)
void OSAllocator::decommit(void* address, size_t)
{
- _aligned_free(address);
+ if (qt_winrt_use_jit)
+ Q_UNREACHABLE();
+ else
+ _aligned_free(address);
}
void OSAllocator::releaseDecommitted(void* address, size_t bytes)
{
- decommit(address, bytes);
+ if (qt_winrt_use_jit) {
+ bool result = VirtualFree(address, 0, MEM_RELEASE);
+ if (!result)
+ CRASH();
+ } else {
+ decommit(address, bytes);
+ }
}
+bool OSAllocator::canAllocateExecutableMemory()
+{
+ if (qt_winrt_use_jit) {
+ // For WinRT we first check if code generation is enabled. If successful
+ // we allow to use JIT, otherwise fallback to the interpreter
+ const size_t pageSize = getPageSize();
+ void *all = VirtualAllocFromApp(0, pageSize, MEM_RESERVE | MEM_COMMIT,
+ protection(true, false));
+ DWORD oldProtect;
+ bool res = VirtualProtectFromApp(all, pageSize, PAGE_EXECUTE, &oldProtect);
+ VirtualFree(all, 0, MEM_RELEASE);
+ if (!res) {
+ qt_winrt_use_jit = false;
+ qWarning("Could not enable JIT, fallback to interpreter mode. "
+ "Consider setting the code-generation capability");
+ }
+ }
+ return qt_winrt_use_jit;
+}
+
+
} // namespace WTF
#endif // OS(WINRT)