diff options
Diffstat (limited to 'src/qml/jsruntime/qv4vme_moth.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 153 |
1 files changed, 133 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index c69bb67061..d2c91da12c 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -348,6 +348,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(); @@ -459,6 +523,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 (;;) { @@ -517,6 +586,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) @@ -529,6 +599,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) @@ -553,6 +624,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) @@ -560,6 +632,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(LoadQmlContextPropertyLookup) @@ -567,6 +640,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, QV4::Lookup *l = function->compilationUnit->runtimeLookups + index; acc = l->qmlContextPropertyGetter(l, engine, nullptr); CHECK_EXCEPTION; + traceValue(acc, function, traceSlot); MOTH_END_INSTR(LoadQmlContextPropertyLookup) MOTH_BEGIN_INSTR(StoreNameStrict) @@ -586,14 +660,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) @@ -602,6 +687,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) @@ -620,6 +706,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, acc = l->getter(l, engine, accumulator); CHECK_EXCEPTION; + traceValue(acc, function, traceSlot); MOTH_END_INSTR(GetLookup) MOTH_BEGIN_INSTR(StoreProperty) @@ -693,6 +780,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) @@ -704,12 +792,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) @@ -737,42 +827,49 @@ 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(CallQmlContextPropertyLookup) STORE_IP(); acc = Runtime::method_callQmlContextPropertyLookup(engine, index, stack + argv, argc); CHECK_EXCEPTION; + traceValue(acc, function, traceSlot); MOTH_END_INSTR(CallQmlContextPropertyLookup) 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) @@ -1010,23 +1107,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) @@ -1195,14 +1294,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) @@ -1213,49 +1315,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) @@ -1272,13 +1382,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) @@ -1292,6 +1404,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) |