aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-11-08 18:09:21 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-12-03 08:28:36 +0000
commit74d23ca548b47c85c4b8cdde5fd5a9026e4eb08c (patch)
treecaf94cffe04b7c6235ccfd5f117b17187733752b /src/3rdparty
parentfaf99c36d29bfad629fb6ec541ccc2f61ef93443 (diff)
V4: Generate function tables on 64bit windows
In order for global exception handlers to be called reliably, the runtime needs to unwind through JIT-generated code. This can be facilitated by installing a "function table" for each JITed function that specifies "use the frame pointer". Also make sure to generate a function table for JIT'ed regular expressions. Those were forgotten also in the linux case. Fixes: QTBUG-50061 Change-Id: Ib0b8ae9356ed80afe1cab017e36efa4ccbe73f90 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.h13
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h1
-rw-r--r--src/3rdparty/masm/yarr/YarrJIT.cpp40
-rw-r--r--src/3rdparty/masm/yarr/YarrJIT.h25
4 files changed, 63 insertions, 16 deletions
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index c79b0663c8..4dfd051797 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -228,6 +228,8 @@ public:
return m_size;
}
+ inline void makeExecutable();
+
private:
template <typename T> T applyOffset(T src)
{
@@ -353,6 +355,11 @@ inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performF
ASSERT(m_size <= INT_MAX);
MacroAssembler::cacheFlush(code(), m_size);
+}
+
+template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
+inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
+{
ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
}
@@ -389,6 +396,7 @@ public:
}
inline void performFinalization();
+ inline void makeExecutable();
inline void linkCode(void* ownerUID, JITCompilationEffort);
@@ -421,6 +429,11 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization()
#endif
MacroAssembler::cacheFlush(code(), m_size);
+}
+
+template <typename MacroAssembler>
+inline void BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable()
+{
ExecutableAllocator::makeExecutable(code(), m_initialSize);
}
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index 156b24b4e8..a439c53827 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -82,6 +82,7 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
inline bool isManaged() const { return true; }
+ void *exceptionHandler() { return m_allocation->exceptionHandler(); }
void *start() { return m_allocation->start(); }
size_t sizeInBytes() { return m_size; }
diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp
index 9a9ab581e8..73c919dd90 100644
--- a/src/3rdparty/masm/yarr/YarrJIT.cpp
+++ b/src/3rdparty/masm/yarr/YarrJIT.cpp
@@ -33,6 +33,8 @@
#include "Yarr.h"
#include "YarrCanonicalize.h"
+#include <private/qv4functiontable_p.h>
+
#if ENABLE(YARR_JIT)
using namespace WTF;
@@ -3529,17 +3531,30 @@ public:
m_backtrackingState.linkDataLabels(linkBuffer);
+ CodeRef codeRef;
if (compileMode == MatchOnly) {
- if (m_charSize == Char8)
- codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 8-bit regular expression"));
- else
- codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 16-bit regular expression"));
+ if (m_charSize == Char8) {
+ codeRef = FINALIZE_CODE(linkBuffer, "YarJIT",
+ "Match-only 8-bit regular expression");
+ codeBlock.set8BitCodeMatchOnly(codeRef);
+ } else {
+ codeRef = FINALIZE_CODE(linkBuffer, "YarJIT",
+ "Match-only 16-bit regular expression");
+ codeBlock.set16BitCodeMatchOnly(codeRef);
+ }
} else {
- if (m_charSize == Char8)
- codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression"));
- else
- codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression"));
+ if (m_charSize == Char8) {
+ codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression");
+ codeBlock.set8BitCode(codeRef);
+ } else {
+ codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression");
+ codeBlock.set16BitCode(codeRef);
+ }
}
+ QV4::generateFunctionTable(nullptr, &codeRef);
+
+ linkBuffer.makeExecutable();
+
if (m_failureReason)
codeBlock.setFallBackWithFailureReason(*m_failureReason);
}
@@ -3587,6 +3602,15 @@ private:
BacktrackingState m_backtrackingState;
};
+void YarrCodeBlock::replaceCodeRef(MacroAssemblerCodeRef &target,
+ const MacroAssemblerCodeRef &source)
+{
+ if (!!target && target.code().executableAddress() != source.code().executableAddress())
+ QV4::destroyFunctionTable(nullptr, &target);
+
+ target = source;
+}
+
static void dumpCompileFailure(JITFailureReason failure)
{
switch (failure) {
diff --git a/src/3rdparty/masm/yarr/YarrJIT.h b/src/3rdparty/masm/yarr/YarrJIT.h
index 8b6b3a7577..35a0690f6e 100644
--- a/src/3rdparty/masm/yarr/YarrJIT.h
+++ b/src/3rdparty/masm/yarr/YarrJIT.h
@@ -82,19 +82,28 @@ class YarrCodeBlock {
public:
YarrCodeBlock() = default;
+ ~YarrCodeBlock() { clear(); }
+
+ static void replaceCodeRef(MacroAssemblerCodeRef &target, const MacroAssemblerCodeRef &source);
void setFallBackWithFailureReason(JITFailureReason failureReason) { m_failureReason = failureReason; }
std::optional<JITFailureReason> failureReason() { return m_failureReason; }
bool has8BitCode() { return m_ref8.size(); }
bool has16BitCode() { return m_ref16.size(); }
- void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; }
- void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; }
+ void set8BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref8, ref); }
+ void set16BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref16, ref); }
bool has8BitCodeMatchOnly() { return m_matchOnly8.size(); }
bool has16BitCodeMatchOnly() { return m_matchOnly16.size(); }
- void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
- void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
+ void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly)
+ {
+ replaceCodeRef(m_matchOnly8, matchOnly);
+ }
+ void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly)
+ {
+ replaceCodeRef(m_matchOnly16, matchOnly);
+ }
#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; }
@@ -190,10 +199,10 @@ public:
void clear()
{
- m_ref8 = MacroAssemblerCodeRef();
- m_ref16 = MacroAssemblerCodeRef();
- m_matchOnly8 = MacroAssemblerCodeRef();
- m_matchOnly16 = MacroAssemblerCodeRef();
+ replaceCodeRef(m_ref8, MacroAssemblerCodeRef());
+ replaceCodeRef(m_ref16, MacroAssemblerCodeRef());
+ replaceCodeRef(m_matchOnly8, MacroAssemblerCodeRef());
+ replaceCodeRef(m_matchOnly16, MacroAssemblerCodeRef());
m_failureReason = std::nullopt;
}