aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp140
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;