aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp4
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h10
-rw-r--r--src/qml/compiler/qv4bytecodehandler.cpp482
-rw-r--r--src/qml/compiler/qv4bytecodehandler_p.h2
-rw-r--r--src/qml/compiler/qv4codegen.cpp58
-rw-r--r--src/qml/compiler/qv4compileddata_p.h15
-rw-r--r--src/qml/compiler/qv4compiler.cpp13
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h1
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h3
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp21
-rw-r--r--src/qml/jit/qv4baselineassembler_p.h14
-rw-r--r--src/qml/jit/qv4baselinejit.cpp20
-rw-r--r--src/qml/jit/qv4baselinejit_p.h5
13 files changed, 104 insertions, 544 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index d0bca69b56..ea252a6013 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -180,6 +180,10 @@ void BytecodeGenerator::finalize(Compiler::Context *context)
context->code = code;
context->lineNumberMapping = lineNumbers;
+
+ for (const auto &li : _labelInfos) {
+ context->labelInfo.push_back(instructions.at(labels.at(li.labelIndex)).position);
+ }
}
int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, int offsetOfOffset) {
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 5a27d3948c..1d0a57c536 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -306,6 +306,11 @@ QT_WARNING_POP
return nTraceInfos;
}
+ void addLoopStart(const Label &start)
+ {
+ _labelInfos.push_back({ start.index });
+ }
+
private:
friend struct Jump;
friend struct Label;
@@ -342,6 +347,11 @@ private:
Moth::Instr lastInstr;
TraceInfoCount nTraceInfos = TraceInfoCount(0);
+
+ struct LabelInfo {
+ int labelIndex;
+ };
+ std::vector<LabelInfo> _labelInfos;
};
}
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp
index 1508790926..92b112c2fa 100644
--- a/src/qml/compiler/qv4bytecodehandler.cpp
+++ b/src/qml/compiler/qv4bytecodehandler.cpp
@@ -79,485 +79,3 @@ void ByteCodeHandler::decode(const char *code, uint len)
#undef DECODE_AND_DISPATCH
#undef DISPATCH_INSTRUCTION
-
-#define MOTH_UNUSED_ARGS0()
-#define MOTH_UNUSED_ARGS1(arg) \
- Q_UNUSED(arg);
-#define MOTH_UNUSED_ARGS2(arg1, arg2) \
- Q_UNUSED(arg1); \
- Q_UNUSED(arg2);
-#define MOTH_UNUSED_ARGS3(arg1, arg2, arg3) \
- Q_UNUSED(arg1); \
- Q_UNUSED(arg2); \
- Q_UNUSED(arg3);
-#define MOTH_UNUSED_ARGS4(arg1, arg2, arg3, arg4) \
- Q_UNUSED(arg1); \
- Q_UNUSED(arg2); \
- Q_UNUSED(arg3); \
- Q_UNUSED(arg4);
-#define MOTH_UNUSED_ARGS5(arg1, arg2, arg3, arg4, arg5) \
- Q_UNUSED(arg1); \
- Q_UNUSED(arg2); \
- Q_UNUSED(arg3); \
- Q_UNUSED(arg4); \
- Q_UNUSED(arg5);
-
-#define MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, ...) \
- MOTH_EXPAND_FOR_MSVC(MOTH_UNUSED_ARGS##nargs(__VA_ARGS__))
-
-#define MOTH_MARK_ARGS_UNUSED_INSTRUCTION(name, nargs, ...) \
- MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, __VA_ARGS__)
-
-#define COLLECTOR_BEGIN_INSTR(instr) \
- { \
- INSTR_##instr(MOTH_DECODE_WITH_BASE) \
- INSTR_##instr(MOTH_MARK_ARGS_UNUSED) \
- Q_UNUSED(base_ptr);
-
-#define COLLECTOR_END_INSTR(instr) \
- continue; \
- }
-
-std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint len)
-{
- MOTH_JUMP_TABLE;
-
- std::vector<int> labels;
-
- const auto addLabel = [&labels,len](int offset) {
- Q_ASSERT(offset >= 0 && offset < static_cast<int>(len));
- labels.push_back(offset);
- };
-
- const char *start = code;
- const char *end = code + len;
- while (code < end) {
- MOTH_DISPATCH()
- Q_UNREACHABLE();
-
- COLLECTOR_BEGIN_INSTR(LoadReg)
- COLLECTOR_END_INSTR(LoadReg)
-
- COLLECTOR_BEGIN_INSTR(StoreReg)
- COLLECTOR_END_INSTR(StoreReg)
-
- COLLECTOR_BEGIN_INSTR(MoveReg)
- COLLECTOR_END_INSTR(MoveReg)
-
- COLLECTOR_BEGIN_INSTR(LoadConst)
- COLLECTOR_END_INSTR(LoadConst)
-
- COLLECTOR_BEGIN_INSTR(LoadNull)
- COLLECTOR_END_INSTR(LoadNull)
-
- COLLECTOR_BEGIN_INSTR(LoadZero)
- COLLECTOR_END_INSTR(LoadZero)
-
- COLLECTOR_BEGIN_INSTR(LoadTrue)
- COLLECTOR_END_INSTR(LoadTrue)
-
- COLLECTOR_BEGIN_INSTR(LoadFalse)
- COLLECTOR_END_INSTR(LoadFalse)
-
- COLLECTOR_BEGIN_INSTR(LoadUndefined)
- COLLECTOR_END_INSTR(LoadUndefined)
-
- COLLECTOR_BEGIN_INSTR(LoadInt)
- COLLECTOR_END_INSTR(LoadInt)
-
- COLLECTOR_BEGIN_INSTR(MoveConst)
- COLLECTOR_END_INSTR(MoveConst)
-
- COLLECTOR_BEGIN_INSTR(LoadImport)
- COLLECTOR_END_INSTR(LoadImport)
-
- COLLECTOR_BEGIN_INSTR(LoadLocal)
- COLLECTOR_END_INSTR(LoadLocal)
-
- COLLECTOR_BEGIN_INSTR(StoreLocal)
- COLLECTOR_END_INSTR(StoreLocal)
-
- COLLECTOR_BEGIN_INSTR(LoadScopedLocal)
- COLLECTOR_END_INSTR(LoadScopedLocal)
-
- COLLECTOR_BEGIN_INSTR(StoreScopedLocal)
- COLLECTOR_END_INSTR(StoreScopedLocal)
-
- COLLECTOR_BEGIN_INSTR(LoadRuntimeString)
- COLLECTOR_END_INSTR(LoadRuntimeString)
-
- COLLECTOR_BEGIN_INSTR(MoveRegExp)
- COLLECTOR_END_INSTR(MoveRegExp)
-
- COLLECTOR_BEGIN_INSTR(LoadClosure)
- COLLECTOR_END_INSTR(LoadClosure)
-
- COLLECTOR_BEGIN_INSTR(LoadName)
- COLLECTOR_END_INSTR(LoadName)
-
- COLLECTOR_BEGIN_INSTR(LoadGlobalLookup)
- COLLECTOR_END_INSTR(LoadGlobalLookup)
-
- COLLECTOR_BEGIN_INSTR(StoreNameSloppy)
- COLLECTOR_END_INSTR(StoreNameSloppy)
-
- COLLECTOR_BEGIN_INSTR(StoreNameStrict)
- COLLECTOR_END_INSTR(StoreNameStrict)
-
- COLLECTOR_BEGIN_INSTR(LoadElement)
- COLLECTOR_END_INSTR(LoadElement)
-
- COLLECTOR_BEGIN_INSTR(StoreElement)
- COLLECTOR_END_INSTR(StoreElement)
-
- COLLECTOR_BEGIN_INSTR(LoadProperty)
- COLLECTOR_END_INSTR(LoadProperty)
-
- COLLECTOR_BEGIN_INSTR(GetLookup)
- COLLECTOR_END_INSTR(GetLookup)
-
- COLLECTOR_BEGIN_INSTR(StoreProperty)
- COLLECTOR_END_INSTR(StoreProperty)
-
- COLLECTOR_BEGIN_INSTR(SetLookup)
- COLLECTOR_END_INSTR(SetLookup)
-
- COLLECTOR_BEGIN_INSTR(LoadSuperProperty)
- COLLECTOR_END_INSTR(LoadSuperProperty)
-
- COLLECTOR_BEGIN_INSTR(StoreSuperProperty)
- COLLECTOR_END_INSTR(StoreSuperProperty)
-
- COLLECTOR_BEGIN_INSTR(StoreScopeObjectProperty)
- COLLECTOR_END_INSTR(StoreScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadScopeObjectProperty)
- COLLECTOR_END_INSTR(LoadScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(StoreContextObjectProperty)
- COLLECTOR_END_INSTR(StoreContextObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadContextObjectProperty)
- COLLECTOR_END_INSTR(LoadContextObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(LoadIdObject)
- COLLECTOR_END_INSTR(LoadIdObject)
-
- COLLECTOR_BEGIN_INSTR(Yield)
- COLLECTOR_END_INSTR(Yield)
-
- COLLECTOR_BEGIN_INSTR(YieldStar)
- COLLECTOR_END_INSTR(YieldStar)
-
- COLLECTOR_BEGIN_INSTR(Resume)
- COLLECTOR_END_INSTR(Resume)
-
- COLLECTOR_BEGIN_INSTR(CallValue)
- COLLECTOR_END_INSTR(CallValue)
-
- COLLECTOR_BEGIN_INSTR(CallWithReceiver)
- COLLECTOR_END_INSTR(CallWithReceiver)
-
- COLLECTOR_BEGIN_INSTR(CallProperty)
- COLLECTOR_END_INSTR(CallProperty)
-
- COLLECTOR_BEGIN_INSTR(CallPropertyLookup)
- COLLECTOR_END_INSTR(CallPropertyLookup)
-
- COLLECTOR_BEGIN_INSTR(CallElement)
- COLLECTOR_END_INSTR(CallElement)
-
- COLLECTOR_BEGIN_INSTR(CallName)
- COLLECTOR_END_INSTR(CallName)
-
- COLLECTOR_BEGIN_INSTR(CallPossiblyDirectEval)
- COLLECTOR_END_INSTR(CallPossiblyDirectEval)
-
- COLLECTOR_BEGIN_INSTR(CallGlobalLookup)
- COLLECTOR_END_INSTR(CallGlobalLookup)
-
- COLLECTOR_BEGIN_INSTR(CallScopeObjectProperty)
- COLLECTOR_END_INSTR(CallScopeObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(CallContextObjectProperty)
- COLLECTOR_END_INSTR(CallContextObjectProperty)
-
- COLLECTOR_BEGIN_INSTR(CallWithSpread)
- COLLECTOR_END_INSTR(CallWithSpread)
-
- COLLECTOR_BEGIN_INSTR(Construct)
- COLLECTOR_END_INSTR(Construct)
-
- COLLECTOR_BEGIN_INSTR(ConstructWithSpread)
- COLLECTOR_END_INSTR(ConstructWithSpread)
-
- COLLECTOR_BEGIN_INSTR(SetUnwindHandler)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(SetUnwindHandler)
-
- COLLECTOR_BEGIN_INSTR(UnwindDispatch)
- COLLECTOR_END_INSTR(UnwindDispatch)
-
- COLLECTOR_BEGIN_INSTR(UnwindToLabel)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(UnwindToLabel)
-
- COLLECTOR_BEGIN_INSTR(DeadTemporalZoneCheck)
- COLLECTOR_END_INSTR(DeadTemporalZoneCheck)
-
- COLLECTOR_BEGIN_INSTR(ThrowException)
- COLLECTOR_END_INSTR(ThrowException)
-
- COLLECTOR_BEGIN_INSTR(GetException)
- COLLECTOR_END_INSTR(HasException)
-
- COLLECTOR_BEGIN_INSTR(SetException)
- COLLECTOR_END_INSTR(SetExceptionFlag)
-
- COLLECTOR_BEGIN_INSTR(CreateCallContext)
- COLLECTOR_END_INSTR(CreateCallContext)
-
- COLLECTOR_BEGIN_INSTR(PushCatchContext)
- COLLECTOR_END_INSTR(PushCatchContext)
-
- COLLECTOR_BEGIN_INSTR(PushWithContext)
- COLLECTOR_END_INSTR(PushWithContext)
-
- COLLECTOR_BEGIN_INSTR(PushBlockContext)
- COLLECTOR_END_INSTR(PushBlockContext)
-
- COLLECTOR_BEGIN_INSTR(CloneBlockContext)
- COLLECTOR_END_INSTR(CloneBlockContext)
-
- COLLECTOR_BEGIN_INSTR(PushScriptContext)
- COLLECTOR_END_INSTR(PushScriptContext)
-
- COLLECTOR_BEGIN_INSTR(PopScriptContext)
- COLLECTOR_END_INSTR(PopScriptContext)
-
- COLLECTOR_BEGIN_INSTR(PopContext)
- COLLECTOR_END_INSTR(PopContext)
-
- COLLECTOR_BEGIN_INSTR(GetIterator)
- COLLECTOR_END_INSTR(GetIterator)
-
- COLLECTOR_BEGIN_INSTR(IteratorNext)
- COLLECTOR_END_INSTR(IteratorNext)
-
- COLLECTOR_BEGIN_INSTR(IteratorNextForYieldStar)
- COLLECTOR_END_INSTR(IteratorNextForYieldStar)
-
- COLLECTOR_BEGIN_INSTR(IteratorClose)
- COLLECTOR_END_INSTR(IteratorClose)
-
- COLLECTOR_BEGIN_INSTR(DestructureRestElement)
- COLLECTOR_END_INSTR(DestructureRestElement)
-
- COLLECTOR_BEGIN_INSTR(DeleteProperty)
- COLLECTOR_END_INSTR(DeleteProperty)
-
- COLLECTOR_BEGIN_INSTR(DeleteName)
- COLLECTOR_END_INSTR(DeleteName)
-
- COLLECTOR_BEGIN_INSTR(TypeofName)
- COLLECTOR_END_INSTR(TypeofName)
-
- COLLECTOR_BEGIN_INSTR(TypeofValue)
- COLLECTOR_END_INSTR(TypeofValue)
-
- COLLECTOR_BEGIN_INSTR(DeclareVar)
- COLLECTOR_END_INSTR(DeclareVar)
-
- COLLECTOR_BEGIN_INSTR(DefineArray)
- COLLECTOR_END_INSTR(DefineArray)
-
- COLLECTOR_BEGIN_INSTR(DefineObjectLiteral)
- COLLECTOR_END_INSTR(DefineObjectLiteral)
-
- COLLECTOR_BEGIN_INSTR(CreateClass)
- COLLECTOR_END_INSTR(CreateClass)
-
- COLLECTOR_BEGIN_INSTR(CreateMappedArgumentsObject)
- COLLECTOR_END_INSTR(CreateMappedArgumentsObject)
-
- COLLECTOR_BEGIN_INSTR(CreateUnmappedArgumentsObject)
- COLLECTOR_END_INSTR(CreateUnmappedArgumentsObject)
-
- COLLECTOR_BEGIN_INSTR(CreateRestParameter)
- COLLECTOR_END_INSTR(CreateRestParameter)
-
- COLLECTOR_BEGIN_INSTR(ConvertThisToObject)
- COLLECTOR_END_INSTR(ConvertThisToObject)
-
- COLLECTOR_BEGIN_INSTR(LoadSuperConstructor)
- COLLECTOR_END_INSTR(LoadSuperConstructor)
-
- COLLECTOR_BEGIN_INSTR(ToObject)
- COLLECTOR_END_INSTR(ToObject)
-
- COLLECTOR_BEGIN_INSTR(Jump)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(Jump)
-
- COLLECTOR_BEGIN_INSTR(JumpTrue)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(JumpTrue)
-
- COLLECTOR_BEGIN_INSTR(JumpFalse)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(JumpFalse)
-
- COLLECTOR_BEGIN_INSTR(JumpNoException)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(JumpNoException)
-
- COLLECTOR_BEGIN_INSTR(JumpNotUndefined)
- addLabel(code - start + offset);
- COLLECTOR_END_INSTR(JumpNotUndefined)
-
- COLLECTOR_BEGIN_INSTR(CmpEqNull)
- COLLECTOR_END_INSTR(CmpEqNull)
-
- COLLECTOR_BEGIN_INSTR(CmpNeNull)
- COLLECTOR_END_INSTR(CmpNeNull)
-
- COLLECTOR_BEGIN_INSTR(CmpEqInt)
- COLLECTOR_END_INSTR(CmpEq)
-
- COLLECTOR_BEGIN_INSTR(CmpNeInt)
- COLLECTOR_END_INSTR(CmpNeInt)
-
- COLLECTOR_BEGIN_INSTR(CmpEq)
- COLLECTOR_END_INSTR(CmpEq)
-
- COLLECTOR_BEGIN_INSTR(CmpNe)
- COLLECTOR_END_INSTR(CmpNe)
-
- COLLECTOR_BEGIN_INSTR(CmpGt)
- COLLECTOR_END_INSTR(CmpGt)
-
- COLLECTOR_BEGIN_INSTR(CmpGe)
- COLLECTOR_END_INSTR(CmpGe)
-
- COLLECTOR_BEGIN_INSTR(CmpLt)
- COLLECTOR_END_INSTR(CmpLt)
-
- COLLECTOR_BEGIN_INSTR(CmpLe)
- COLLECTOR_END_INSTR(CmpLe)
-
- COLLECTOR_BEGIN_INSTR(CmpStrictEqual)
- COLLECTOR_END_INSTR(CmpStrictEqual)
-
- COLLECTOR_BEGIN_INSTR(CmpStrictNotEqual)
- COLLECTOR_END_INSTR(CmpStrictNotEqual)
-
- COLLECTOR_BEGIN_INSTR(CmpIn)
- COLLECTOR_END_INSTR(CmpIn)
-
- COLLECTOR_BEGIN_INSTR(CmpInstanceOf)
- COLLECTOR_END_INSTR(CmpInstanceOf)
-
- COLLECTOR_BEGIN_INSTR(UNot)
- COLLECTOR_END_INSTR(UNot)
-
- COLLECTOR_BEGIN_INSTR(UPlus)
- COLLECTOR_END_INSTR(UPlus)
-
- COLLECTOR_BEGIN_INSTR(UMinus)
- COLLECTOR_END_INSTR(UMinus)
-
- COLLECTOR_BEGIN_INSTR(UCompl)
- COLLECTOR_END_INSTR(UCompl)
-
- COLLECTOR_BEGIN_INSTR(Increment)
- COLLECTOR_END_INSTR(PreIncrement)
-
- COLLECTOR_BEGIN_INSTR(Decrement)
- COLLECTOR_END_INSTR(PreDecrement)
-
- COLLECTOR_BEGIN_INSTR(Add)
- COLLECTOR_END_INSTR(Add)
-
- COLLECTOR_BEGIN_INSTR(BitAnd)
- COLLECTOR_END_INSTR(BitAnd)
-
- COLLECTOR_BEGIN_INSTR(BitOr)
- COLLECTOR_END_INSTR(BitOr)
-
- COLLECTOR_BEGIN_INSTR(BitXor)
- COLLECTOR_END_INSTR(BitXor)
-
- COLLECTOR_BEGIN_INSTR(UShr)
- COLLECTOR_END_INSTR(UShr)
-
- COLLECTOR_BEGIN_INSTR(Shr)
- COLLECTOR_END_INSTR(Shr)
-
- COLLECTOR_BEGIN_INSTR(Shl)
- COLLECTOR_END_INSTR(Shl)
-
- COLLECTOR_BEGIN_INSTR(BitAndConst)
- COLLECTOR_END_INSTR(BitAndConst)
-
- COLLECTOR_BEGIN_INSTR(BitOrConst)
- COLLECTOR_END_INSTR(BitOr)
-
- COLLECTOR_BEGIN_INSTR(BitXorConst)
- COLLECTOR_END_INSTR(BitXor)
-
- COLLECTOR_BEGIN_INSTR(UShrConst)
- COLLECTOR_END_INSTR(UShrConst)
-
- COLLECTOR_BEGIN_INSTR(ShrConst)
- COLLECTOR_END_INSTR(ShrConst)
-
- COLLECTOR_BEGIN_INSTR(ShlConst)
- COLLECTOR_END_INSTR(ShlConst)
-
- COLLECTOR_BEGIN_INSTR(Exp)
- COLLECTOR_END_INSTR(Exp)
-
- COLLECTOR_BEGIN_INSTR(Mul)
- COLLECTOR_END_INSTR(Mul)
-
- COLLECTOR_BEGIN_INSTR(Div)
- COLLECTOR_END_INSTR(Div)
-
- COLLECTOR_BEGIN_INSTR(Mod)
- COLLECTOR_END_INSTR(Mod)
-
- COLLECTOR_BEGIN_INSTR(Sub)
- COLLECTOR_END_INSTR(Sub)
-
- COLLECTOR_BEGIN_INSTR(Ret)
- COLLECTOR_END_INSTR(Ret)
-
-#ifndef QT_NO_QML_DEBUGGER
- COLLECTOR_BEGIN_INSTR(Debug)
- COLLECTOR_END_INSTR(Debug)
-#endif // QT_NO_QML_DEBUGGER
-
- COLLECTOR_BEGIN_INSTR(InitializeBlockDeadTemporalZone)
- COLLECTOR_END_INSTR(InitializeBlockDeadTemporalZone)
-
- COLLECTOR_BEGIN_INSTR(ThrowOnNullOrUndefined)
- COLLECTOR_END_INSTR(ThrowOnNullOrUndefined)
-
- COLLECTOR_BEGIN_INSTR(GetTemplateObject)
- COLLECTOR_END_INSTR(GetTemplateObject)
-
- COLLECTOR_BEGIN_INSTR(LoadQmlContext)
- COLLECTOR_END_INSTR(LoadQmlContext)
-
- COLLECTOR_BEGIN_INSTR(LoadQmlImportedScripts)
- COLLECTOR_END_INSTR(LoadQmlImportedScripts)
-
- COLLECTOR_BEGIN_INSTR(TailCall)
- COLLECTOR_END_INSTR(TailCall)
- }
-
- return labels;
-}
-
-#undef COLLECTOR_BEGIN_INSTR
-#undef COLLECTOR_END_INSTR
diff --git a/src/qml/compiler/qv4bytecodehandler_p.h b/src/qml/compiler/qv4bytecodehandler_p.h
index b37c8810bd..10626ddb74 100644
--- a/src/qml/compiler/qv4bytecodehandler_p.h
+++ b/src/qml/compiler/qv4bytecodehandler_p.h
@@ -100,8 +100,6 @@ public:
int currentInstructionOffset() const { return _currentOffset; }
int nextInstructionOffset() const { return _nextOffset; }
- static std::vector<int> collectLabelsInBytecode(const char *code, uint len);
-
protected:
FOR_EACH_MOTH_INSTR(BYTECODE_HANDLER_DEFINE_VIRTUAL_BYTECODE_HANDLER)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 6ad26c41dd..7aa848f6e9 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -3260,25 +3260,28 @@ bool Codegen::visit(DoWhileStatement *ast)
RegisterScope scope(this);
- BytecodeGenerator::Label body = bytecodeGenerator->label();
+ BytecodeGenerator::Label body = bytecodeGenerator->newLabel();
BytecodeGenerator::Label cond = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
ControlFlowLoop flow(this, &end, &cond);
-
- statement(ast->statement);
- setJumpOutLocation(bytecodeGenerator, ast->statement, ast->semicolonToken);
+ bytecodeGenerator->jump().link(body);
cond.link();
+ bytecodeGenerator->addLoopStart(cond);
- TailCallBlocker blockTailCalls(this);
- if (!AST::cast<FalseLiteral *>(ast->expression)) {
- if (AST::cast<TrueLiteral *>(ast->expression))
- bytecodeGenerator->jump().link(body);
- else
- condition(ast->expression, &body, &end, false);
+ if (!AST::cast<TrueLiteral *>(ast->expression)) {
+ TailCallBlocker blockTailCalls(this);
+ condition(ast->expression, &body, &end, true);
}
+ body.link();
+ statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->semicolonToken);
+
+ if (!AST::cast<FalseLiteral *>(ast->expression))
+ bytecodeGenerator->jump().link(cond);
+
end.link();
return false;
@@ -3350,9 +3353,14 @@ bool Codegen::visit(ForEachStatement *ast)
}
};
ControlFlowLoop flow(this, &end, &in, cleanup);
- bytecodeGenerator->jump().link(in);
-
- BytecodeGenerator::Label body = bytecodeGenerator->label();
+ bytecodeGenerator->addLoopStart(in);
+ in.link();
+ iterator.loadInAccumulator();
+ Instruction::IteratorNext next;
+ next.value = lhsValue.stackSlot();
+ next.done = iteratorDone.stackSlot();
+ bytecodeGenerator->addInstruction(next);
+ bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpTrue()).link(done);
// each iteration gets it's own context, as per spec
{
@@ -3383,22 +3391,17 @@ bool Codegen::visit(ForEachStatement *ast)
Q_UNREACHABLE();
}
+ blockTailCalls.unblock();
statement(ast->statement);
setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
-
}
- error:
- in.link();
- iterator.loadInAccumulator();
- Instruction::IteratorNext next;
- next.value = lhsValue.stackSlot();
- next.done = iteratorDone.stackSlot();
- bytecodeGenerator->addInstruction(next);
- bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpFalse()).link(body);
- bytecodeGenerator->jump().link(done);
+ bytecodeGenerator->jump().link(in);
+ error:
end.link();
+
+ // ~ControlFlowLoop will be called here, which will generate unwind code when needed
}
done.link();
@@ -3427,7 +3430,7 @@ bool Codegen::visit(ForStatement *ast)
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
ControlFlowLoop flow(this, &end, &step);
-
+ bytecodeGenerator->addLoopStart(cond);
condition(ast->condition, &body, &end, true);
body.link();
@@ -3720,16 +3723,17 @@ bool Codegen::visit(WhileStatement *ast)
return false;
RegisterScope scope(this);
- TailCallBlocker blockTailCalls(this);
BytecodeGenerator::Label start = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
BytecodeGenerator::Label cond = bytecodeGenerator->label();
ControlFlowLoop flow(this, &end, &cond);
+ bytecodeGenerator->addLoopStart(cond);
- if (!AST::cast<TrueLiteral *>(ast->expression))
+ if (!AST::cast<TrueLiteral *>(ast->expression)) {
+ TailCallBlocker blockTailCalls(this);
condition(ast->expression, &start, &end, true);
- blockTailCalls.unblock();
+ }
start.link();
statement(ast->statement);
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 52c8e9f651..7197b4cde8 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -73,7 +73,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x1a
+#define QV4_DATA_STRUCTURE_VERSION 0x1b
class QIODevice;
class QQmlPropertyCache;
@@ -302,9 +302,14 @@ struct Function
typedef quint16_le TraceInfoCount;
TraceInfoCount nTraceInfos;
static constexpr TraceInfoCount NoTracing() { return TraceInfoCount::max(); }
+
+ quint32_le nLabelInfos;
+ size_t labelInfosOffset() const { return dependingScopePropertiesOffset() + nDependingScopeProperties; }
+
// Keep all unaligned data at the end
quint8 flags;
quint8 padding1;
+ quint16 padding2;
// quint32 formalsIndex[nFormals]
// quint32 localsIndex[nLocals]
@@ -321,12 +326,14 @@ struct Function
const quint32_le *formalsEnd() const { return formalsTable() + nFormals; }
// ---
+ const quint32_le *labelInfoTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + labelInfosOffset()); }
+
const char *code() const { return reinterpret_cast<const char *>(this) + codeOffset; }
inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; }
- static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies, int codeSize) {
- int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies +
+ static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies, int labelInfoSize, int codeSize) {
+ int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies + labelInfoSize +
2 * nPropertyDependencies)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine);
size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize);
Q_ASSERT(size < INT_MAX);
@@ -337,7 +344,7 @@ struct Function
return (a + 7) & ~size_t(7);
}
};
-static_assert(sizeof(Function) == 56, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Function) == 60, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Method {
enum Type {
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 8735cc074b..0833f552e6 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -445,6 +445,12 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
currentOffset += function->nDependingScopeProperties * sizeof(quint32) * 2;
}
+ if (!irFunction->labelInfo.empty()) {
+ function->nLabelInfos = quint32(irFunction->labelInfo.size());
+ Q_ASSERT(function->labelInfosOffset() == currentOffset);
+ currentOffset += function->nLabelInfos * sizeof(quint32);
+ }
+
function->location.line = irFunction->line;
function->location.column = irFunction->column;
@@ -483,6 +489,11 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
*writtenDeps++ = property.value(); // notify index
}
+ quint32_le *labels = (quint32_le *)(f + function->labelInfosOffset());
+ for (unsigned u : irFunction->labelInfo) {
+ *labels++ = u;
+ }
+
// write byte code
memcpy(f + function->codeOffset, irFunction->code.constData(), irFunction->code.size());
}
@@ -682,7 +693,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
const int qmlIdDepsCount = f->idObjectDependencies.count();
const int qmlPropertyDepsCount = f->scopeObjectPropertyDependencies.count() + f->contextObjectPropertyDependencies.count();
quint32 size = QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(),
- qmlIdDepsCount, qmlPropertyDepsCount, f->code.size());
+ qmlIdDepsCount, qmlPropertyDepsCount, int(f->labelInfo.size()), f->code.size());
functionSize += size - f->code.size();
nextOffset += size;
}
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 0fa1074580..5b91b93346 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -201,6 +201,7 @@ struct Context {
ControlFlow *controlFlow = nullptr;
QByteArray code;
QVector<CompiledData::CodeOffsetToLine> lineNumberMapping;
+ std::vector<unsigned> labelInfo;
int nRegisters = 0;
int registerOffset = -1;
diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h
index 8f4d3238c4..3e70457bd8 100644
--- a/src/qml/jit/qv4assemblercommon_p.h
+++ b/src/qml/jit/qv4assemblercommon_p.h
@@ -670,7 +670,8 @@ public:
void addLabelForOffset(int offset)
{
- labelForOffset.insert(offset, label());
+ if (!labelForOffset.contains(offset))
+ labelForOffset.insert(offset, label());
}
void addJumpToOffset(const Jump &jump, int offset)
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 9663754cbf..987f366256 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -1382,28 +1382,31 @@ void BaselineAssembler::cmpStrictNotEqual(int lhs)
pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}
-void BaselineAssembler::jump(int offset)
+int BaselineAssembler::jump(int offset)
{
pasm()->addJumpToOffset(pasm()->jump(), offset);
+ return offset;
}
-void BaselineAssembler::jumpTrue(int offset)
+int BaselineAssembler::jumpTrue(int offset)
{
pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
auto jump = pasm()->branch32(PlatformAssembler::NotEqual, TrustedImm32(0), resultReg);
pasm()->addJumpToOffset(jump, offset);
});
+ return offset;
}
-void BaselineAssembler::jumpFalse(int offset)
+int BaselineAssembler::jumpFalse(int offset)
{
pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
auto jump = pasm()->branch32(PlatformAssembler::Equal, TrustedImm32(0), resultReg);
pasm()->addJumpToOffset(jump, offset);
});
+ return offset;
}
-void BaselineAssembler::jumpNoException(int offset)
+int BaselineAssembler::jumpNoException(int offset)
{
auto jump = pasm()->branch32(
PlatformAssembler::Equal,
@@ -1411,11 +1414,13 @@ void BaselineAssembler::jumpNoException(int offset)
offsetof(EngineBase, hasException)),
TrustedImm32(0));
pasm()->addJumpToOffset(jump, offset);
+ return offset;
}
-void BaselineAssembler::jumpNotUndefined(int offset)
+int BaselineAssembler::jumpNotUndefined(int offset)
{
pasm()->jumpNotUndefined(offset);
+ return offset;
}
void BaselineAssembler::prepareCallWithArgCount(int argc)
@@ -1539,10 +1544,11 @@ void BaselineAssembler::setException()
noException.link(pasm());
}
-void BaselineAssembler::setUnwindHandler(int offset)
+int BaselineAssembler::setUnwindHandler(int offset)
{
auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
pasm()->addEHTarget(l, offset);
+ return offset;
}
@@ -1568,12 +1574,13 @@ void JIT::BaselineAssembler::unwindDispatch()
noUnwind.link(pasm());
}
-void JIT::BaselineAssembler::unwindToLabel(int level, int offset)
+int JIT::BaselineAssembler::unwindToLabel(int level, int offset)
{
auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLabel)));
pasm()->addEHTarget(l, offset);
pasm()->store32(TrustedImm32(level), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)));
gotoCatchException();
+ return offset;
}
void BaselineAssembler::pushCatchContext(int index, int name)
diff --git a/src/qml/jit/qv4baselineassembler_p.h b/src/qml/jit/qv4baselineassembler_p.h
index dbefa42784..c39d002bf9 100644
--- a/src/qml/jit/qv4baselineassembler_p.h
+++ b/src/qml/jit/qv4baselineassembler_p.h
@@ -135,11 +135,11 @@ public:
void cmpStrictNotEqual(int lhs);
// jumps
- void jump(int offset);
- void jumpTrue(int offset);
- void jumpFalse(int offset);
- void jumpNoException(int offset);
- void jumpNotUndefined(int offset);
+ Q_REQUIRED_RESULT int jump(int offset);
+ Q_REQUIRED_RESULT int jumpTrue(int offset);
+ Q_REQUIRED_RESULT int jumpFalse(int offset);
+ Q_REQUIRED_RESULT int jumpNoException(int offset);
+ Q_REQUIRED_RESULT int jumpNotUndefined(int offset);
// stuff for runtime calls
void prepareCallWithArgCount(int argc);
@@ -160,10 +160,10 @@ public:
void gotoCatchException();
void getException();
void setException();
- void setUnwindHandler(int offset);
+ Q_REQUIRED_RESULT int setUnwindHandler(int offset);
void clearUnwindHandler();
void unwindDispatch();
- void unwindToLabel(int level, int offset);
+ Q_REQUIRED_RESULT int unwindToLabel(int level, int offset);
void pushCatchContext(int index, int name);
void popContext();
void deadTemporalZoneCheck(int offsetForSavedIP, int variableName);
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index ed4cdabd26..df3af1fce3 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -63,7 +63,9 @@ void BaselineJIT::generate()
// qDebug()<<"jitting" << function->name()->toQString();
const char *code = function->codeData;
uint len = function->compiledFunction->codeSize;
- labels = collectLabelsInBytecode(code, len);
+
+ for (unsigned i = 0, ei = function->compiledFunction->nLabelInfos; i != ei; ++i)
+ labels.insert(int(function->compiledFunction->labelInfoTable()[i]));
as->generatePrologue();
decode(code, len);
@@ -591,7 +593,7 @@ void BaselineJIT::generate_ConstructWithSpread(int func, int argc, int argv)
void BaselineJIT::generate_SetUnwindHandler(int offset)
{
if (offset)
- as->setUnwindHandler(absoluteOffsetForJump(offset));
+ labels.insert(as->setUnwindHandler(absoluteOffsetForJump(offset)));
else
as->clearUnwindHandler();
}
@@ -603,7 +605,7 @@ void BaselineJIT::generate_UnwindDispatch()
void BaselineJIT::generate_UnwindToLabel(int level, int offset)
{
- as->unwindToLabel(level, absoluteOffsetForJump(offset));
+ labels.insert(as->unwindToLabel(level, absoluteOffsetForJump(offset)));
}
void BaselineJIT::generate_DeadTemporalZoneCheck(int name)
@@ -870,11 +872,11 @@ void BaselineJIT::generate_ToObject()
}
-void BaselineJIT::generate_Jump(int offset) { as->jump(absoluteOffsetForJump(offset)); }
-void BaselineJIT::generate_JumpTrue(int /*traceSlot*/, int offset) { as->jumpTrue(absoluteOffsetForJump(offset)); }
-void BaselineJIT::generate_JumpFalse(int /*traceSlot*/, int offset) { as->jumpFalse(absoluteOffsetForJump(offset)); }
-void BaselineJIT::generate_JumpNoException(int offset) { as->jumpNoException(absoluteOffsetForJump(offset)); }
-void BaselineJIT::generate_JumpNotUndefined(int offset) { as->jumpNotUndefined(absoluteOffsetForJump(offset)); }
+void BaselineJIT::generate_Jump(int offset) { labels.insert(as->jump(absoluteOffsetForJump(offset))); }
+void BaselineJIT::generate_JumpTrue(int /*traceSlot*/, int offset) { labels.insert(as->jumpTrue(absoluteOffsetForJump(offset))); }
+void BaselineJIT::generate_JumpFalse(int /*traceSlot*/, int offset) { labels.insert(as->jumpFalse(absoluteOffsetForJump(offset))); }
+void BaselineJIT::generate_JumpNoException(int offset) { labels.insert(as->jumpNoException(absoluteOffsetForJump(offset))); }
+void BaselineJIT::generate_JumpNotUndefined(int offset) { labels.insert(as->jumpNotUndefined(absoluteOffsetForJump(offset))); }
void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); }
void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); }
@@ -1004,7 +1006,7 @@ void BaselineJIT::generate_GetTemplateObject(int index)
void BaselineJIT::startInstruction(Instr::Type /*instr*/)
{
- if (hasLabel())
+ if (labels.contains(currentInstructionOffset()))
as->addLabel(currentInstructionOffset());
}
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index 9e7dd8f2ca..385fbf72f3 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -221,16 +221,13 @@ public:
void endInstruction(Moth::Instr::Type instr) override;
protected:
- bool hasLabel() const
- { return std::find(labels.cbegin(), labels.cend(), currentInstructionOffset()) != labels.cend(); }
-
int absoluteOffsetForJump(int relativeOffset) const
{ return nextInstructionOffset() + relativeOffset; }
private:
QV4::Function *function;
QScopedPointer<BaselineAssembler> as;
- std::vector<int> labels;
+ QSet<int> labels;
};
#endif // V4_ENABLE_JIT