Warning, /graphics/krita/3rdparty/ext_qt/0137-masm-Add-error-handling-for-failed-mprotect.patch is written in an unsupported language. File is not indexed.

0001 From 4b7586b88b7bb611f72c0a1cfca9b2c257da84a2 Mon Sep 17 00:00:00 2001
0002 From: Ulf Hermann <ulf.hermann@qt.io>
0003 Date: Mon, 11 Jan 2021 11:33:26 +0100
0004 Subject: [PATCH 137/139] masm: Add error handling for failed mprotect()
0005 
0006 If we cannot mprotect() we have to abort the JIT compilation. Delete
0007 RepatchBuffer.h as it is unfixable in that regard. Luckily we don't use
0008 it.
0009 
0010 Task-number: QTBUG-89659
0011 Change-Id: Ic5ddbdf51b471db4ddeaa75aab48b24c1f7ced56
0012 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
0013 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
0014 (cherry picked from commit 131e2c81d40e3d324c62e113749a08e7993d008f)
0015 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
0016 (cherry picked from commit ab15d9a547dbd83bec99366e7f7b0449fdcdb6ef)
0017 Signed-off-by: L. E. Segovia <amy@amyspark.me>
0018 ---
0019  .../masm/assembler/AbstractMacroAssembler.h   |   2 -
0020  src/3rdparty/masm/assembler/AssemblerBuffer.h |   3 +-
0021  src/3rdparty/masm/assembler/LinkBuffer.h      |  19 +-
0022  .../masm/assembler/MacroAssemblerARMv7.h      |   1 -
0023  .../masm/assembler/MacroAssemblerMIPS.h       |   1 -
0024  .../masm/assembler/MacroAssemblerX86.h        |   1 -
0025  .../masm/assembler/MacroAssemblerX86_64.h     |   1 -
0026  src/3rdparty/masm/assembler/RepatchBuffer.h   | 181 ------------------
0027  src/3rdparty/masm/stubs/ExecutableAllocator.h |  14 +-
0028  src/3rdparty/masm/yarr/YarrJIT.cpp            |   3 +-
0029  src/qml/jit/qv4assemblercommon.cpp            |   3 +-
0030  src/qml/jsruntime/qv4vme_moth.cpp             |   5 +-
0031  12 files changed, 29 insertions(+), 205 deletions(-)
0032  delete mode 100644 src/3rdparty/masm/assembler/RepatchBuffer.h
0033 
0034 diff --git a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h
0035 index d0c1c461..9bafa243 100644
0036 --- a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h
0037 +++ b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h
0038 @@ -51,7 +51,6 @@ template <typename, template <typename> class>
0039  class LinkBufferBase;
0040  template <typename>
0041  class BranchCompactingLinkBuffer;
0042 -class RepatchBuffer;
0043  class Watchpoint;
0044  namespace DFG {
0045  struct OSRExit;
0046 @@ -831,7 +830,6 @@ protected:
0047  
0048      template <typename, template <typename> class> friend class LinkBufferBase;
0049      template <typename> friend class BranchCompactingLinkBuffer;
0050 -    friend class RepatchBuffer;
0051  
0052      static void linkJump(void* code, Jump jump, CodeLocationLabel target)
0053      {
0054 diff --git a/src/3rdparty/masm/assembler/AssemblerBuffer.h b/src/3rdparty/masm/assembler/AssemblerBuffer.h
0055 index 2292a4c2..58ecac2a 100644
0056 --- a/src/3rdparty/masm/assembler/AssemblerBuffer.h
0057 +++ b/src/3rdparty/masm/assembler/AssemblerBuffer.h
0058 @@ -140,7 +140,8 @@ namespace JSC {
0059              if (!result)
0060                  return 0;
0061  
0062 -            ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize());
0063 +            if (Q_UNLIKELY(!ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize())))
0064 +                return 0;
0065  
0066              memcpy(result->codeStart(), m_buffer, m_index);
0067              
0068 diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
0069 index aef35662..d9b5959f 100644
0070 --- a/src/3rdparty/masm/assembler/LinkBuffer.h
0071 +++ b/src/3rdparty/masm/assembler/LinkBuffer.h
0072 @@ -228,7 +228,7 @@ public:
0073          return m_size;
0074      }
0075  
0076 -    inline void makeExecutable();
0077 +    inline bool makeExecutable();
0078  
0079  private:
0080      template <typename T> T applyOffset(T src)
0081 @@ -358,10 +358,10 @@ void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinaliza
0082  }
0083  
0084  template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
0085 -inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
0086 +inline bool LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
0087  {
0088 -    ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(),
0089 -                                        m_executableMemory->memorySize());
0090 +    return ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(),
0091 +                                               m_executableMemory->memorySize());
0092  }
0093  
0094  template <typename MacroAssembler>
0095 @@ -397,7 +397,7 @@ public:
0096      }
0097  
0098      virtual void performFinalization() override final;
0099 -    inline void makeExecutable();
0100 +    inline bool makeExecutable();
0101  
0102      inline void linkCode(void* ownerUID, JITCompilationEffort);
0103  
0104 @@ -433,9 +433,9 @@ void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization()
0105  }
0106  
0107  template <typename MacroAssembler>
0108 -inline void BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable()
0109 +inline bool BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable()
0110  {
0111 -    ExecutableAllocator::makeExecutable(code(), m_initialSize);
0112 +    return ExecutableAllocator::makeExecutable(code(), m_initialSize);
0113  }
0114  
0115  template <typename MacroAssembler>
0116 @@ -448,9 +448,12 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID,
0117      m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
0118      if (!m_executableMemory)
0119          return;
0120 +    if (Q_UNLIKELY(!ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize()))) {
0121 +        m_executableMemory = {};
0122 +        return;
0123 +    }
0124      m_code = (uint8_t*)m_executableMemory->codeStart();
0125      ASSERT(m_code);
0126 -    ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize());
0127      uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
0128      uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
0129      int readPtr = 0;
0130 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
0131 index 99801a0e..dd66eefb 100644
0132 --- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
0133 +++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
0134 @@ -2022,7 +2022,6 @@ protected:
0135      
0136  private:
0137      template <typename, template <typename> class> friend class LinkBufferBase;
0138 -    friend class RepatchBuffer;
0139  
0140  #if !defined(V4_BOOTSTRAP)
0141      static void linkCall(void* code, Call call, FunctionPtr function)
0142 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
0143 index 07f0ec62..6dfc1048 100644
0144 --- a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
0145 +++ b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
0146 @@ -2818,7 +2818,6 @@ private:
0147      bool m_fixedWidth;
0148  
0149      template <typename, template <typename> class> friend class LinkBufferBase;
0150 -    friend class RepatchBuffer;
0151  
0152      static void linkCall(void* code, Call call, FunctionPtr function)
0153      {
0154 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86.h b/src/3rdparty/masm/assembler/MacroAssemblerX86.h
0155 index e3e0bfe5..bf5deeb1 100644
0156 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86.h
0157 +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86.h
0158 @@ -345,7 +345,6 @@ public:
0159  
0160  private:
0161      template <typename, template <typename> class> friend class LinkBufferBase;
0162 -    friend class RepatchBuffer;
0163  
0164      static void linkCall(void* code, Call call, FunctionPtr function)
0165      {
0166 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
0167 index f4349e1f..c419bcd7 100644
0168 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
0169 +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
0170 @@ -743,7 +743,6 @@ public:
0171  
0172  private:
0173      template <typename, template <typename> class> friend class LinkBufferBase;
0174 -    friend class RepatchBuffer;
0175  
0176      static void linkCall(void* code, Call call, FunctionPtr function)
0177      {
0178 diff --git a/src/3rdparty/masm/assembler/RepatchBuffer.h b/src/3rdparty/masm/assembler/RepatchBuffer.h
0179 deleted file mode 100644
0180 index dbb56f9a..00000000
0181 --- a/src/3rdparty/masm/assembler/RepatchBuffer.h
0182 +++ /dev/null
0183 @@ -1,181 +0,0 @@
0184 -/*
0185 - * Copyright (C) 2009 Apple Inc. All rights reserved.
0186 - *
0187 - * Redistribution and use in source and binary forms, with or without
0188 - * modification, are permitted provided that the following conditions
0189 - * are met:
0190 - * 1. Redistributions of source code must retain the above copyright
0191 - *    notice, this list of conditions and the following disclaimer.
0192 - * 2. Redistributions in binary form must reproduce the above copyright
0193 - *    notice, this list of conditions and the following disclaimer in the
0194 - *    documentation and/or other materials provided with the distribution.
0195 - *
0196 - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
0197 - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0198 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0199 - * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
0200 - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0201 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0202 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0203 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0204 - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0205 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0206 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
0207 - */
0208 -
0209 -#ifndef RepatchBuffer_h
0210 -#define RepatchBuffer_h
0211 -
0212 -#if ENABLE(JIT)
0213 -
0214 -#include "CodeBlock.h"
0215 -#include <MacroAssembler.h>
0216 -#include <wtf/Noncopyable.h>
0217 -
0218 -namespace JSC {
0219 -
0220 -// RepatchBuffer:
0221 -//
0222 -// This class is used to modify code after code generation has been completed,
0223 -// and after the code has potentially already been executed.  This mechanism is
0224 -// used to apply optimizations to the code.
0225 -//
0226 -class RepatchBuffer {
0227 -    typedef MacroAssemblerCodePtr CodePtr;
0228 -
0229 -public:
0230 -    RepatchBuffer(CodeBlock* codeBlock)
0231 -    {
0232 -        JITCode& code = codeBlock->getJITCode();
0233 -        m_start = code.start();
0234 -        m_size = code.size();
0235 -
0236 -        ExecutableAllocator::makeWritable(m_start, m_size);
0237 -    }
0238 -
0239 -    ~RepatchBuffer()
0240 -    {
0241 -        ExecutableAllocator::makeExecutable(m_start, m_size);
0242 -    }
0243 -
0244 -    void relink(CodeLocationJump jump, CodeLocationLabel destination)
0245 -    {
0246 -        MacroAssembler::repatchJump(jump, destination);
0247 -    }
0248 -
0249 -    void relink(CodeLocationCall call, CodeLocationLabel destination)
0250 -    {
0251 -        MacroAssembler::repatchCall(call, destination);
0252 -    }
0253 -
0254 -    void relink(CodeLocationCall call, FunctionPtr destination)
0255 -    {
0256 -        MacroAssembler::repatchCall(call, destination);
0257 -    }
0258 -
0259 -    void relink(CodeLocationNearCall nearCall, CodePtr destination)
0260 -    {
0261 -        MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination));
0262 -    }
0263 -
0264 -    void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination)
0265 -    {
0266 -        MacroAssembler::repatchNearCall(nearCall, destination);
0267 -    }
0268 -
0269 -    void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value)
0270 -    {
0271 -        MacroAssembler::repatchInt32(dataLabel32, value);
0272 -    }
0273 -
0274 -    void repatch(CodeLocationDataLabelCompact dataLabelCompact, int32_t value)
0275 -    {
0276 -        MacroAssembler::repatchCompact(dataLabelCompact, value);
0277 -    }
0278 -
0279 -    void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value)
0280 -    {
0281 -        MacroAssembler::repatchPointer(dataLabelPtr, value);
0282 -    }
0283 -
0284 -    void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
0285 -    {
0286 -        relink(CodeLocationCall(CodePtr(returnAddress)), label);
0287 -    }
0288 -    
0289 -    void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
0290 -    {
0291 -        relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
0292 -    }
0293 -
0294 -    void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function)
0295 -    {
0296 -        relink(CodeLocationCall(CodePtr(returnAddress)), function);
0297 -    }
0298 -    
0299 -    void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
0300 -    {
0301 -        relink(CodeLocationNearCall(CodePtr(returnAddress)), label);
0302 -    }
0303 -    
0304 -    void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
0305 -    {
0306 -        relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
0307 -    }
0308 -    
0309 -    void replaceWithLoad(CodeLocationConvertibleLoad label)
0310 -    {
0311 -        MacroAssembler::replaceWithLoad(label);
0312 -    }
0313 -    
0314 -    void replaceWithAddressComputation(CodeLocationConvertibleLoad label)
0315 -    {
0316 -        MacroAssembler::replaceWithAddressComputation(label);
0317 -    }
0318 -    
0319 -    void setLoadInstructionIsActive(CodeLocationConvertibleLoad label, bool isActive)
0320 -    {
0321 -        if (isActive)
0322 -            replaceWithLoad(label);
0323 -        else
0324 -            replaceWithAddressComputation(label);
0325 -    }
0326 -
0327 -    static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label)
0328 -    {
0329 -        return MacroAssembler::startOfBranchPtrWithPatchOnRegister(label);
0330 -    }
0331 -    
0332 -    static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr label)
0333 -    {
0334 -        return MacroAssembler::startOfPatchableBranchPtrWithPatchOnAddress(label);
0335 -    }
0336 -    
0337 -    void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
0338 -    {
0339 -        MacroAssembler::replaceWithJump(instructionStart, destination);
0340 -    }
0341 -    
0342 -    // This is a *bit* of a silly API, since we currently always also repatch the
0343 -    // immediate after calling this. But I'm fine with that, since this just feels
0344 -    // less yucky.
0345 -    void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, MacroAssembler::RegisterID reg, void* value)
0346 -    {
0347 -        MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(instructionStart, reg, value);
0348 -    }
0349 -
0350 -    void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, MacroAssembler::Address address, void* value)
0351 -    {
0352 -        MacroAssembler::revertJumpReplacementToPatchableBranchPtrWithPatch(instructionStart, address, value);
0353 -    }
0354 -
0355 -private:
0356 -    void* m_start;
0357 -    size_t m_size;
0358 -};
0359 -
0360 -} // namespace JSC
0361 -
0362 -#endif // ENABLE(ASSEMBLER)
0363 -
0364 -#endif // RepatchBuffer_h
0365 diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
0366 index f9847040..515285a7 100644
0367 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
0368 +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
0369 @@ -109,7 +109,7 @@ struct ExecutableAllocator {
0370          return adoptRef(new ExecutableMemoryHandle(realAllocator, size));
0371      }
0372  
0373 -    static void makeWritable(void* addr, size_t size)
0374 +    static bool makeWritable(void* addr, size_t size)
0375      {
0376          quintptr pageSize = WTF::pageSize();
0377          quintptr iaddr = reinterpret_cast<quintptr>(addr);
0378 @@ -125,7 +125,7 @@ struct ExecutableAllocator {
0379  #    else
0380          bool hr = VirtualProtectFromApp(addr, size, PAGE_READWRITE, &oldProtect);
0381          if (!hr) {
0382 -            Q_UNREACHABLE();
0383 +            return false;
0384          }
0385  #    endif
0386  #  elif OS(INTEGRITY)
0387 @@ -134,7 +134,7 @@ struct ExecutableAllocator {
0388          int mode = PROT_READ | PROT_WRITE;
0389          if (mprotect(addr, size, mode) != 0) {
0390              perror("mprotect failed in ExecutableAllocator::makeWritable");
0391 -            Q_UNREACHABLE();
0392 +            return false;
0393          }
0394  #  endif
0395  #else
0396 @@ -142,9 +142,10 @@ struct ExecutableAllocator {
0397          (void)addr; // suppress unused parameter warning
0398          (void)size; // suppress unused parameter warning
0399  #endif
0400 +        return true;
0401      }
0402  
0403 -    static void makeExecutable(void* addr, size_t size)
0404 +    static bool makeExecutable(void* addr, size_t size)
0405      {
0406          quintptr pageSize = WTF::pageSize();
0407          quintptr iaddr = reinterpret_cast<quintptr>(addr);
0408 @@ -161,7 +162,7 @@ struct ExecutableAllocator {
0409  #    else
0410          bool hr = VirtualProtectFromApp(addr, size, PAGE_EXECUTE_READ, &oldProtect);
0411          if (!hr) {
0412 -            Q_UNREACHABLE();
0413 +            return false;
0414          }
0415  #    endif
0416  #  elif OS(INTEGRITY)
0417 @@ -170,7 +171,7 @@ struct ExecutableAllocator {
0418          int mode = PROT_READ | PROT_EXEC;
0419          if (mprotect(addr, size, mode) != 0) {
0420              perror("mprotect failed in ExecutableAllocator::makeExecutable");
0421 -            Q_UNREACHABLE();
0422 +            return false;
0423          }
0424  #  endif
0425  #else
0426 @@ -180,6 +181,7 @@ struct ExecutableAllocator {
0427          (void)addr; // suppress unused parameter warning
0428          (void)size; // suppress unused parameter warning
0429  #endif
0430 +        return true;
0431      }
0432  
0433      QV4::ExecutableAllocator *realAllocator;
0434 diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp
0435 index 98e4ade5..92706ffb 100644
0436 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp
0437 +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp
0438 @@ -3553,7 +3553,8 @@ public:
0439          }
0440          QV4::generateFunctionTable(nullptr, &codeRef);
0441  
0442 -        linkBuffer.makeExecutable();
0443 +        if (Q_UNLIKELY(!linkBuffer.makeExecutable()))
0444 +            m_failureReason = JITFailureReason::ExecutableMemoryAllocationFailure;
0445  
0446          if (m_failureReason)
0447              codeBlock.setFallBackWithFailureReason(*m_failureReason);
0448 diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
0449 index 6dc40ad8..45ff79c9 100644
0450 --- a/src/qml/jit/qv4assemblercommon.cpp
0451 +++ b/src/qml/jit/qv4assemblercommon.cpp
0452 @@ -153,7 +153,8 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind)
0453  
0454      generateFunctionTable(function, &codeRef);
0455  
0456 -    linkBuffer.makeExecutable();
0457 +    if (Q_UNLIKELY(!linkBuffer.makeExecutable()))
0458 +        function->jittedCode = nullptr; // The function is not executable, but the coderef exists.
0459  }
0460  
0461  void PlatformAssemblerCommon::prepareCallWithArgCount(int argc)
0462 diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
0463 index 47ad22f4..9d8a1c5a 100644
0464 --- a/src/qml/jsruntime/qv4vme_moth.cpp
0465 +++ b/src/qml/jsruntime/qv4vme_moth.cpp
0466 @@ -429,7 +429,10 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine)
0467  
0468  #ifdef V4_ENABLE_JIT
0469      if (debugger == nullptr) {
0470 -        if (function->jittedCode == nullptr) {
0471 +        // Check for codeRef here. In rare cases the JIT compilation may fail, which leaves us
0472 +        // with a (useless) codeRef, but no jittedCode. In that case, don't try to JIT again every
0473 +        // time we execute the function, but just interpret instead.
0474 +        if (function->codeRef == nullptr) {
0475              if (engine->canJIT(function))
0476                  QV4::JIT::BaselineJIT(function).generate();
0477              else
0478 -- 
0479 2.37.3
0480