diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/jit/qv4assemblercommon.cpp | 19 | ||||
| -rw-r--r-- | src/qml/jit/qv4assemblercommon_p.h | 6 | ||||
| -rw-r--r-- | src/qml/jit/qv4baselineassembler.cpp | 62 | ||||
| -rw-r--r-- | src/qml/jit/qv4baselineassembler_p.h | 13 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 127 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 2 |
6 files changed, 175 insertions, 54 deletions
diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp index 800ee22cd7..e75f35a665 100644 --- a/src/qml/jit/qv4assemblercommon.cpp +++ b/src/qml/jit/qv4assemblercommon.cpp @@ -96,8 +96,9 @@ private: static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<const void*, const char*>& functions) { - for (QHash<const void*, const char*>::ConstIterator it = functions.begin(), end = functions.end(); - it != end; ++it) { + const auto symbols = Runtime::symbolTable(); + const QByteArray padding(" ; "); + for (auto it = functions.begin(), end = functions.end(); it != end; ++it) { const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16); int idx = 0; while (idx >= 0) { @@ -107,7 +108,9 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput, idx = processedOutput.indexOf('\n', idx); if (idx < 0) break; - processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value()); + const char *functionName = it.value(); + processedOutput = processedOutput.insert( + idx, padding + QByteArray(functionName ? functionName : symbols[it.key()])); } } @@ -302,27 +305,29 @@ void JIT::PlatformAssemblerCommon::passPointerAsArg(void *ptr, int arg) storePtr(TrustedImmPtr(ptr), argStackAddress(arg)); } -void PlatformAssemblerCommon::callRuntime(const char *functionName, const void *funcPtr) +void PlatformAssemblerCommon::callRuntime(const void *funcPtr, const char *functionName) { #ifndef QT_NO_DEBUG Q_ASSERT(remainingArgcForCall == 0); remainingArgcForCall = NoCall; #endif - callRuntimeUnchecked(functionName, funcPtr); + callRuntimeUnchecked(funcPtr, functionName); if (argcOnStackForCall > 0) { addPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister); argcOnStackForCall = 0; } } -void PlatformAssemblerCommon::callRuntimeUnchecked(const char *functionName, const void *funcPtr) +void PlatformAssemblerCommon::callRuntimeUnchecked(const void *funcPtr, const char *functionName) { + Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr)); functions.insert(funcPtr, functionName); callAbsolute(funcPtr); } -void PlatformAssemblerCommon::tailCallRuntime(const char *functionName, const void *funcPtr) +void PlatformAssemblerCommon::tailCallRuntime(const void *funcPtr, const char *functionName) { + Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr)); functions.insert(funcPtr, functionName); setTailCallArg(EngineRegister, 1); setTailCallArg(CppStackFrameRegister, 0); diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index b18d082be6..ead1e757de 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -706,9 +706,9 @@ public: void passCppFrameAsArg(int arg); void passInt32AsArg(int value, int arg); void passPointerAsArg(void *ptr, int arg); - void callRuntime(const char *functionName, const void *funcPtr); - void callRuntimeUnchecked(const char *functionName, const void *funcPtr); - void tailCallRuntime(const char *functionName, const void *funcPtr); + void callRuntime(const void *funcPtr, const char *functionName = nullptr); + void callRuntimeUnchecked(const void *funcPtr, const char *functionName = nullptr); + void tailCallRuntime(const void *funcPtr, const char *functionName = nullptr); void setTailCallArg(RegisterID src, int arg); Address jsAlloca(int slotCount); void storeInt32AsValue(int srcInt, Address destAddr); diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp index 59de86a85d..25652e0a63 100644 --- a/src/qml/jit/qv4baselineassembler.cpp +++ b/src/qml/jit/qv4baselineassembler.cpp @@ -61,7 +61,8 @@ namespace JIT { #define ASM_GENERATE_RUNTIME_CALL(function, destination) \ pasm()->GENERATE_RUNTIME_CALL(function, destination) -#define callHelper(x) PlatformAssemblerCommon::callRuntimeUnchecked(#x, reinterpret_cast<void *>(&x)) +#define callHelper(x) \ + PlatformAssemblerCommon::callRuntimeUnchecked(reinterpret_cast<void *>(&x), #x) const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer; @@ -83,10 +84,9 @@ public: : PlatformAssemblerCommon(constantTable) {} - void callRuntime(const char *functionName, const void *funcPtr, - CallResultDestination dest) + void callRuntime(const void *funcPtr, CallResultDestination dest) { - PlatformAssemblerCommon::callRuntime(functionName, funcPtr); + PlatformAssemblerCommon::callRuntime(funcPtr); if (dest == CallResultDestination::InAccumulator) saveReturnValueInAccumulator(); } @@ -240,7 +240,7 @@ public: auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2); move(AccumulatorRegister, registerForArg(0)); - callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper)); + callHelper(toInt32Helper); saveReturnValueInAccumulator(); isInt.link(this); @@ -383,10 +383,9 @@ public: : PlatformAssemblerCommon(constantTable) {} - void callRuntime(const char *functionName, const void *funcPtr, - CallResultDestination dest) + void callRuntime(const void *funcPtr, CallResultDestination dest) { - PlatformAssemblerCommon::callRuntime(functionName, funcPtr); + PlatformAssemblerCommon::callRuntime(funcPtr); if (dest == CallResultDestination::InAccumulator) saveReturnValueInAccumulator(); } @@ -491,7 +490,7 @@ public: move(AccumulatorRegisterValue, registerForArg(0)); move(AccumulatorRegisterTag, registerForArg(1)); } - callRuntimeUnchecked("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper)); + callHelper(toNumberHelper); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); @@ -548,7 +547,7 @@ public: move(AccumulatorRegisterValue, registerForArg(0)); move(AccumulatorRegisterTag, registerForArg(1)); } - callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper)); + callHelper(toInt32Helper); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); @@ -570,7 +569,7 @@ public: move(AccumulatorRegisterValue, registerForArg(0)); move(AccumulatorRegisterTag, registerForArg(1)); } - callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper)); + callHelper(toInt32Helper); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); @@ -1267,7 +1266,7 @@ void BaselineAssembler::cmpeqInt(int lhs) else pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1)); pasm()->pushAccumulatorAsArg(0); - pasm()->callRuntimeUnchecked("Equal", (void*)Runtime::Equal::call); + pasm()->callRuntimeUnchecked((void*)Runtime::Equal::call); pasm()->saveReturnValueInAccumulator(); if (PlatformAssembler::ArgInRegCount < 2) pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister); @@ -1291,7 +1290,7 @@ void BaselineAssembler::cmpneInt(int lhs) else pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1)); pasm()->pushAccumulatorAsArg(0); - pasm()->callRuntimeUnchecked("NotEqual", (void*)Runtime::NotEqual::call); + pasm()->callRuntimeUnchecked((void*)Runtime::NotEqual::call); pasm()->saveReturnValueInAccumulator(); if (PlatformAssembler::ArgInRegCount < 2) pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister); @@ -1305,7 +1304,7 @@ void BaselineAssembler::cmpneInt(int lhs) done.link(pasm()); } -void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs) +void BaselineAssembler::cmp(int cond, CmpFunc function, int lhs) { auto c = static_cast<PlatformAssembler::RelationalCondition>(cond); auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){ @@ -1321,7 +1320,7 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName pasm()->passAccumulatorAsArg(1); pasm()->passJSSlotAsArg(lhs, 0); - callRuntime(functionName, reinterpret_cast<void*>(function), CallResultDestination::InAccumulator); + callRuntime(reinterpret_cast<void*>(function), CallResultDestination::InAccumulator); checkException(); // done. @@ -1331,50 +1330,42 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName void BaselineAssembler::cmpeq(int lhs) { - cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call, - "CompareEqual", lhs); + cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call, lhs); } void BaselineAssembler::cmpne(int lhs) { - cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call, - "CompareNotEqual", lhs); + cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call, lhs); } void BaselineAssembler::cmpgt(int lhs) { - cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call, - "CompareGreaterThan", lhs); + cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call, lhs); } void BaselineAssembler::cmpge(int lhs) { - cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call, - "CompareGreaterEqual", lhs); + cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call, lhs); } void BaselineAssembler::cmplt(int lhs) { - cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call, - "CompareLessThan", lhs); + cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call, lhs); } void BaselineAssembler::cmple(int lhs) { - cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call, - "CompareLessEqual", lhs); + cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call, lhs); } void BaselineAssembler::cmpStrictEqual(int lhs) { - cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call, - "RuntimeHelpers::strictEqual", lhs); + cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call, lhs); } void BaselineAssembler::cmpStrictNotEqual(int lhs) { - cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call, - "RuntimeHelpers::strictNotEqual", lhs); + cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call, lhs); } int BaselineAssembler::jump(int offset) @@ -1463,9 +1454,9 @@ void BaselineAssembler::passPointerAsArg(void *ptr, int arg) pasm()->passPointerAsArg(ptr, arg); } -void BaselineAssembler::callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest) +void BaselineAssembler::callRuntime(const void *funcPtr, CallResultDestination dest) { - pasm()->callRuntime(functionName, funcPtr, dest); + pasm()->callRuntime(funcPtr, dest); } void BaselineAssembler::saveAccumulatorInFrame() @@ -1498,8 +1489,9 @@ void BaselineAssembler::jsTailCall(int func, int thisObject, int argc, int argv) pasm()->storeInt32AsValue(argv, Address(tos.base, argvOffset)); pasm()->moveReg(regAddr(thisObject), Address(tos.base, thisOffset)); pasm()->moveReg(regAddr(func), Address(tos.base, funcOffset)); - pasm()->tailCallRuntime("TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing", - reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing)); + pasm()->tailCallRuntime( + reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing), + "TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing"); } void BaselineAssembler::checkException() diff --git a/src/qml/jit/qv4baselineassembler_p.h b/src/qml/jit/qv4baselineassembler_p.h index 33fd288ac3..c2c735282b 100644 --- a/src/qml/jit/qv4baselineassembler_p.h +++ b/src/qml/jit/qv4baselineassembler_p.h @@ -62,16 +62,11 @@ QT_BEGIN_NAMESPACE namespace QV4 { namespace JIT { -#define JIT_STRINGIFYx(s) #s -#define JIT_STRINGIFY(s) JIT_STRINGIFYx(s) - #define GENERATE_RUNTIME_CALL(function, destination) \ - callRuntime(JIT_STRINGIFY(function), \ - reinterpret_cast<void *>(&Runtime::function::call), \ + callRuntime(reinterpret_cast<void *>(&Runtime::function::call), \ destination) #define GENERATE_TAIL_CALL(function) \ - tailCallRuntime(JIT_STRINGIFY(function), \ - reinterpret_cast<void *>(&function)) + tailCallRuntime(reinterpret_cast<void *>(&function)) class BaselineAssembler { public: @@ -153,7 +148,7 @@ public: void passCppFrameAsArg(int arg); void passInt32AsArg(int value, int arg); void passPointerAsArg(void *ptr, int arg); - void callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest); + void callRuntime(const void *funcPtr, CallResultDestination dest); void saveAccumulatorInFrame(); void loadAccumulatorFromFrame(); void jsTailCall(int func, int thisObject, int argc, int argv); @@ -179,7 +174,7 @@ protected: private: typedef unsigned(*CmpFunc)(const Value&,const Value&); - void cmp(int cond, CmpFunc function, const char *functionName, int lhs); + void cmp(int cond, CmpFunc function, int lhs); }; } // namespace JIT diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index aaa198c62a..21a0017728 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -2316,6 +2316,133 @@ Bool Runtime::CompareStrictNotEqual::call(const Value &left, const Value &right) return ! RuntimeHelpers::strictEqual(left, right); } +template<typename Operation> +static inline const void *symbol() +{ + return reinterpret_cast<void *>(&Operation::call); +} + +QHash<const void *, const char *> Runtime::symbolTable() +{ + static const QHash<const void *, const char *> symbols({ +#ifndef V4_BOOTSTRAP + {symbol<CallGlobalLookup>(), "CallGlobalLookup" }, + {symbol<CallQmlContextPropertyLookup>(), "CallQmlContextPropertyLookup" }, + {symbol<CallName>(), "CallName" }, + {symbol<CallProperty>(), "CallProperty" }, + {symbol<CallPropertyLookup>(), "CallPropertyLookup" }, + {symbol<CallElement>(), "CallElement" }, + {symbol<CallValue>(), "CallValue" }, + {symbol<CallWithReceiver>(), "CallWithReceiver" }, + {symbol<CallPossiblyDirectEval>(), "CallPossiblyDirectEval" }, + {symbol<CallWithSpread>(), "CallWithSpread" }, + {symbol<TailCall>(), "TailCall" }, + + {symbol<Construct>(), "Construct" }, + {symbol<ConstructWithSpread>(), "ConstructWithSpread" }, + + {symbol<StoreNameStrict>(), "StoreNameStrict" }, + {symbol<StoreNameSloppy>(), "StoreNameSloppy" }, + {symbol<StoreProperty>(), "StoreProperty" }, + {symbol<StoreElement>(), "StoreElement" }, + {symbol<LoadProperty>(), "LoadProperty" }, + {symbol<LoadName>(), "LoadName" }, + {symbol<LoadElement>(), "LoadElement" }, + {symbol<LoadSuperProperty>(), "LoadSuperProperty" }, + {symbol<StoreSuperProperty>(), "StoreSuperProperty" }, + {symbol<LoadSuperConstructor>(), "LoadSuperConstructor" }, + {symbol<LoadGlobalLookup>(), "LoadGlobalLookup" }, + {symbol<LoadQmlContextPropertyLookup>(), "LoadQmlContextPropertyLookup" }, + {symbol<GetLookup>(), "GetLookup" }, + {symbol<SetLookupStrict>(), "SetLookupStrict" }, + {symbol<SetLookupSloppy>(), "SetLookupSloppy" }, + + {symbol<TypeofValue>(), "TypeofValue" }, + {symbol<TypeofName>(), "TypeofName" }, + + {symbol<DeleteProperty_NoThrow>(), "DeleteProperty_NoThrow" }, + {symbol<DeleteProperty>(), "DeleteProperty" }, + {symbol<DeleteName_NoThrow>(), "DeleteName_NoThrow" }, + {symbol<DeleteName>(), "DeleteName" }, + + {symbol<ThrowException>(), "ThrowException" }, + {symbol<PushCallContext>(), "PushCallContext" }, + {symbol<PushWithContext>(), "PushWithContext" }, + {symbol<PushCatchContext>(), "PushCatchContext" }, + {symbol<PushBlockContext>(), "PushBlockContext" }, + {symbol<CloneBlockContext>(), "CloneBlockContext" }, + {symbol<PushScriptContext>(), "PushScriptContext" }, + {symbol<PopScriptContext>(), "PopScriptContext" }, + {symbol<ThrowReferenceError>(), "ThrowReferenceError" }, + {symbol<ThrowOnNullOrUndefined>(), "ThrowOnNullOrUndefined" }, + + {symbol<Closure>(), "Closure" }, + + {symbol<ConvertThisToObject>(), "ConvertThisToObject" }, + {symbol<DeclareVar>(), "DeclareVar" }, + {symbol<CreateMappedArgumentsObject>(), "CreateMappedArgumentsObject" }, + {symbol<CreateUnmappedArgumentsObject>(), "CreateUnmappedArgumentsObject" }, + {symbol<CreateRestParameter>(), "CreateRestParameter" }, + + {symbol<ArrayLiteral>(), "ArrayLiteral" }, + {symbol<ObjectLiteral>(), "ObjectLiteral" }, + {symbol<CreateClass>(), "CreateClass" }, + + {symbol<GetIterator>(), "GetIterator" }, + {symbol<IteratorNext>(), "IteratorNext" }, + {symbol<IteratorNextForYieldStar>(), "IteratorNextForYieldStar" }, + {symbol<IteratorClose>(), "IteratorClose" }, + {symbol<DestructureRestElement>(), "DestructureRestElement" }, + + {symbol<ToObject>(), "ToObject" }, + {symbol<ToBoolean>(), "ToBoolean" }, + {symbol<ToNumber>(), "ToNumber" }, + + {symbol<UMinus>(), "UMinus" }, + + {symbol<Instanceof>(), "Instanceof" }, + {symbol<In>(), "In" }, + {symbol<Add>(), "Add" }, + {symbol<Sub>(), "Sub" }, + {symbol<Mul>(), "Mul" }, + {symbol<Div>(), "Div" }, + {symbol<Mod>(), "Mod" }, + {symbol<Exp>(), "Exp" }, + {symbol<BitAnd>(), "BitAnd" }, + {symbol<BitOr>(), "BitOr" }, + {symbol<BitXor>(), "BitXor" }, + {symbol<Shl>(), "Shl" }, + {symbol<Shr>(), "Shr" }, + {symbol<UShr>(), "UShr" }, + {symbol<GreaterThan>(), "GreaterThan" }, + {symbol<LessThan>(), "LessThan" }, + {symbol<GreaterEqual>(), "GreaterEqual" }, + {symbol<LessEqual>(), "LessEqual" }, + {symbol<Equal>(), "Equal" }, + {symbol<NotEqual>(), "NotEqual" }, + {symbol<StrictEqual>(), "StrictEqual" }, + {symbol<StrictNotEqual>(), "StrictNotEqual" }, + + {symbol<CompareGreaterThan>(), "CompareGreaterThan" }, + {symbol<CompareLessThan>(), "CompareLessThan" }, + {symbol<CompareGreaterEqual>(), "CompareGreaterEqual" }, + {symbol<CompareLessEqual>(), "CompareLessEqual" }, + {symbol<CompareEqual>(), "CompareEqual" }, + {symbol<CompareNotEqual>(), "CompareNotEqual" }, + {symbol<CompareStrictEqual>(), "CompareStrictEqual" }, + {symbol<CompareStrictNotEqual>(), "CompareStrictNotEqual" }, + + {symbol<CompareInstanceof>(), "CompareInstanceOf" }, + {symbol<CompareIn>(), "CompareIn" }, + + {symbol<RegexpLiteral>(), "RegexpLiteral" }, + {symbol<GetTemplateObject>(), "GetTemplateObject" } +#endif + }); + + return symbols; +} + } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 05ffb84d58..d155187e48 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -501,6 +501,8 @@ struct Q_QML_PRIVATE_EXPORT Runtime { static const int tailCall_argv = -3; static const int tailCall_argc = -4; }; + + static QHash<const void *, const char *> symbolTable(); }; static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof"); |
