diff options
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4enginebase_p.h | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 11 |
2 files changed, 28 insertions, 3 deletions
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h index b5cfea8863..82eccd9f3c 100644 --- a/src/qml/jsruntime/qv4enginebase_p.h +++ b/src/qml/jsruntime/qv4enginebase_p.h @@ -69,9 +69,23 @@ struct Q_QML_EXPORT EngineBase { CppStackFrame *currentStackFrame = nullptr; Value *jsStackTop = nullptr; + + // The JIT expects hasException and isInterrupted to be in the same 32bit word in memory. quint8 hasException = false; - quint8 writeBarrierActive = false; + // isInterrupted is expected to be set from a different thread +#if defined(Q_ATOMIC_INT8_IS_SUPPORTED) + QAtomicInteger<quint8> isInterrupted = false; quint16 unused = 0; +#elif defined(Q_ATOMIC_INT16_IS_SUPPORTED) + quint8 unused = 0; + QAtomicInteger<quint16> isInterrupted = false; +#elif defined(V4_BOOTSTRAP) + // We don't need the isInterrupted flag when bootstrapping. + quint8 unused[3]; +#else +# error V4 needs either 8bit or 16bit atomics. +#endif + quint8 isExecutingInRegExpJIT = false; quint8 padding[3]; MemoryManager *memoryManager = nullptr; @@ -137,6 +151,10 @@ Q_STATIC_ASSERT(offsetof(EngineBase, hasException) == offsetof(EngineBase, jsSta Q_STATIC_ASSERT(offsetof(EngineBase, memoryManager) == offsetof(EngineBase, hasException) + 8); Q_STATIC_ASSERT(offsetof(EngineBase, runtime) == offsetof(EngineBase, memoryManager) + QT_POINTER_SIZE); +#ifndef V4_BOOTSTRAP +Q_STATIC_ASSERT(offsetof(EngineBase, isInterrupted) + sizeof(EngineBase::isInterrupted) <= offsetof(EngineBase, hasException) + 4); +#endif + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 4c292d429a..ec44f42933 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -347,7 +347,7 @@ static struct InstrCount { #undef CHECK_EXCEPTION #endif #define CHECK_EXCEPTION \ - if (engine->hasException) \ + if (engine->hasException || engine->isInterrupted) \ goto handleUnwind static inline Heap::CallContext *getScope(QV4::Value *stack, int level) @@ -1013,6 +1013,10 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, code += offset; MOTH_END_INSTR(JumpNotUndefined) + MOTH_BEGIN_INSTR(CheckException) + CHECK_EXCEPTION; + MOTH_END_INSTR(CheckException) + MOTH_BEGIN_INSTR(CmpEqNull) acc = Encode(ACC.isNullOrUndefined()); MOTH_END_INSTR(CmpEqNull) @@ -1363,7 +1367,10 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_END_INSTR(Debug) handleUnwind: - Q_ASSERT(engine->hasException || frame->unwindLevel); + // We do start the exception handler in case of isInterrupted. The exception handler will + // immediately abort, due to the same isInterrupted. We don't skip the exception handler + // because the current behavior is easier to implement in the JIT. + Q_ASSERT(engine->hasException || engine->isInterrupted || frame->unwindLevel); if (!frame->unwindHandler) { acc = Encode::undefined(); return acc; |