diff options
-rw-r--r-- | src/qml/compiler/compiler.pri | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodehandler.cpp | 524 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodehandler_p.h | 113 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4jit.cpp | 480 | ||||
-rw-r--r-- | src/qml/jit/qv4jit_p.h | 54 |
6 files changed, 650 insertions, 529 deletions
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri index 95096db51d..da3c173545 100644 --- a/src/qml/compiler/compiler.pri +++ b/src/qml/compiler/compiler.pri @@ -11,7 +11,8 @@ HEADERS += \ $$PWD/qv4codegen_p.h \ $$PWD/qqmlirbuilder_p.h \ $$PWD/qqmltypecompiler_p.h \ - $$PWD/qv4instr_moth_p.h + $$PWD/qv4instr_moth_p.h \ + $$PWD/qv4bytecodehandler_p.h SOURCES += \ $$PWD/qv4bytecodegenerator.cpp \ @@ -21,7 +22,8 @@ SOURCES += \ $$PWD/qv4compilerscanfunctions.cpp \ $$PWD/qv4codegen.cpp \ $$PWD/qqmlirbuilder.cpp \ - $$PWD/qv4instr_moth.cpp + $$PWD/qv4instr_moth.cpp \ + $$PWD/qv4bytecodehandler.cpp !qmldevtools_build { diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp new file mode 100644 index 0000000000..ad1057bb9d --- /dev/null +++ b/src/qml/compiler/qv4bytecodehandler.cpp @@ -0,0 +1,524 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qv4bytecodehandler_p.h> + +QT_USE_NAMESPACE +using namespace QV4; +using namespace Moth; + +ByteCodeHandler::~ByteCodeHandler() +{ +} + +#define DISPATCH_INSTRUCTION(name, nargs, ...) \ + generate_##name( \ + __VA_ARGS__ \ + ); + +#define DECODE_AND_DISPATCH(instr) \ + { \ + INSTR_##instr(MOTH_DECODE_WITH_BASE) \ + Q_UNUSED(base_ptr); \ + startInstruction(Instr::Type::instr); \ + _offset = code - start; \ + INSTR_##instr(DISPATCH) \ + endInstruction(Instr::Type::instr); \ + continue; \ + } + +void ByteCodeHandler::decode(const char *code, uint len) +{ + MOTH_JUMP_TABLE; + + const char *start = code; + const char *end = code + len; + while (code < end) { + MOTH_DISPATCH() + + FOR_EACH_MOTH_INSTR(DECODE_AND_DISPATCH) + } +} + +#undef DECODE_AND_DISPATCH +#undef DISPATCH_INSTRUCTION + +#define MOTH_UNUSED_ARGS0() +#define MOTH_UNUSED_ARGS1(arg) \ + Q_UNUSED(arg); +#define MOTH_UNUSED_ARGS2(arg1, arg2) \ + Q_UNUSED(arg1); \ + Q_UNUSED(arg2); +#define MOTH_UNUSED_ARGS3(arg1, arg2, arg3) \ + Q_UNUSED(arg1); \ + Q_UNUSED(arg2); \ + Q_UNUSED(arg3); +#define MOTH_UNUSED_ARGS4(arg1, arg2, arg3, arg4) \ + Q_UNUSED(arg1); \ + Q_UNUSED(arg2); \ + Q_UNUSED(arg3); \ + Q_UNUSED(arg4); + +#define MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, ...) \ + MOTH_EXPAND_FOR_MSVC(MOTH_UNUSED_ARGS##nargs(__VA_ARGS__)) + +#define MOTH_MARK_ARGS_UNUSED_INSTRUCTION(name, nargs, ...) \ + MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, __VA_ARGS__) + +#define COLLECTOR_BEGIN_INSTR(instr) \ + { \ + INSTR_##instr(MOTH_DECODE_WITH_BASE) \ + INSTR_##instr(MOTH_MARK_ARGS_UNUSED) \ + Q_UNUSED(base_ptr); + +#define COLLECTOR_END_INSTR(instr) \ + continue; \ + } + +std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint len) +{ + MOTH_JUMP_TABLE; + + std::vector<int> labels; + + const auto addLabel = [&labels,len](int offset) { + Q_ASSERT(offset >= 0 && offset < static_cast<int>(len)); + labels.push_back(offset); + }; + + const char *start = code; + const char *end = code + len; + while (code < end) { + MOTH_DISPATCH() + Q_UNREACHABLE(); + + COLLECTOR_BEGIN_INSTR(LoadReg) + COLLECTOR_END_INSTR(LoadReg) + + COLLECTOR_BEGIN_INSTR(StoreReg) + COLLECTOR_END_INSTR(StoreReg) + + COLLECTOR_BEGIN_INSTR(MoveReg) + COLLECTOR_END_INSTR(MoveReg) + + COLLECTOR_BEGIN_INSTR(LoadConst) + COLLECTOR_END_INSTR(LoadConst) + + COLLECTOR_BEGIN_INSTR(LoadNull) + COLLECTOR_END_INSTR(LoadNull) + + COLLECTOR_BEGIN_INSTR(LoadZero) + COLLECTOR_END_INSTR(LoadZero) + + COLLECTOR_BEGIN_INSTR(LoadTrue) + COLLECTOR_END_INSTR(LoadTrue) + + COLLECTOR_BEGIN_INSTR(LoadFalse) + COLLECTOR_END_INSTR(LoadFalse) + + COLLECTOR_BEGIN_INSTR(LoadUndefined) + COLLECTOR_END_INSTR(LoadUndefined) + + COLLECTOR_BEGIN_INSTR(LoadInt) + COLLECTOR_END_INSTR(LoadInt) + + COLLECTOR_BEGIN_INSTR(MoveConst) + COLLECTOR_END_INSTR(MoveConst) + + COLLECTOR_BEGIN_INSTR(LoadLocal) + COLLECTOR_END_INSTR(LoadLocal) + + COLLECTOR_BEGIN_INSTR(StoreLocal) + COLLECTOR_END_INSTR(StoreLocal) + + COLLECTOR_BEGIN_INSTR(LoadScopedLocal) + COLLECTOR_END_INSTR(LoadScopedLocal) + + COLLECTOR_BEGIN_INSTR(StoreScopedLocal) + COLLECTOR_END_INSTR(StoreScopedLocal) + + COLLECTOR_BEGIN_INSTR(LoadRuntimeString) + COLLECTOR_END_INSTR(LoadRuntimeString) + + COLLECTOR_BEGIN_INSTR(MoveRegExp) + COLLECTOR_END_INSTR(MoveRegExp) + + COLLECTOR_BEGIN_INSTR(LoadClosure) + COLLECTOR_END_INSTR(LoadClosure) + + COLLECTOR_BEGIN_INSTR(LoadName) + COLLECTOR_END_INSTR(LoadName) + + COLLECTOR_BEGIN_INSTR(LoadGlobalLookup) + COLLECTOR_END_INSTR(LoadGlobalLookup) + + COLLECTOR_BEGIN_INSTR(StoreNameSloppy) + COLLECTOR_END_INSTR(StoreNameSloppy) + + COLLECTOR_BEGIN_INSTR(StoreNameStrict) + COLLECTOR_END_INSTR(StoreNameStrict) + + COLLECTOR_BEGIN_INSTR(LoadElement) + COLLECTOR_END_INSTR(LoadElement) + + COLLECTOR_BEGIN_INSTR(LoadElementA) + COLLECTOR_END_INSTR(LoadElement) + + COLLECTOR_BEGIN_INSTR(StoreElement) + COLLECTOR_END_INSTR(StoreElement) + + COLLECTOR_BEGIN_INSTR(LoadProperty) + COLLECTOR_END_INSTR(LoadProperty) + + COLLECTOR_BEGIN_INSTR(LoadPropertyA) + COLLECTOR_END_INSTR(LoadElementA) + + COLLECTOR_BEGIN_INSTR(GetLookup) + COLLECTOR_END_INSTR(GetLookup) + + COLLECTOR_BEGIN_INSTR(GetLookupA) + COLLECTOR_END_INSTR(GetLookupA) + + COLLECTOR_BEGIN_INSTR(StoreProperty) + COLLECTOR_END_INSTR(StoreProperty) + + COLLECTOR_BEGIN_INSTR(SetLookup) + COLLECTOR_END_INSTR(SetLookup) + + COLLECTOR_BEGIN_INSTR(StoreScopeObjectProperty) + COLLECTOR_END_INSTR(StoreScopeObjectProperty) + + COLLECTOR_BEGIN_INSTR(LoadScopeObjectProperty) + COLLECTOR_END_INSTR(LoadScopeObjectProperty) + + COLLECTOR_BEGIN_INSTR(StoreContextObjectProperty) + COLLECTOR_END_INSTR(StoreContextObjectProperty) + + COLLECTOR_BEGIN_INSTR(LoadContextObjectProperty) + COLLECTOR_END_INSTR(LoadContextObjectProperty) + + COLLECTOR_BEGIN_INSTR(LoadIdObject) + COLLECTOR_END_INSTR(LoadIdObject) + + COLLECTOR_BEGIN_INSTR(Yield) + COLLECTOR_END_INSTR(Yield) + + COLLECTOR_BEGIN_INSTR(Resume) + COLLECTOR_END_INSTR(Resume) + + COLLECTOR_BEGIN_INSTR(CallValue) + COLLECTOR_END_INSTR(CallValue) + + COLLECTOR_BEGIN_INSTR(CallProperty) + COLLECTOR_END_INSTR(CallProperty) + + COLLECTOR_BEGIN_INSTR(CallPropertyLookup) + COLLECTOR_END_INSTR(CallPropertyLookup) + + COLLECTOR_BEGIN_INSTR(CallElement) + COLLECTOR_END_INSTR(CallElement) + + COLLECTOR_BEGIN_INSTR(CallName) + COLLECTOR_END_INSTR(CallName) + + COLLECTOR_BEGIN_INSTR(CallPossiblyDirectEval) + COLLECTOR_END_INSTR(CallPossiblyDirectEval) + + COLLECTOR_BEGIN_INSTR(CallGlobalLookup) + COLLECTOR_END_INSTR(CallGlobalLookup) + + COLLECTOR_BEGIN_INSTR(CallScopeObjectProperty) + COLLECTOR_END_INSTR(CallScopeObjectProperty) + + COLLECTOR_BEGIN_INSTR(CallContextObjectProperty) + COLLECTOR_END_INSTR(CallContextObjectProperty) + + COLLECTOR_BEGIN_INSTR(SetExceptionHandler) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(SetExceptionHandler) + + COLLECTOR_BEGIN_INSTR(ThrowException) + COLLECTOR_END_INSTR(ThrowException) + + COLLECTOR_BEGIN_INSTR(GetException) + COLLECTOR_END_INSTR(HasException) + + COLLECTOR_BEGIN_INSTR(SetException) + COLLECTOR_END_INSTR(SetExceptionFlag) + + COLLECTOR_BEGIN_INSTR(CreateCallContext) + COLLECTOR_END_INSTR(CreateCallContext) + + COLLECTOR_BEGIN_INSTR(PushCatchContext) + COLLECTOR_END_INSTR(PushCatchContext) + + COLLECTOR_BEGIN_INSTR(PushWithContext) + COLLECTOR_END_INSTR(PushWithContext) + + COLLECTOR_BEGIN_INSTR(PushBlockContext) + COLLECTOR_END_INSTR(PushBlockContext) + + COLLECTOR_BEGIN_INSTR(CloneBlockContext) + COLLECTOR_END_INSTR(CloneBlockContext) + + COLLECTOR_BEGIN_INSTR(PushScriptContext) + COLLECTOR_END_INSTR(PushScriptContext) + + COLLECTOR_BEGIN_INSTR(PopScriptContext) + COLLECTOR_END_INSTR(PopScriptContext) + + COLLECTOR_BEGIN_INSTR(PopContext) + COLLECTOR_END_INSTR(PopContext) + + COLLECTOR_BEGIN_INSTR(GetIterator) + COLLECTOR_END_INSTR(GetIterator) + + COLLECTOR_BEGIN_INSTR(IteratorNext) + COLLECTOR_END_INSTR(IteratorNext) + + COLLECTOR_BEGIN_INSTR(IteratorClose) + COLLECTOR_END_INSTR(IteratorClose) + + COLLECTOR_BEGIN_INSTR(DestructureRestElement) + COLLECTOR_END_INSTR(DestructureRestElement) + + COLLECTOR_BEGIN_INSTR(DeleteMember) + COLLECTOR_END_INSTR(DeleteMember) + + COLLECTOR_BEGIN_INSTR(DeleteSubscript) + COLLECTOR_END_INSTR(DeleteSubscript) + + COLLECTOR_BEGIN_INSTR(DeleteName) + COLLECTOR_END_INSTR(DeleteName) + + COLLECTOR_BEGIN_INSTR(TypeofName) + COLLECTOR_END_INSTR(TypeofName) + + COLLECTOR_BEGIN_INSTR(TypeofValue) + COLLECTOR_END_INSTR(TypeofValue) + + COLLECTOR_BEGIN_INSTR(DeclareVar) + COLLECTOR_END_INSTR(DeclareVar) + + COLLECTOR_BEGIN_INSTR(DefineArray) + COLLECTOR_END_INSTR(DefineArray) + + COLLECTOR_BEGIN_INSTR(DefineObjectLiteral) + COLLECTOR_END_INSTR(DefineObjectLiteral) + + COLLECTOR_BEGIN_INSTR(CreateMappedArgumentsObject) + COLLECTOR_END_INSTR(CreateMappedArgumentsObject) + + COLLECTOR_BEGIN_INSTR(CreateUnmappedArgumentsObject) + COLLECTOR_END_INSTR(CreateUnmappedArgumentsObject) + + COLLECTOR_BEGIN_INSTR(CreateRestParameter) + COLLECTOR_END_INSTR(CreateRestParameter) + + COLLECTOR_BEGIN_INSTR(ConvertThisToObject) + COLLECTOR_END_INSTR(ConvertThisToObject) + + COLLECTOR_BEGIN_INSTR(ToObject) + COLLECTOR_END_INSTR(ToObject) + + COLLECTOR_BEGIN_INSTR(Construct) + COLLECTOR_END_INSTR(Construct) + + COLLECTOR_BEGIN_INSTR(Jump) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(Jump) + + COLLECTOR_BEGIN_INSTR(JumpTrue) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpTrue) + + COLLECTOR_BEGIN_INSTR(JumpFalse) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpFalse) + + COLLECTOR_BEGIN_INSTR(JumpNotUndefined) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpNotUndefined) + + COLLECTOR_BEGIN_INSTR(JumpEmpty) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpEmpty) + + COLLECTOR_BEGIN_INSTR(CmpEqNull) + COLLECTOR_END_INSTR(CmpEqNull) + + COLLECTOR_BEGIN_INSTR(CmpNeNull) + COLLECTOR_END_INSTR(CmpNeNull) + + COLLECTOR_BEGIN_INSTR(CmpEqInt) + COLLECTOR_END_INSTR(CmpEq) + + COLLECTOR_BEGIN_INSTR(CmpNeInt) + COLLECTOR_END_INSTR(CmpNeInt) + + COLLECTOR_BEGIN_INSTR(CmpEq) + COLLECTOR_END_INSTR(CmpEq) + + COLLECTOR_BEGIN_INSTR(CmpNe) + COLLECTOR_END_INSTR(CmpNe) + + COLLECTOR_BEGIN_INSTR(CmpGt) + COLLECTOR_END_INSTR(CmpGt) + + COLLECTOR_BEGIN_INSTR(CmpGe) + COLLECTOR_END_INSTR(CmpGe) + + COLLECTOR_BEGIN_INSTR(CmpLt) + COLLECTOR_END_INSTR(CmpLt) + + COLLECTOR_BEGIN_INSTR(CmpLe) + COLLECTOR_END_INSTR(CmpLe) + + COLLECTOR_BEGIN_INSTR(CmpStrictEqual) + COLLECTOR_END_INSTR(CmpStrictEqual) + + COLLECTOR_BEGIN_INSTR(CmpStrictNotEqual) + COLLECTOR_END_INSTR(CmpStrictNotEqual) + + COLLECTOR_BEGIN_INSTR(CmpIn) + COLLECTOR_END_INSTR(CmpIn) + + COLLECTOR_BEGIN_INSTR(CmpInstanceOf) + COLLECTOR_END_INSTR(CmpInstanceOf) + + COLLECTOR_BEGIN_INSTR(JumpStrictEqualStackSlotInt) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpStrictEqualStackSlotInt) + + COLLECTOR_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt) + addLabel(code - start + offset); + COLLECTOR_END_INSTR(JumpStrictNotEqualStackSlotInt) + + COLLECTOR_BEGIN_INSTR(UNot) + COLLECTOR_END_INSTR(UNot) + + COLLECTOR_BEGIN_INSTR(UPlus) + COLLECTOR_END_INSTR(UPlus) + + COLLECTOR_BEGIN_INSTR(UMinus) + COLLECTOR_END_INSTR(UMinus) + + COLLECTOR_BEGIN_INSTR(UCompl) + COLLECTOR_END_INSTR(UCompl) + + COLLECTOR_BEGIN_INSTR(Increment) + COLLECTOR_END_INSTR(PreIncrement) + + COLLECTOR_BEGIN_INSTR(Decrement) + COLLECTOR_END_INSTR(PreDecrement) + + COLLECTOR_BEGIN_INSTR(Add) + COLLECTOR_END_INSTR(Add) + + COLLECTOR_BEGIN_INSTR(BitAnd) + COLLECTOR_END_INSTR(BitAnd) + + COLLECTOR_BEGIN_INSTR(BitOr) + COLLECTOR_END_INSTR(BitOr) + + COLLECTOR_BEGIN_INSTR(BitXor) + COLLECTOR_END_INSTR(BitXor) + + COLLECTOR_BEGIN_INSTR(UShr) + COLLECTOR_END_INSTR(UShr) + + COLLECTOR_BEGIN_INSTR(Shr) + COLLECTOR_END_INSTR(Shr) + + COLLECTOR_BEGIN_INSTR(Shl) + COLLECTOR_END_INSTR(Shl) + + COLLECTOR_BEGIN_INSTR(BitAndConst) + COLLECTOR_END_INSTR(BitAndConst) + + COLLECTOR_BEGIN_INSTR(BitOrConst) + COLLECTOR_END_INSTR(BitOr) + + COLLECTOR_BEGIN_INSTR(BitXorConst) + COLLECTOR_END_INSTR(BitXor) + + COLLECTOR_BEGIN_INSTR(UShrConst) + COLLECTOR_END_INSTR(UShrConst) + + COLLECTOR_BEGIN_INSTR(ShrConst) + COLLECTOR_END_INSTR(ShrConst) + + COLLECTOR_BEGIN_INSTR(ShlConst) + COLLECTOR_END_INSTR(ShlConst) + + COLLECTOR_BEGIN_INSTR(Exp) + COLLECTOR_END_INSTR(Exp) + + COLLECTOR_BEGIN_INSTR(Mul) + COLLECTOR_END_INSTR(Mul) + + COLLECTOR_BEGIN_INSTR(Div) + COLLECTOR_END_INSTR(Div) + + COLLECTOR_BEGIN_INSTR(Mod) + COLLECTOR_END_INSTR(Mod) + + COLLECTOR_BEGIN_INSTR(Sub) + COLLECTOR_END_INSTR(Sub) + + COLLECTOR_BEGIN_INSTR(Ret) + COLLECTOR_END_INSTR(Ret) + +#ifndef QT_NO_QML_DEBUGGER + COLLECTOR_BEGIN_INSTR(Debug) + COLLECTOR_END_INSTR(Debug) +#endif // QT_NO_QML_DEBUGGER + + COLLECTOR_BEGIN_INSTR(LoadQmlContext) + COLLECTOR_END_INSTR(LoadQmlContext) + + COLLECTOR_BEGIN_INSTR(LoadQmlImportedScripts) + COLLECTOR_END_INSTR(LoadQmlImportedScripts) + } + + return labels; +} + +#undef COLLECTOR_BEGIN_INSTR +#undef COLLECTOR_END_INSTR diff --git a/src/qml/compiler/qv4bytecodehandler_p.h b/src/qml/compiler/qv4bytecodehandler_p.h new file mode 100644 index 0000000000..5f1121306f --- /dev/null +++ b/src/qml/compiler/qv4bytecodehandler_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QV4BYTECODEHANDLER_P_H +#define QV4BYTECODEHANDLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +#include <private/qv4instr_moth_p.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { +namespace Moth { + +#define BYTECODE_HANDLER_DEFINE_ARGS(nargs, ...) \ + MOTH_EXPAND_FOR_MSVC(BYTECODE_HANDLER_DEFINE_ARGS##nargs(__VA_ARGS__)) + +#define BYTECODE_HANDLER_DEFINE_ARGS0() +#define BYTECODE_HANDLER_DEFINE_ARGS1(arg) \ + int arg +#define BYTECODE_HANDLER_DEFINE_ARGS2(arg1, arg2) \ + int arg1, \ + int arg2 +#define BYTECODE_HANDLER_DEFINE_ARGS3(arg1, arg2, arg3) \ + int arg1, \ + int arg2, \ + int arg3 +#define BYTECODE_HANDLER_DEFINE_ARGS4(arg1, arg2, arg3, arg4) \ + int arg1, \ + int arg2, \ + int arg3, \ + int arg4 + +#define BYTECODE_HANDLER_DEFINE_VIRTUAL_BYTECODE_HANDLER_INSTRUCTION(name, nargs, ...) \ + virtual void generate_##name( \ + BYTECODE_HANDLER_DEFINE_ARGS(nargs, __VA_ARGS__) \ + ) = 0; + +#define BYTECODE_HANDLER_DEFINE_VIRTUAL_BYTECODE_HANDLER(instr) \ + INSTR_##instr(BYTECODE_HANDLER_DEFINE_VIRTUAL_BYTECODE_HANDLER) + +class ByteCodeHandler +{ +public: + virtual ~ByteCodeHandler(); + + void decode(const char *code, uint len); + + int instructionOffset() const { return _offset; } + + static std::vector<int> collectLabelsInBytecode(const char *code, uint len); + +protected: + FOR_EACH_MOTH_INSTR(BYTECODE_HANDLER_DEFINE_VIRTUAL_BYTECODE_HANDLER) + + virtual void startInstruction(Moth::Instr::Type instr) = 0; + virtual void endInstruction(Moth::Instr::Type instr) = 0; + +private: + int _offset = 0; +}; + +} // Moth namespace +} // QV4 namespace + +QT_END_NAMESPACE + +#endif // QV4BYTECODEHANDLER_P_H diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 54a7f5f13e..5dc20ba11b 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -53,6 +53,8 @@ #include <private/qv4global_p.h> #include <private/qv4value_p.h> #include <private/qv4runtime_p.h> +#include <private/qv4compileddata_p.h> // for CompiledData::CodeOffsetToLine used by the dumper +#include <qendian.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp index 2bc60bff70..e9151599f6 100644 --- a/src/qml/jit/qv4jit.cpp +++ b/src/qml/jit/qv4jit.cpp @@ -49,42 +49,6 @@ using namespace QV4; using namespace QV4::JIT; using namespace QV4::Moth; -ByteCodeHandler::~ByteCodeHandler() -{ -} - -#define DISPATCH_INSTRUCTION(name, nargs, ...) \ - generate_##name( \ - __VA_ARGS__ \ - ); - -#define DECODE_AND_DISPATCH(instr) \ - { \ - INSTR_##instr(MOTH_DECODE_WITH_BASE) \ - Q_UNUSED(base_ptr); \ - startInstruction(Instr::Type::instr); \ - _offset = code - start; \ - INSTR_##instr(DISPATCH) \ - endInstruction(Instr::Type::instr); \ - continue; \ - } - -void ByteCodeHandler::decode(const char *code, uint len) -{ - MOTH_JUMP_TABLE; - - const char *start = code; - const char *end = code + len; - while (code < end) { - MOTH_DISPATCH() - - FOR_EACH_MOTH_INSTR(DECODE_AND_DISPATCH) - } -} - -#undef DECODE_AND_DISPATCH -#undef DISPATCH_INSTRUCTION - BaselineJIT::BaselineJIT(Function *function) : function(function) , as(new Assembler(function->compilationUnit->constants)) @@ -96,10 +60,12 @@ BaselineJIT::~BaselineJIT() void BaselineJIT::generate() { // qDebug()<<"jitting" << function->name()->toQString(); - collectLabelsInBytecode(); + const char *code = reinterpret_cast<const char *>(function->codeData); + uint len = function->compiledFunction->codeSize; + labels = collectLabelsInBytecode(code, len); as->generatePrologue(); - decode(reinterpret_cast<const char *>(function->codeData), function->compiledFunction->codeSize); + decode(code, len); as->generateEpilogue(); as->link(function); @@ -1066,442 +1032,4 @@ void BaselineJIT::endInstruction(Instr::Type instr) Q_UNUSED(instr); } -#define MOTH_UNUSED_ARGS0() -#define MOTH_UNUSED_ARGS1(arg) \ - Q_UNUSED(arg); -#define MOTH_UNUSED_ARGS2(arg1, arg2) \ - Q_UNUSED(arg1); \ - Q_UNUSED(arg2); -#define MOTH_UNUSED_ARGS3(arg1, arg2, arg3) \ - Q_UNUSED(arg1); \ - Q_UNUSED(arg2); \ - Q_UNUSED(arg3); -#define MOTH_UNUSED_ARGS4(arg1, arg2, arg3, arg4) \ - Q_UNUSED(arg1); \ - Q_UNUSED(arg2); \ - Q_UNUSED(arg3); \ - Q_UNUSED(arg4); - -#define MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, ...) \ - MOTH_EXPAND_FOR_MSVC(MOTH_UNUSED_ARGS##nargs(__VA_ARGS__)) - -#define MOTH_MARK_ARGS_UNUSED_INSTRUCTION(name, nargs, ...) \ - MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, __VA_ARGS__) - -#define MOTH_BEGIN_INSTR(instr) \ - { \ - INSTR_##instr(MOTH_DECODE_WITH_BASE) \ - INSTR_##instr(MOTH_MARK_ARGS_UNUSED) \ - Q_UNUSED(base_ptr); - -#define MOTH_END_INSTR(instr) \ - continue; \ - } - -void BaselineJIT::collectLabelsInBytecode() -{ - MOTH_JUMP_TABLE; - - const auto addLabel = [&](int offset) { - Q_ASSERT(offset >= 0 && offset < static_cast<int>(function->compiledFunction->codeSize)); - labels.push_back(offset); - }; - - const char *code = reinterpret_cast<const char *>(function->codeData); - const char *start = code; - const char *end = code + function->compiledFunction->codeSize; - while (code < end) { - MOTH_DISPATCH() - Q_UNREACHABLE(); - - MOTH_BEGIN_INSTR(LoadReg) - MOTH_END_INSTR(LoadReg) - - MOTH_BEGIN_INSTR(StoreReg) - MOTH_END_INSTR(StoreReg) - - MOTH_BEGIN_INSTR(MoveReg) - MOTH_END_INSTR(MoveReg) - - MOTH_BEGIN_INSTR(LoadConst) - MOTH_END_INSTR(LoadConst) - - MOTH_BEGIN_INSTR(LoadNull) - MOTH_END_INSTR(LoadNull) - - MOTH_BEGIN_INSTR(LoadZero) - MOTH_END_INSTR(LoadZero) - - MOTH_BEGIN_INSTR(LoadTrue) - MOTH_END_INSTR(LoadTrue) - - MOTH_BEGIN_INSTR(LoadFalse) - MOTH_END_INSTR(LoadFalse) - - MOTH_BEGIN_INSTR(LoadUndefined) - MOTH_END_INSTR(LoadUndefined) - - MOTH_BEGIN_INSTR(LoadInt) - MOTH_END_INSTR(LoadInt) - - MOTH_BEGIN_INSTR(MoveConst) - MOTH_END_INSTR(MoveConst) - - MOTH_BEGIN_INSTR(LoadLocal) - MOTH_END_INSTR(LoadLocal) - - MOTH_BEGIN_INSTR(StoreLocal) - MOTH_END_INSTR(StoreLocal) - - MOTH_BEGIN_INSTR(LoadScopedLocal) - MOTH_END_INSTR(LoadScopedLocal) - - MOTH_BEGIN_INSTR(StoreScopedLocal) - MOTH_END_INSTR(StoreScopedLocal) - - MOTH_BEGIN_INSTR(LoadRuntimeString) - MOTH_END_INSTR(LoadRuntimeString) - - MOTH_BEGIN_INSTR(MoveRegExp) - MOTH_END_INSTR(MoveRegExp) - - MOTH_BEGIN_INSTR(LoadClosure) - MOTH_END_INSTR(LoadClosure) - - MOTH_BEGIN_INSTR(LoadName) - MOTH_END_INSTR(LoadName) - - MOTH_BEGIN_INSTR(LoadGlobalLookup) - MOTH_END_INSTR(LoadGlobalLookup) - - MOTH_BEGIN_INSTR(StoreNameSloppy) - MOTH_END_INSTR(StoreNameSloppy) - - MOTH_BEGIN_INSTR(StoreNameStrict) - MOTH_END_INSTR(StoreNameStrict) - - MOTH_BEGIN_INSTR(LoadElement) - MOTH_END_INSTR(LoadElement) - - MOTH_BEGIN_INSTR(LoadElementA) - MOTH_END_INSTR(LoadElement) - - MOTH_BEGIN_INSTR(StoreElement) - MOTH_END_INSTR(StoreElement) - - MOTH_BEGIN_INSTR(LoadProperty) - MOTH_END_INSTR(LoadProperty) - - MOTH_BEGIN_INSTR(LoadPropertyA) - MOTH_END_INSTR(LoadElementA) - - MOTH_BEGIN_INSTR(GetLookup) - MOTH_END_INSTR(GetLookup) - - MOTH_BEGIN_INSTR(GetLookupA) - MOTH_END_INSTR(GetLookupA) - - MOTH_BEGIN_INSTR(StoreProperty) - MOTH_END_INSTR(StoreProperty) - - MOTH_BEGIN_INSTR(SetLookup) - MOTH_END_INSTR(SetLookup) - - MOTH_BEGIN_INSTR(StoreScopeObjectProperty) - MOTH_END_INSTR(StoreScopeObjectProperty) - - MOTH_BEGIN_INSTR(LoadScopeObjectProperty) - MOTH_END_INSTR(LoadScopeObjectProperty) - - MOTH_BEGIN_INSTR(StoreContextObjectProperty) - MOTH_END_INSTR(StoreContextObjectProperty) - - MOTH_BEGIN_INSTR(LoadContextObjectProperty) - MOTH_END_INSTR(LoadContextObjectProperty) - - MOTH_BEGIN_INSTR(LoadIdObject) - MOTH_END_INSTR(LoadIdObject) - - MOTH_BEGIN_INSTR(Yield) - MOTH_END_INSTR(Yield) - - MOTH_BEGIN_INSTR(Resume) - MOTH_END_INSTR(Resume) - - MOTH_BEGIN_INSTR(CallValue) - MOTH_END_INSTR(CallValue) - - MOTH_BEGIN_INSTR(CallProperty) - MOTH_END_INSTR(CallProperty) - - MOTH_BEGIN_INSTR(CallPropertyLookup) - MOTH_END_INSTR(CallPropertyLookup) - - MOTH_BEGIN_INSTR(CallElement) - MOTH_END_INSTR(CallElement) - - MOTH_BEGIN_INSTR(CallName) - MOTH_END_INSTR(CallName) - - MOTH_BEGIN_INSTR(CallPossiblyDirectEval) - MOTH_END_INSTR(CallPossiblyDirectEval) - - MOTH_BEGIN_INSTR(CallGlobalLookup) - MOTH_END_INSTR(CallGlobalLookup) - - MOTH_BEGIN_INSTR(CallScopeObjectProperty) - MOTH_END_INSTR(CallScopeObjectProperty) - - MOTH_BEGIN_INSTR(CallContextObjectProperty) - MOTH_END_INSTR(CallContextObjectProperty) - - MOTH_BEGIN_INSTR(SetExceptionHandler) - addLabel(code - start + offset); - MOTH_END_INSTR(SetExceptionHandler) - - MOTH_BEGIN_INSTR(ThrowException) - MOTH_END_INSTR(ThrowException) - - MOTH_BEGIN_INSTR(GetException) - MOTH_END_INSTR(HasException) - - MOTH_BEGIN_INSTR(SetException) - MOTH_END_INSTR(SetExceptionFlag) - - MOTH_BEGIN_INSTR(CreateCallContext) - MOTH_END_INSTR(CreateCallContext) - - MOTH_BEGIN_INSTR(PushCatchContext) - MOTH_END_INSTR(PushCatchContext) - - MOTH_BEGIN_INSTR(PushWithContext) - MOTH_END_INSTR(PushWithContext) - - MOTH_BEGIN_INSTR(PushBlockContext) - MOTH_END_INSTR(PushBlockContext) - - MOTH_BEGIN_INSTR(CloneBlockContext) - MOTH_END_INSTR(CloneBlockContext) - - MOTH_BEGIN_INSTR(PushScriptContext) - MOTH_END_INSTR(PushScriptContext) - - MOTH_BEGIN_INSTR(PopScriptContext) - MOTH_END_INSTR(PopScriptContext) - - MOTH_BEGIN_INSTR(PopContext) - MOTH_END_INSTR(PopContext) - - MOTH_BEGIN_INSTR(GetIterator) - MOTH_END_INSTR(GetIterator) - - MOTH_BEGIN_INSTR(IteratorNext) - MOTH_END_INSTR(IteratorNext) - - MOTH_BEGIN_INSTR(IteratorClose) - MOTH_END_INSTR(IteratorClose) - - MOTH_BEGIN_INSTR(DestructureRestElement) - MOTH_END_INSTR(DestructureRestElement) - - MOTH_BEGIN_INSTR(DeleteMember) - MOTH_END_INSTR(DeleteMember) - - MOTH_BEGIN_INSTR(DeleteSubscript) - MOTH_END_INSTR(DeleteSubscript) - - MOTH_BEGIN_INSTR(DeleteName) - MOTH_END_INSTR(DeleteName) - - MOTH_BEGIN_INSTR(TypeofName) - MOTH_END_INSTR(TypeofName) - - MOTH_BEGIN_INSTR(TypeofValue) - MOTH_END_INSTR(TypeofValue) - - MOTH_BEGIN_INSTR(DeclareVar) - MOTH_END_INSTR(DeclareVar) - - MOTH_BEGIN_INSTR(DefineArray) - MOTH_END_INSTR(DefineArray) - - MOTH_BEGIN_INSTR(DefineObjectLiteral) - MOTH_END_INSTR(DefineObjectLiteral) - - MOTH_BEGIN_INSTR(CreateMappedArgumentsObject) - MOTH_END_INSTR(CreateMappedArgumentsObject) - - MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject) - MOTH_END_INSTR(CreateUnmappedArgumentsObject) - - MOTH_BEGIN_INSTR(CreateRestParameter) - MOTH_END_INSTR(CreateRestParameter) - - MOTH_BEGIN_INSTR(ToObject) - MOTH_END_INSTR(ToObject) - - MOTH_BEGIN_INSTR(ConvertThisToObject) - MOTH_END_INSTR(ConvertThisToObject) - - MOTH_BEGIN_INSTR(Construct) - MOTH_END_INSTR(Construct) - - MOTH_BEGIN_INSTR(Jump) - addLabel(code - start + offset); - MOTH_END_INSTR(Jump) - - MOTH_BEGIN_INSTR(JumpTrue) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpTrue) - - MOTH_BEGIN_INSTR(JumpFalse) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpFalse) - - MOTH_BEGIN_INSTR(JumpNotUndefined) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpNotUndefined) - - MOTH_BEGIN_INSTR(JumpEmpty) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpEmpty) - - MOTH_BEGIN_INSTR(CmpEqNull) - MOTH_END_INSTR(CmpEqNull) - - MOTH_BEGIN_INSTR(CmpNeNull) - MOTH_END_INSTR(CmpNeNull) - - MOTH_BEGIN_INSTR(CmpEqInt) - MOTH_END_INSTR(CmpEq) - - MOTH_BEGIN_INSTR(CmpNeInt) - MOTH_END_INSTR(CmpNeInt) - - MOTH_BEGIN_INSTR(CmpEq) - MOTH_END_INSTR(CmpEq) - - MOTH_BEGIN_INSTR(CmpNe) - MOTH_END_INSTR(CmpNe) - - MOTH_BEGIN_INSTR(CmpGt) - MOTH_END_INSTR(CmpGt) - - MOTH_BEGIN_INSTR(CmpGe) - MOTH_END_INSTR(CmpGe) - - MOTH_BEGIN_INSTR(CmpLt) - MOTH_END_INSTR(CmpLt) - - MOTH_BEGIN_INSTR(CmpLe) - MOTH_END_INSTR(CmpLe) - - MOTH_BEGIN_INSTR(CmpStrictEqual) - MOTH_END_INSTR(CmpStrictEqual) - - MOTH_BEGIN_INSTR(CmpStrictNotEqual) - MOTH_END_INSTR(CmpStrictNotEqual) - - MOTH_BEGIN_INSTR(CmpIn) - MOTH_END_INSTR(CmpIn) - - MOTH_BEGIN_INSTR(CmpInstanceOf) - MOTH_END_INSTR(CmpInstanceOf) - - MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpStrictEqualStackSlotInt) - - MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt) - addLabel(code - start + offset); - MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt) - - MOTH_BEGIN_INSTR(UNot) - MOTH_END_INSTR(UNot) - - MOTH_BEGIN_INSTR(UPlus) - MOTH_END_INSTR(UPlus) - - MOTH_BEGIN_INSTR(UMinus) - MOTH_END_INSTR(UMinus) - - MOTH_BEGIN_INSTR(UCompl) - MOTH_END_INSTR(UCompl) - - MOTH_BEGIN_INSTR(Increment) - MOTH_END_INSTR(PreIncrement) - - MOTH_BEGIN_INSTR(Decrement) - MOTH_END_INSTR(PreDecrement) - - MOTH_BEGIN_INSTR(Add) - MOTH_END_INSTR(Add) - - MOTH_BEGIN_INSTR(BitAnd) - MOTH_END_INSTR(BitAnd) - - MOTH_BEGIN_INSTR(BitOr) - MOTH_END_INSTR(BitOr) - - MOTH_BEGIN_INSTR(BitXor) - MOTH_END_INSTR(BitXor) - - MOTH_BEGIN_INSTR(UShr) - MOTH_END_INSTR(UShr) - - MOTH_BEGIN_INSTR(Shr) - MOTH_END_INSTR(Shr) - - MOTH_BEGIN_INSTR(Shl) - MOTH_END_INSTR(Shl) - - MOTH_BEGIN_INSTR(BitAndConst) - MOTH_END_INSTR(BitAndConst) - - MOTH_BEGIN_INSTR(BitOrConst) - MOTH_END_INSTR(BitOr) - - MOTH_BEGIN_INSTR(BitXorConst) - MOTH_END_INSTR(BitXor) - - MOTH_BEGIN_INSTR(UShrConst) - MOTH_END_INSTR(UShrConst) - - MOTH_BEGIN_INSTR(ShrConst) - MOTH_END_INSTR(ShrConst) - - MOTH_BEGIN_INSTR(ShlConst) - MOTH_END_INSTR(ShlConst) - - MOTH_BEGIN_INSTR(Exp) - MOTH_END_INSTR(Exp) - - MOTH_BEGIN_INSTR(Mul) - MOTH_END_INSTR(Mul) - - MOTH_BEGIN_INSTR(Div) - MOTH_END_INSTR(Div) - - MOTH_BEGIN_INSTR(Mod) - MOTH_END_INSTR(Mod) - - MOTH_BEGIN_INSTR(Sub) - MOTH_END_INSTR(Sub) - - MOTH_BEGIN_INSTR(Ret) - MOTH_END_INSTR(Ret) - - MOTH_BEGIN_INSTR(Debug) - MOTH_END_INSTR(Debug) - - MOTH_BEGIN_INSTR(LoadQmlContext) - MOTH_END_INSTR(LoadQmlContext) - - MOTH_BEGIN_INSTR(LoadQmlImportedScripts) - MOTH_END_INSTR(LoadQmlImportedScripts) - } -} -#undef MOTH_BEGIN_INSTR -#undef MOTH_END_INSTR - #endif // V4_ENABLE_JIT diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h index 8aa0cb430e..12a3f27e1b 100644 --- a/src/qml/jit/qv4jit_p.h +++ b/src/qml/jit/qv4jit_p.h @@ -54,36 +54,10 @@ #include <private/qv4global_p.h> #include <private/qv4function_p.h> #include <private/qv4instr_moth_p.h> +#include <private/qv4bytecodehandler_p.h> //QT_REQUIRE_CONFIG(qml_jit); -#define JIT_DEFINE_ARGS(nargs, ...) \ - MOTH_EXPAND_FOR_MSVC(JIT_DEFINE_ARGS##nargs(__VA_ARGS__)) - -#define JIT_DEFINE_ARGS0() -#define JIT_DEFINE_ARGS1(arg) \ - int arg -#define JIT_DEFINE_ARGS2(arg1, arg2) \ - int arg1, \ - int arg2 -#define JIT_DEFINE_ARGS3(arg1, arg2, arg3) \ - int arg1, \ - int arg2, \ - int arg3 -#define JIT_DEFINE_ARGS4(arg1, arg2, arg3, arg4) \ - int arg1, \ - int arg2, \ - int arg3, \ - int arg4 - -#define JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER_INSTRUCTION(name, nargs, ...) \ - virtual void generate_##name( \ - JIT_DEFINE_ARGS(nargs, __VA_ARGS__) \ - ) = 0; - -#define JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER(instr) \ - INSTR_##instr(JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER) - QT_BEGIN_NAMESPACE namespace QV4 { @@ -91,31 +65,12 @@ namespace JIT { class Assembler; -class ByteCodeHandler -{ -public: - virtual ~ByteCodeHandler(); - - void decode(const char *code, uint len); - - int instructionOffset() const { return _offset; } - -protected: - FOR_EACH_MOTH_INSTR(JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER) - - virtual void startInstruction(Moth::Instr::Type instr) = 0; - virtual void endInstruction(Moth::Instr::Type instr) = 0; - -private: - int _offset = 0; -}; - #ifdef V4_ENABLE_JIT -class BaselineJIT final: public ByteCodeHandler +class BaselineJIT final: public Moth::ByteCodeHandler { public: BaselineJIT(QV4::Function *); - virtual ~BaselineJIT(); + virtual ~BaselineJIT() Q_DECL_OVERRIDE; void generate(); @@ -263,9 +218,6 @@ protected: { return std::find(labels.cbegin(), labels.cend(), instructionOffset()) != labels.cend(); } private: - void collectLabelsInBytecode(); - -private: QV4::Function *function; QScopedPointer<Assembler> as; std::vector<int> labels; |