aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4vme_moth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4vme_moth.cpp')
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp153
1 files changed, 133 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 937a535b83..d69a0fe34e 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -346,6 +346,70 @@ static struct InstrCount {
if (engine->hasException) \
goto handleUnwind
+static inline void traceJumpTakesTruePath(bool truePathTaken, Function *f, int slot)
+{
+#if QT_CONFIG(qml_tracing)
+ quint8 *traceInfo = f->traceInfo(slot);
+ Q_ASSERT(traceInfo);
+ *traceInfo |= truePathTaken ? quint8(ObservedTraceValues::TruePathTaken)
+ : quint8(ObservedTraceValues::FalsePathTaken);
+#else
+ Q_UNUSED(truePathTaken);
+ Q_UNUSED(f);
+ Q_UNUSED(slot);
+#endif
+}
+
+static inline void traceValue(ReturnedValue acc, Function *f, int slot)
+{
+#if QT_CONFIG(qml_tracing)
+ quint8 *traceInfo = f->traceInfo(slot);
+ Q_ASSERT(traceInfo);
+ switch (Primitive::fromReturnedValue(acc).type()) {
+ case QV4::Value::Integer_Type:
+ *traceInfo |= quint8(ObservedTraceValues::Integer);
+ break;
+ case QV4::Value::Boolean_Type:
+ *traceInfo |= quint8(ObservedTraceValues::Boolean);
+ break;
+ case QV4::Value::Double_Type:
+ *traceInfo |= quint8(ObservedTraceValues::Double);
+ break;
+ default:
+ *traceInfo |= quint8(ObservedTraceValues::Other);
+ break;
+ }
+#else
+ Q_UNUSED(acc);
+ Q_UNUSED(f);
+ Q_UNUSED(slot);
+#endif
+}
+
+static inline void traceDoubleValue(Function *f, int slot)
+{
+#if QT_CONFIG(qml_tracing)
+ quint8 *traceInfo = f->traceInfo(slot);
+ Q_ASSERT(traceInfo);
+ *traceInfo |= quint8(ObservedTraceValues::Double);
+#else
+ Q_UNUSED(f);
+ Q_UNUSED(slot);
+#endif
+}
+
+static inline void traceOtherValue(Function *f, int slot)
+{
+#if QT_CONFIG(qml_tracing)
+ quint8 *traceInfo = f->traceInfo(slot);
+ Q_ASSERT(traceInfo);
+ *traceInfo |= quint8(ObservedTraceValues::Other);
+#else
+ Q_UNUSED(f);
+ Q_UNUSED(slot);
+#endif
+}
+
static inline Heap::CallContext *getScope(QV4::Value *stack, int level)
{
Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[CallData::Context]).d();
@@ -453,6 +517,11 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
QV4::ReturnedValue acc = accumulator.asReturnedValue();
Value *stack = reinterpret_cast<Value *>(frame->jsFrame);
+ if (function->tracingEnabled()) {
+ for (int i = 0; i < int(function->nFormals); ++i)
+ traceValue(frame->jsFrame->argument(i), function, i);
+ }
+
MOTH_JUMP_TABLE;
for (;;) {
@@ -511,6 +580,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
Q_ASSERT(cc->type != QV4::Heap::CallContext::Type_GlobalContext);
acc = cc->locals[index].asReturnedValue();
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(LoadLocal)
MOTH_BEGIN_INSTR(StoreLocal)
@@ -523,6 +593,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_BEGIN_INSTR(LoadScopedLocal)
auto cc = getScope(stack, scope);
acc = cc->locals[index].asReturnedValue();
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(LoadScopedLocal)
MOTH_BEGIN_INSTR(StoreScopedLocal)
@@ -547,6 +618,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
STORE_IP();
acc = Runtime::method_loadName(engine, name);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(LoadGlobalLookup)
@@ -554,6 +626,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
acc = l->globalGetter(l, engine);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(LoadGlobalLookup)
MOTH_BEGIN_INSTR(StoreNameStrict)
@@ -573,14 +646,25 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_BEGIN_INSTR(LoadElement)
STORE_IP();
STORE_ACC();
+#if QT_CONFIG(qml_tracing)
+ acc = Runtime::method_loadElement_traced(engine, STACK_VALUE(base), accumulator, function->traceInfo(traceSlot));
+ traceValue(acc, function, traceSlot);
+#else
+ Q_UNUSED(traceSlot);
acc = Runtime::method_loadElement(engine, STACK_VALUE(base), accumulator);
+#endif
CHECK_EXCEPTION;
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
STORE_IP();
STORE_ACC();
+#if QT_CONFIG(qml_tracing)
+ Runtime::method_storeElement_traced(engine, STACK_VALUE(base), STACK_VALUE(index), accumulator, function->traceInfo(traceSlot));
+#else
+ Q_UNUSED(traceSlot);
Runtime::method_storeElement(engine, STACK_VALUE(base), STACK_VALUE(index), accumulator);
+#endif
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
@@ -589,6 +673,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
STORE_ACC();
acc = Runtime::method_loadProperty(engine, accumulator, name);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(GetLookup)
@@ -597,6 +682,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
acc = l->getter(l, engine, accumulator);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(StoreProperty)
@@ -701,6 +787,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
Value undef = Value::undefinedValue();
acc = static_cast<const FunctionObject &>(func).call(&undef, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallWithReceiver)
@@ -712,12 +799,14 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
}
acc = static_cast<const FunctionObject &>(func).call(stack + thisObject, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallWithReceiver)
MOTH_BEGIN_INSTR(CallProperty)
STORE_IP();
acc = Runtime::method_callProperty(engine, stack + base, name, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
@@ -733,48 +822,56 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
acc = static_cast<FunctionObject &>(f).call(stack + base, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
STORE_IP();
acc = Runtime::method_callElement(engine, stack + base, STACK_VALUE(index), stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallName)
STORE_IP();
acc = Runtime::method_callName(engine, name, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallName)
MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
STORE_IP();
acc = Runtime::method_callPossiblyDirectEval(engine, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallPossiblyDirectEval)
MOTH_BEGIN_INSTR(CallGlobalLookup)
STORE_IP();
acc = Runtime::method_callGlobalLookup(engine, index, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(CallScopeObjectProperty)
STORE_IP();
acc = Runtime::method_callQmlScopeObjectProperty(engine, stack + base, name, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallScopeObjectProperty)
MOTH_BEGIN_INSTR(CallContextObjectProperty)
STORE_IP();
acc = Runtime::method_callQmlContextObjectProperty(engine, stack + base, name, stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallContextObjectProperty)
MOTH_BEGIN_INSTR(CallWithSpread)
STORE_IP();
acc = Runtime::method_callWithSpread(engine, STACK_VALUE(func), STACK_VALUE(thisObject), stack + argv, argc);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(CallWithSpread)
MOTH_BEGIN_INSTR(TailCall)
@@ -1012,23 +1109,25 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(JumpTrue)
- if (Q_LIKELY(ACC.integerCompatible())) {
- if (ACC.int_32())
- code += offset;
- } else {
- if (ACC.toBoolean())
- code += offset;
- }
+ bool takeJump;
+ if (Q_LIKELY(ACC.integerCompatible()))
+ takeJump = ACC.int_32();
+ else
+ takeJump = ACC.toBoolean();
+ traceJumpTakesTruePath(takeJump, function, traceSlot);
+ if (takeJump)
+ code += offset;
MOTH_END_INSTR(JumpTrue)
MOTH_BEGIN_INSTR(JumpFalse)
- if (Q_LIKELY(ACC.integerCompatible())) {
- if (!ACC.int_32())
- code += offset;
- } else {
- if (!ACC.toBoolean())
- code += offset;
- }
+ bool takeJump;
+ if (Q_LIKELY(ACC.integerCompatible()))
+ takeJump = !ACC.int_32();
+ else
+ takeJump = !ACC.toBoolean();
+ traceJumpTakesTruePath(!takeJump, function, traceSlot);
+ if (takeJump)
+ code += offset;
MOTH_END_INSTR(JumpFalse)
MOTH_BEGIN_INSTR(JumpNoException)
@@ -1197,14 +1296,17 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
int a = ACC.int_32();
if (a == 0 || a == std::numeric_limits<int>::min()) {
acc = Encode(-static_cast<double>(a));
+ traceDoubleValue(function, traceSlot);
} else {
- acc = sub_int32(0, ACC.int_32());
+ acc = sub_int32(0, ACC.int_32(), function->traceInfo(traceSlot));
}
} else if (ACC.isDouble()) {
acc ^= (1ull << 63); // simply flip sign bit
+ traceDoubleValue(function, traceSlot);
} else {
acc = Encode(-ACC.toNumberImpl());
CHECK_EXCEPTION;
+ traceOtherValue(function, traceSlot);
}
MOTH_END_INSTR(UMinus)
@@ -1215,49 +1317,57 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_BEGIN_INSTR(Increment)
if (Q_LIKELY(ACC.integerCompatible())) {
- acc = add_int32(ACC.int_32(), 1);
+ acc = add_int32(ACC.int_32(), 1, function->traceInfo(traceSlot));
} else if (ACC.isDouble()) {
acc = QV4::Encode(ACC.doubleValue() + 1.);
+ traceDoubleValue(function, traceSlot);
} else {
acc = Encode(ACC.toNumberImpl() + 1.);
CHECK_EXCEPTION;
+ traceDoubleValue(function, traceSlot);
}
MOTH_END_INSTR(Increment)
MOTH_BEGIN_INSTR(Decrement)
if (Q_LIKELY(ACC.integerCompatible())) {
- acc = sub_int32(ACC.int_32(), 1);
+ acc = sub_int32(ACC.int_32(), 1, function->traceInfo(traceSlot));
} else if (ACC.isDouble()) {
acc = QV4::Encode(ACC.doubleValue() - 1.);
+ traceDoubleValue(function, traceSlot);
} else {
acc = Encode(ACC.toNumberImpl() - 1.);
CHECK_EXCEPTION;
+ traceDoubleValue(function, traceSlot);
}
MOTH_END_INSTR(Decrement)
MOTH_BEGIN_INSTR(Add)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
- acc = add_int32(left.int_32(), ACC.int_32());
+ acc = add_int32(left.int_32(), ACC.int_32(), function->traceInfo(traceSlot));
} else if (left.isNumber() && ACC.isNumber()) {
acc = Encode(left.asDouble() + ACC.asDouble());
+ traceDoubleValue(function, traceSlot);
} else {
STORE_ACC();
acc = Runtime::method_add(engine, left, accumulator);
CHECK_EXCEPTION;
+ traceOtherValue(function, traceSlot);
}
MOTH_END_INSTR(Add)
MOTH_BEGIN_INSTR(Sub)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
- acc = sub_int32(left.int_32(), ACC.int_32());
+ acc = sub_int32(left.int_32(), ACC.int_32(), function->traceInfo(traceSlot));
} else if (left.isNumber() && ACC.isNumber()) {
acc = Encode(left.asDouble() - ACC.asDouble());
+ traceDoubleValue(function, traceSlot);
} else {
STORE_ACC();
acc = Runtime::method_sub(left, accumulator);
CHECK_EXCEPTION;
+ traceOtherValue(function, traceSlot);
}
MOTH_END_INSTR(Sub)
@@ -1274,13 +1384,15 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_BEGIN_INSTR(Mul)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
- acc = mul_int32(left.int_32(), ACC.int_32());
+ acc = mul_int32(left.int_32(), ACC.int_32(), function->traceInfo(traceSlot));
} else if (left.isNumber() && ACC.isNumber()) {
acc = Encode(left.asDouble() * ACC.asDouble());
+ traceDoubleValue(function, traceSlot);
} else {
STORE_ACC();
acc = Runtime::method_mul(left, accumulator);
CHECK_EXCEPTION;
+ traceOtherValue(function, traceSlot);
}
MOTH_END_INSTR(Mul)
@@ -1294,6 +1406,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
STORE_ACC();
acc = Runtime::method_mod(STACK_VALUE(lhs), accumulator);
CHECK_EXCEPTION;
+ traceValue(acc, function, traceSlot);
MOTH_END_INSTR(Mod)
MOTH_BEGIN_INSTR(BitAnd)