diff options
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 140 |
1 files changed, 72 insertions, 68 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 3fdba08f20..e0d259bd0c 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -288,8 +288,8 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) switch (op) { case UMinus: { expr.loadInAccumulator(); - Instruction::UMinus uminus; - bytecodeGenerator->addInstruction(uminus); + Instruction::UMinus uminus = {}; + bytecodeGenerator->addTracingInstruction(uminus); return Reference::fromAccumulator(this); } case UPlus: { @@ -317,8 +317,8 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) Instruction::UPlus uplus; bytecodeGenerator->addInstruction(uplus); Reference originalValue = Reference::fromStackSlot(this).storeRetainAccumulator(); - Instruction::Increment inc; - bytecodeGenerator->addInstruction(inc); + Instruction::Increment inc = {}; + bytecodeGenerator->addTracingInstruction(inc); e.storeConsumeAccumulator(); return originalValue; } else { @@ -329,8 +329,8 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) case PreIncrement: { Reference e = expr.asLValue(); e.loadInAccumulator(); - Instruction::Increment inc; - bytecodeGenerator->addInstruction(inc); + Instruction::Increment inc = {}; + bytecodeGenerator->addTracingInstruction(inc); if (exprAccept(nx)) return e.storeConsumeAccumulator(); else @@ -343,8 +343,8 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) Instruction::UPlus uplus; bytecodeGenerator->addInstruction(uplus); Reference originalValue = Reference::fromStackSlot(this).storeRetainAccumulator(); - Instruction::Decrement dec; - bytecodeGenerator->addInstruction(dec); + Instruction::Decrement dec = {}; + bytecodeGenerator->addTracingInstruction(dec); e.storeConsumeAccumulator(); return originalValue; } else { @@ -355,8 +355,8 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) case PreDecrement: { Reference e = expr.asLValue(); e.loadInAccumulator(); - Instruction::Decrement dec; - bytecodeGenerator->addInstruction(dec); + Instruction::Decrement dec = {}; + bytecodeGenerator->addTracingInstruction(dec); if (exprAccept(nx)) return e.storeConsumeAccumulator(); else @@ -1138,8 +1138,8 @@ bool Codegen::visit(ArrayPattern *ast) slot.storeConsumeAccumulator(); index.loadInAccumulator(); - Instruction::Increment inc; - bytecodeGenerator->addInstruction(inc); + Instruction::Increment inc = {}; + bytecodeGenerator->addTracingInstruction(inc); index.storeConsumeAccumulator(); }; @@ -1195,7 +1195,7 @@ bool Codegen::visit(ArrayPattern *ast) next.value = lhsValue.stackSlot(); next.done = iteratorDone.stackSlot(); bytecodeGenerator->addInstruction(next); - bytecodeGenerator->addJumpInstruction(Instruction::JumpTrue()).link(end); + bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpTrue()).link(end); lhsValue.loadInAccumulator(); pushAccumulator(); @@ -1482,24 +1482,24 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re { switch (oper) { case QSOperator::Add: { - //### Todo: when we add type hints, we can generate an Increment when both the lhs is a number and the rhs == 1 left = left.storeOnStack(); right.loadInAccumulator(); Instruction::Add add; add.lhs = left.stackSlot(); - bytecodeGenerator->addInstruction(add); + bytecodeGenerator->addTracingInstruction(add); break; } case QSOperator::Sub: { if (right.isConstant() && right.constant == Encode(int(1))) { left.loadInAccumulator(); - bytecodeGenerator->addInstruction(Instruction::Decrement()); + Instruction::Decrement dec = {}; + bytecodeGenerator->addTracingInstruction(dec); } else { left = left.storeOnStack(); right.loadInAccumulator(); Instruction::Sub sub; sub.lhs = left.stackSlot(); - bytecodeGenerator->addInstruction(sub); + bytecodeGenerator->addTracingInstruction(sub); } break; } @@ -1516,7 +1516,7 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re right.loadInAccumulator(); Instruction::Mul mul; mul.lhs = left.stackSlot(); - bytecodeGenerator->addInstruction(mul); + bytecodeGenerator->addTracingInstruction(mul); break; } case QSOperator::Div: { @@ -1532,7 +1532,7 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re right.loadInAccumulator(); Instruction::Mod mod; mod.lhs = left.stackSlot(); - bytecodeGenerator->addInstruction(mod); + bytecodeGenerator->addTracingInstruction(mod); break; } case QSOperator::BitAnd: @@ -1901,7 +1901,7 @@ bool Codegen::visit(CallExpression *ast) call.thisObject = baseObject.stackSlot(); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else { Instruction::TailCall call; call.func = base.stackSlot(); @@ -1930,14 +1930,14 @@ void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunctio call.lookupIndex = registerGetterLookup(base.propertyNameIndex); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else { Instruction::CallProperty call; call.base = base.propertyBase.stackSlot(); call.name = base.propertyNameIndex; call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } } else if (base.type == Reference::Subscript) { Instruction::CallElement call; @@ -1945,33 +1945,33 @@ void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunctio call.index = base.elementSubscript.stackSlot(); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else if (base.type == Reference::Name) { if (base.name == QStringLiteral("eval")) { Instruction::CallPossiblyDirectEval call; call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else if (!disable_lookups && useFastLookups && base.global) { if (base.qmlGlobal) { Instruction::CallQmlContextPropertyLookup call; call.index = registerQmlContextPropertyGetterLookup(base.nameAsIndex()); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else { Instruction::CallGlobalLookup call; call.index = registerGlobalGetterLookup(base.nameAsIndex()); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } } else { Instruction::CallName call; call.name = base.nameAsIndex(); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } } else if (base.type == Reference::SuperProperty) { Reference receiver = base.baseObject(); @@ -1988,14 +1988,14 @@ void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunctio call.thisObject = receiver.stackSlot(); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } else { Q_ASSERT(base.isStackSlot()); Instruction::CallValue call; call.name = base.stackSlot(); call.argc = calldata.argc; call.argv = calldata.argv; - bytecodeGenerator->addInstruction(call); + bytecodeGenerator->addTracingInstruction(call); } setExprResult(Reference::fromAccumulator(this)); @@ -2490,9 +2490,6 @@ bool Codegen::visit(ObjectPattern *ast) TailCallBlocker blockTailCalls(this); - QVector<QPair<Reference, ObjectPropertyValue>> computedProperties; - QMap<QString, ObjectPropertyValue> valueMap; - RegisterScope scope(this); QStringList members; @@ -2734,14 +2731,14 @@ bool Codegen::visit(TemplateLiteral *ast) Instruction::Add instr; instr.lhs = temp2; - bytecodeGenerator->addInstruction(instr); + bytecodeGenerator->addTracingInstruction(instr); } else { expr.loadInAccumulator(); } Instruction::Add instr; instr.lhs = temp; - bytecodeGenerator->addInstruction(instr); + bytecodeGenerator->addTracingInstruction(instr); } auto r = Reference::fromAccumulator(this); @@ -2999,6 +2996,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, bool savedFunctionEndsWithReturn = functionEndsWithReturn; functionEndsWithReturn = endsWithReturn(_module, body); + bytecodeGenerator->setTracing(_functionContext->canUseTracingJit(), _context->arguments.size()); // reserve the js stack frame (Context & js Function & accumulator) bytecodeGenerator->newRegisterArray(sizeof(CallData)/sizeof(Value) - 1 + _context->arguments.size()); @@ -3085,6 +3083,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, Q_ASSERT(_context == _functionContext); bytecodeGenerator->finalize(_context); _context->registerCountInFunction = bytecodeGenerator->registerCount(); + _context->nTraceInfos = bytecodeGenerator->traceInfoCount(); static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE"); if (showCode) { qDebug() << "=== Bytecode for" << _context->name << "strict mode" << _context->isStrict @@ -3185,25 +3184,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; @@ -3274,9 +3276,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(end); // each iteration gets it's own context, as per spec { @@ -3307,20 +3314,16 @@ bool Codegen::visit(ForEachStatement *ast) Q_UNREACHABLE(); } + blockTailCalls.unblock(); statement(ast->statement); setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken); - } + bytecodeGenerator->jump().link(in); + error: - in.link(); - iterator.loadInAccumulator(); - Instruction::IteratorNext next; - next.value = lhsValue.stackSlot(); - next.done = iteratorDone.stackSlot(); - bytecodeGenerator->addInstruction(next); - bytecodeGenerator->addJumpInstruction(Instruction::JumpFalse()).link(body); end.link(); + // all execution paths need to end up here (normal loop exit, break, and exceptions) in // order to reset the unwind handler, and to close the iterator in calse of an for-of loop. } @@ -3349,7 +3352,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(); @@ -3639,16 +3642,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); @@ -4216,7 +4220,7 @@ void Codegen::Reference::storeAccumulator() const Instruction::StoreElement store; store.base = elementBase; store.index = elementSubscript.stackSlot(); - codegen->bytecodeGenerator->addInstruction(store); + codegen->bytecodeGenerator->addTracingInstruction(store); } return; case Invalid: case Accumulator: @@ -4306,12 +4310,12 @@ QT_WARNING_POP if (!scope) { Instruction::LoadLocal load; load.index = index; - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } else { Instruction::LoadScopedLocal load; load.index = index; load.scope = scope; - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } tdzCheck(requiresTDZCheck); return; @@ -4335,16 +4339,16 @@ QT_WARNING_POP if (qmlGlobal) { Instruction::LoadQmlContextPropertyLookup load; load.index = codegen->registerQmlContextPropertyGetterLookup(nameAsIndex()); - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } else { Instruction::LoadGlobalLookup load; load.index = codegen->registerGlobalGetterLookup(nameAsIndex()); - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } } else { Instruction::LoadName load; load.name = nameAsIndex(); - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } return; case Member: @@ -4353,11 +4357,11 @@ QT_WARNING_POP if (!disable_lookups && codegen->useFastLookups) { Instruction::GetLookup load; load.index = codegen->registerGetterLookup(propertyNameIndex); - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } else { Instruction::LoadProperty load; load.name = propertyNameIndex; - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } return; case Import: { @@ -4372,7 +4376,7 @@ QT_WARNING_POP tdzCheck(subscriptRequiresTDZCheck); Instruction::LoadElement load; load.base = elementBase; - codegen->bytecodeGenerator->addInstruction(load); + codegen->bytecodeGenerator->addTracingInstruction(load); } return; case Invalid: break; |