aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2018-06-06 16:29:13 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2018-08-27 08:37:12 +0000
commitbf136379521d543c54d5c0ce377471ff76dce35e (patch)
tree3ab1957556a73ebbf7e1f236e8186572f1f1fac4 /src
parent83ded6108a947453744114543146a7f691f6f1aa (diff)
V4: Split PlatformAssemblerCommon (and base classes) in its own file
This makes it easier to re-use them later on, without inheriting all extra stuff that the baseline JIT needs. Change-Id: I9368b16017b8b9d99f8c005a5b47ec9f9ed09fb0 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jit/jit.pri6
-rw-r--r--src/qml/jit/qv4assemblercommon.cpp343
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h697
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp (renamed from src/qml/jit/qv4assembler.cpp)1159
-rw-r--r--src/qml/jit/qv4baselineassembler_p.h (renamed from src/qml/jit/qv4assembler_p.h)34
-rw-r--r--src/qml/jit/qv4baselinejit.cpp240
-rw-r--r--src/qml/jit/qv4baselinejit_p.h4
-rw-r--r--src/qml/jsruntime/qv4global_p.h11
8 files changed, 1406 insertions, 1088 deletions
diff --git a/src/qml/jit/jit.pri b/src/qml/jit/jit.pri
index 9e3cf44387..2c664af188 100644
--- a/src/qml/jit/jit.pri
+++ b/src/qml/jit/jit.pri
@@ -4,9 +4,11 @@ INCLUDEPATH += $$OUT_PWD
SOURCES += \
$$PWD/qv4jithelpers.cpp \
$$PWD/qv4baselinejit.cpp \
- $$PWD/qv4assembler.cpp
+ $$PWD/qv4baselineassembler.cpp \
+ $$PWD/qv4assemblercommon.cpp
HEADERS += \
$$PWD/qv4jithelpers_p.h \
$$PWD/qv4baselinejit_p.h \
- $$PWD/qv4assembler_p.h
+ $$PWD/qv4baselineassembler_p.h \
+ $$PWD/qv4assemblercommon_p.h
diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
new file mode 100644
index 0000000000..79a8237878
--- /dev/null
+++ b/src/qml/jit/qv4assemblercommon.cpp
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 <QBuffer>
+#include <QFile>
+
+#include "qv4engine_p.h"
+#include "qv4assemblercommon_p.h"
+#include <private/qv4function_p.h>
+#include <private/qv4runtime_p.h>
+
+#include <assembler/MacroAssemblerCodeRef.h>
+#include <assembler/LinkBuffer.h>
+#include <WTFStubs.h>
+
+#undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES
+
+#ifdef V4_ENABLE_JIT
+
+QT_BEGIN_NAMESPACE
+namespace QV4 {
+namespace JIT {
+
+namespace {
+class QIODevicePrintStream: public FilePrintStream
+{
+ Q_DISABLE_COPY(QIODevicePrintStream)
+
+public:
+ explicit QIODevicePrintStream(QIODevice *dest)
+ : FilePrintStream(nullptr)
+ , dest(dest)
+ , buf(4096, '0')
+ {
+ Q_ASSERT(dest);
+ }
+
+ ~QIODevicePrintStream()
+ {}
+
+ void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
+ {
+ const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
+ if (written > 0)
+ dest->write(buf.constData(), written);
+ memset(buf.data(), 0, qMin(written, buf.size()));
+ }
+
+ void flush()
+ {}
+
+private:
+ QIODevice *dest;
+ QByteArray buf;
+};
+} // anonymous namespace
+
+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 QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
+ int idx = 0;
+ while (idx >= 0) {
+ idx = processedOutput.indexOf(ptrString, idx);
+ if (idx < 0)
+ break;
+ idx = processedOutput.indexOf('\n', idx);
+ if (idx < 0)
+ break;
+ processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value());
+ }
+ }
+
+ qDebug("%s", processedOutput.constData());
+}
+
+static QByteArray functionName(Function *function)
+{
+ QByteArray name = function->name()->toQString().toUtf8();
+ if (name.isEmpty()) {
+ name = QByteArray::number(reinterpret_cast<quintptr>(function), 16);
+ name.prepend("QV4::Function(0x");
+ name.append(')');
+ }
+ return name;
+}
+
+JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon()
+{}
+
+void PlatformAssemblerCommon::link(Function *function)
+{
+ for (const auto &jumpTarget : jumpsToLink)
+ jumpTarget.jump.linkTo(labelForOffset[jumpTarget.offset], this);
+
+ JSC::JSGlobalData dummy(function->internalClass->engine->executableAllocator);
+ JSC::LinkBuffer<MacroAssembler> linkBuffer(dummy, this, nullptr);
+
+ for (const auto &ehTarget : ehTargets) {
+ auto targetLabel = labelForOffset.value(ehTarget.offset);
+ linkBuffer.patch(ehTarget.label, linkBuffer.locationOf(targetLabel));
+ }
+
+ JSC::MacroAssemblerCodeRef codeRef;
+
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
+ if (showCode) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ WTF::setDataFile(new QIODevicePrintStream(&buf));
+
+ QByteArray name = functionName(function);
+ codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.constData());
+
+ WTF::setDataFile(stderr);
+ printDisassembledOutputWithCalls(buf.data(), functions);
+ } else {
+ codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+ }
+
+ function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef);
+ function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress());
+
+ // This implements writing of JIT'd addresses so that perf can find the
+ // symbol names.
+ //
+ // Perf expects the mapping to be in a certain place and have certain
+ // content, for more information, see:
+ // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
+ static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
+ if (Q_UNLIKELY(doProfile)) {
+ static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map")
+ .arg(QCoreApplication::applicationPid()));
+ static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly);
+ if (!isOpen) {
+ qWarning("QV4::JIT::Assembler: Cannot write perf map file.");
+ doProfile = false;
+ } else {
+ perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(
+ codeRef.code().executableAddress()), 16));
+ perfMapFile.putChar(' ');
+ perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16));
+ perfMapFile.putChar(' ');
+ perfMapFile.write(functionName(function));
+ perfMapFile.putChar('\n');
+ perfMapFile.flush();
+ }
+ }
+}
+
+void PlatformAssemblerCommon::prepareCallWithArgCount(int argc)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(remainingArgcForCall == NoCall);
+ remainingArgcForCall = argc;
+#endif
+
+ if (argc > ArgInRegCount) {
+ argcOnStackForCall = int(WTF::roundUpToMultipleOf(16, size_t(argc - ArgInRegCount) * PointerSize));
+ subPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
+ }
+}
+
+void PlatformAssemblerCommon::storeInstructionPointer(int instructionOffset)
+{
+ Address addr(CppStackFrameRegister, offsetof(QV4::CppStackFrame, instructionPointer));
+ store32(TrustedImm32(instructionOffset), addr);
+}
+
+PlatformAssemblerCommon::Address PlatformAssemblerCommon::argStackAddress(int arg)
+{
+ int offset = arg - ArgInRegCount;
+ Q_ASSERT(offset >= 0);
+ return Address(StackPointerRegister, offset * PointerSize);
+}
+
+void PlatformAssemblerCommon::passAccumulatorAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ passAccumulatorAsArg_internal(arg, false);
+}
+
+void JIT::PlatformAssemblerCommon::pushAccumulatorAsArg(int arg)
+{
+ passAccumulatorAsArg_internal(arg, true);
+}
+
+void PlatformAssemblerCommon::passAccumulatorAsArg_internal(int arg, bool doPush)
+{
+ if (arg < ArgInRegCount) {
+ addPtr(TrustedImm32(offsetof(CallData, accumulator)), JSStackFrameRegister, registerForArg(arg));
+ } else {
+ addPtr(TrustedImm32(offsetof(CallData, accumulator)), JSStackFrameRegister, ScratchRegister);
+ if (doPush)
+ push(ScratchRegister);
+ else
+ storePtr(ScratchRegister, argStackAddress(arg));
+ }
+}
+
+void PlatformAssemblerCommon::passFunctionAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ if (arg < ArgInRegCount) {
+ loadFunctionPtr(registerForArg(arg));
+ } else {
+ loadFunctionPtr(ScratchRegister);
+ storePtr(ScratchRegister, argStackAddress(arg));
+ }
+}
+
+void PlatformAssemblerCommon::passEngineAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ if (arg < ArgInRegCount) {
+ move(EngineRegister, registerForArg(arg));
+ } else {
+ storePtr(EngineRegister, argStackAddress(arg));
+ }
+}
+
+void PlatformAssemblerCommon::passJSSlotAsArg(int reg, int arg)
+{
+ Address addr(JSStackFrameRegister, reg * int(sizeof(QV4::Value)));
+ passAddressAsArg(addr, arg);
+}
+
+void JIT::PlatformAssemblerCommon::passAddressAsArg(Address addr, int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ if (arg < ArgInRegCount) {
+ addPtr(TrustedImm32(addr.offset), addr.base, registerForArg(arg));
+ } else {
+ addPtr(TrustedImm32(addr.offset), addr.base, ScratchRegister);
+ storePtr(ScratchRegister, argStackAddress(arg));
+ }
+}
+
+void PlatformAssemblerCommon::passCppFrameAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ if (arg < ArgInRegCount)
+ move(CppStackFrameRegister, registerForArg(arg));
+ else
+ store32(CppStackFrameRegister, argStackAddress(arg));
+}
+
+void PlatformAssemblerCommon::passInt32AsArg(int value, int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ if (arg < ArgInRegCount)
+ move(TrustedImm32(value), registerForArg(arg));
+ else
+ store32(TrustedImm32(value), argStackAddress(arg));
+}
+
+void PlatformAssemblerCommon::callRuntime(const char *functionName, const void *funcPtr)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(remainingArgcForCall == 0);
+ remainingArgcForCall = NoCall;
+#endif
+ callRuntimeUnchecked(functionName, funcPtr);
+ if (argcOnStackForCall > 0) {
+ addPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
+ argcOnStackForCall = 0;
+ }
+}
+
+void JIT::PlatformAssemblerCommon::callRuntimeUnchecked(const char *functionName, const void *funcPtr)
+{
+ functions.insert(funcPtr, functionName);
+ callAbsolute(funcPtr);
+}
+
+} // JIT namespace
+} // QV4 namepsace
+
+QT_END_NAMESPACE
+
+#endif // V4_ENABLE_JIT
diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h
new file mode 100644
index 0000000000..a48d6fae44
--- /dev/null
+++ b/src/qml/jit/qv4assemblercommon_p.h
@@ -0,0 +1,697 @@
+/****************************************************************************
+**
+** 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 QV4PLATFORMASSEMBLER_P_H
+#define QV4PLATFORMASSEMBLER_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/qv4engine_p.h>
+#include <private/qv4global_p.h>
+#include <private/qv4function_p.h>
+#include <QHash>
+#include <wtf/Vector.h>
+#include <assembler/MacroAssembler.h>
+
+#ifdef V4_ENABLE_JIT
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+namespace JIT {
+
+#if defined(Q_PROCESSOR_X86_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+#if defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD) || defined(Q_OS_DARWIN)
+
+class PlatformAssembler_X86_64_SysV : public JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
+{
+public:
+ static constexpr int NativeStackAlignment = 16;
+
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = RegisterID::eax;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg5Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = RegisterID::r12;
+ static const RegisterID CppStackFrameRegister = RegisterID::r13;
+ static const RegisterID EngineRegister = RegisterID::r14;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+ static const FPRegisterID FPScratchRegister2 = FPRegisterID::xmm2;
+
+ static const RegisterID Arg0Reg = RegisterID::edi;
+ static const RegisterID Arg1Reg = RegisterID::esi;
+ static const RegisterID Arg2Reg = RegisterID::edx;
+ static const RegisterID Arg3Reg = RegisterID::ecx;
+ static const RegisterID Arg4Reg = RegisterID::r8;
+ static const RegisterID Arg5Reg = RegisterID::r9;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 6;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ push(FramePointerRegister);
+ move(StackPointerRegister, FramePointerRegister);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(FramePointerRegister);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler_X86_64_SysV PlatformAssemblerBase;
+
+#endif
+#if defined(Q_OS_WIN)
+
+class PlatformAssembler_Win64 : public JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
+{
+public:
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = RegisterID::eax;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg3Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = RegisterID::r12;
+ static const RegisterID CppStackFrameRegister = RegisterID::r13;
+ static const RegisterID EngineRegister = RegisterID::r14;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+
+ static const RegisterID Arg0Reg = RegisterID::ecx;
+ static const RegisterID Arg1Reg = RegisterID::edx;
+ static const RegisterID Arg2Reg = RegisterID::r8;
+ static const RegisterID Arg3Reg = RegisterID::r9;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 4;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ push(FramePointerRegister);
+ move(StackPointerRegister, FramePointerRegister);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(FramePointerRegister);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ subPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
+ call(ScratchRegister);
+ addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler_Win64 PlatformAssemblerBase;
+
+#endif
+#endif
+
+#if (defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_X86_64)) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+
+class PlatformAssembler_X86_All : public JSC::MacroAssembler<JSC::MacroAssemblerX86>
+{
+public:
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegisterValue = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterTag = RegisterID::edx;
+ static const RegisterID ScratchRegister = RegisterID::ecx;
+ static const RegisterID AccumulatorRegisterValue = ReturnValueRegisterValue;
+ static const RegisterID AccumulatorRegisterTag = ReturnValueRegisterTag;
+ static const RegisterID JSStackFrameRegister = RegisterID::ebx;
+ static const RegisterID CppStackFrameRegister = RegisterID::esi;
+ static const RegisterID EngineRegister = RegisterID::edi;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+
+ static const RegisterID Arg0Reg = NoRegister;
+ static const RegisterID Arg1Reg = NoRegister;
+ static const RegisterID Arg2Reg = NoRegister;
+ static const RegisterID Arg3Reg = NoRegister;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 0;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ push(RegisterID::ebp);
+ move(RegisterID::esp, RegisterID::ebp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegisterValue); push(AccumulatorRegisterValue); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ // Ensure the stack is 16-byte aligned in order for compiler generated aligned SSE2
+ // instructions to be able to target the stack.
+ subPtr(TrustedImm32(8), StackPointerRegister);
+ loadPtr(Address(FramePointerRegister, 2 * PointerSize), CppStackFrameRegister);
+ loadPtr(Address(FramePointerRegister, 3 * PointerSize), EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ addPtr(TrustedImm32(8), StackPointerRegister);
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(RegisterID::ebp);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler_X86_All PlatformAssemblerBase;
+
+#endif
+
+#if defined(Q_PROCESSOR_ARM_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+
+class PlatformAssembler_ARM64 : public JSC::MacroAssembler<JSC::MacroAssemblerARM64>
+{
+public:
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
+ static const RegisterID ScratchRegister2 = JSC::ARM64Registers::x7; // Note: overlaps with Arg7Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = JSC::ARM64Registers::x19;
+ static const RegisterID CppStackFrameRegister = JSC::ARM64Registers::x20;
+ static const RegisterID EngineRegister = JSC::ARM64Registers::x21;
+ static const RegisterID StackPointerRegister = JSC::ARM64Registers::sp;
+ static const RegisterID FramePointerRegister = JSC::ARM64Registers::fp;
+ static const FPRegisterID FPScratchRegister = JSC::ARM64Registers::q1;
+
+ static const RegisterID Arg0Reg = JSC::ARM64Registers::x0;
+ static const RegisterID Arg1Reg = JSC::ARM64Registers::x1;
+ static const RegisterID Arg2Reg = JSC::ARM64Registers::x2;
+ static const RegisterID Arg3Reg = JSC::ARM64Registers::x3;
+ static const RegisterID Arg4Reg = JSC::ARM64Registers::x4;
+ static const RegisterID Arg5Reg = JSC::ARM64Registers::x5;
+ static const RegisterID Arg6Reg = JSC::ARM64Registers::x6;
+ static const RegisterID Arg7Reg = JSC::ARM64Registers::x7;
+ static const int ArgInRegCount = 8;
+
+ void push(RegisterID src)
+ {
+ pushToSave(src);
+ }
+
+ void pop(RegisterID dest)
+ {
+ popToRestore(dest);
+ }
+
+ void pop()
+ {
+ add64(TrustedImm32(16), stackPointerRegister);
+ }
+
+ void popValue()
+ {
+ pop();
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ pushPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
+ move(RegisterID::sp, RegisterID::fp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); // exceptionHandler
+ pushPair(JSStackFrameRegister, AccumulatorRegister);
+ pushPair(EngineRegister, CppStackFrameRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ move(AccumulatorRegister, ReturnValueRegister);
+ popPair(EngineRegister, CppStackFrameRegister);
+ popPair(JSStackFrameRegister, AccumulatorRegister);
+ popPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ pushToSave(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ popToRestore(reg);
+ }
+};
+
+typedef PlatformAssembler_ARM64 PlatformAssemblerBase;
+
+#endif
+
+#if defined(Q_PROCESSOR_ARM_32) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+
+class PlatformAssembler_ARM32 : public JSC::MacroAssembler<JSC::MacroAssemblerARMv7>
+{
+public:
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegisterValue = JSC::ARMRegisters::r0;
+ static const RegisterID ReturnValueRegisterTag = JSC::ARMRegisters::r1;
+ static const RegisterID ScratchRegister = JSC::ARMRegisters::r2;
+ static const RegisterID AccumulatorRegisterValue = JSC::ARMRegisters::r4;
+ static const RegisterID AccumulatorRegisterTag = JSC::ARMRegisters::r5;
+ // r6 is used by MacroAssemblerARMv7
+ static const RegisterID JSStackFrameRegister = JSC::ARMRegisters::r8;
+ static const RegisterID CppStackFrameRegister = JSC::ARMRegisters::r10;
+#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
+ static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
+ static const RegisterID EngineRegister = JSC::ARMRegisters::r11;
+#else // Thumbs down
+ static const RegisterID FramePointerRegister = JSC::ARMRegisters::r11;
+ static const RegisterID EngineRegister = JSC::ARMRegisters::r7;
+#endif
+ static const RegisterID StackPointerRegister = JSC::ARMRegisters::r13;
+ static const FPRegisterID FPScratchRegister = JSC::ARMRegisters::d1;
+
+ static const RegisterID Arg0Reg = JSC::ARMRegisters::r0;
+ static const RegisterID Arg1Reg = JSC::ARMRegisters::r1;
+ static const RegisterID Arg2Reg = JSC::ARMRegisters::r2;
+ static const RegisterID Arg3Reg = JSC::ARMRegisters::r3;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 4;
+
+ void popValue()
+ {
+ addPtr(TrustedImm32(sizeof(ReturnedValue)), StackPointerRegister);
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ push(JSC::ARMRegisters::lr);
+ push(FramePointerRegister);
+ move(StackPointerRegister, FramePointerRegister);
+ push(TrustedImm32(0)); // exceptionHandler
+ push(AccumulatorRegisterValue);
+ push(AccumulatorRegisterTag);
+ push(addressTempRegister);
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ subPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ move(AccumulatorRegisterValue, ReturnValueRegisterValue);
+ move(AccumulatorRegisterTag, ReturnValueRegisterTag);
+ addPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(addressTempRegister);
+ pop(AccumulatorRegisterTag);
+ pop(AccumulatorRegisterValue);
+ pop(); // exceptionHandler
+ pop(FramePointerRegister);
+ pop(JSC::ARMRegisters::lr);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), dataTempRegister);
+ call(dataTempRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler_ARM32 PlatformAssemblerBase;
+#endif
+
+class PlatformAssemblerCommon : public JIT::PlatformAssemblerBase
+{
+public:
+ PlatformAssemblerCommon(const Value *constantTable)
+ : constantTable(constantTable)
+ {}
+
+ virtual ~PlatformAssemblerCommon();
+
+ Address exceptionHandlerAddress() const
+ {
+ return Address(FramePointerRegister, -1 * PointerSize);
+ }
+
+ Address contextAddress() const
+ {
+ return Address(JSStackFrameRegister, offsetof(CallData, context));
+ }
+
+ RegisterID registerForArg(int arg) const
+ {
+ Q_ASSERT(arg >= 0);
+ Q_ASSERT(arg < ArgInRegCount);
+ switch (arg) {
+ case 0: return Arg0Reg;
+ case 1: return Arg1Reg;
+ case 2: return Arg2Reg;
+ case 3: return Arg3Reg;
+ case 4: return Arg4Reg;
+ case 5: return Arg5Reg;
+ case 6: return Arg6Reg;
+ case 7: return Arg7Reg;
+ default:
+ Q_UNIMPLEMENTED();
+ Q_UNREACHABLE();
+ }
+ }
+
+ Address loadFunctionPtr(RegisterID target)
+ {
+ Address addr(CppStackFrameRegister, offsetof(CppStackFrame, v4Function));
+ loadPtr(addr, target);
+ return Address(target);
+ }
+
+ Address loadCompilationUnitPtr(RegisterID target)
+ {
+ Address addr = loadFunctionPtr(target);
+ addr.offset = offsetof(QV4::Function, compilationUnit);
+ loadPtr(addr, target);
+ return Address(target);
+ }
+
+ Address loadConstAddress(int constIndex, RegisterID baseReg = ScratchRegister)
+ {
+ Address addr = loadCompilationUnitPtr(baseReg);
+ addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, constants);
+ loadPtr(addr, baseReg);
+ addr.offset = constIndex * int(sizeof(QV4::Value));
+ return addr;
+ }
+
+ Address loadStringAddress(int stringId)
+ {
+ Address addr = loadCompilationUnitPtr(ScratchRegister);
+ addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, runtimeStrings);
+ loadPtr(addr, ScratchRegister);
+ return Address(ScratchRegister, stringId * PointerSize);
+ }
+
+ void passAsArg(RegisterID src, int arg)
+ {
+ move(src, registerForArg(arg));
+ }
+
+ void generateCatchTrampoline(std::function<void()> loadUndefined)
+ {
+ for (Jump j : catchyJumps)
+ j.link(this);
+
+ loadPtr(exceptionHandlerAddress(), ScratchRegister);
+ Jump exitFunction = branchPtr(Equal, ScratchRegister, TrustedImmPtr(0));
+ jump(ScratchRegister);
+ exitFunction.link(this);
+ loadUndefined();
+
+ if (functionExit.isSet())
+ jump(functionExit);
+ else
+ generateFunctionExit();
+ }
+
+ void checkException()
+ {
+ addCatchyJump(
+ branch32(NotEqual,
+ Address(EngineRegister, offsetof(EngineBase, hasException)),
+ TrustedImm32(0)));
+ }
+
+ void addCatchyJump(Jump j)
+ {
+ Q_ASSERT(j.isSet());
+ catchyJumps.push_back(j);
+ }
+
+ void generateFunctionEntry()
+ {
+ generatePlatformFunctionEntry();
+ loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
+ allocateStackSpace();
+ }
+
+ virtual void allocateStackSpace() {}
+
+ void generateFunctionExit()
+ {
+ if (functionExit.isSet()) {
+ jump(functionExit);
+ return;
+ }
+
+ functionExit = label();
+ freeStackSpace();
+ generatePlatformFunctionExit();
+ }
+
+ virtual void freeStackSpace() {}
+
+ void addLabelForOffset(int offset)
+ {
+ labelForOffset.insert(offset, label());
+ }
+
+ void addJumpToOffset(const Jump &jump, int offset)
+ {
+ jumpsToLink.push_back({ jump, offset });
+ }
+
+ void addEHTarget(const DataLabelPtr &label, int offset)
+ {
+ ehTargets.push_back({ label, offset });
+ }
+
+ void link(Function *function);
+
+ Value constant(int idx) const
+ { return constantTable[idx]; }
+
+ // stuff for runtime calls
+ void prepareCallWithArgCount(int argc);
+ void storeInstructionPointer(int instructionOffset);
+ void passAccumulatorAsArg(int arg);
+ void pushAccumulatorAsArg(int arg);
+ void passFunctionAsArg(int arg);
+ void passEngineAsArg(int arg);
+ void passJSSlotAsArg(int reg, int arg);
+ void passAddressAsArg(Address addr, int arg);
+ void passCppFrameAsArg(int arg);
+ void passInt32AsArg(int value, int arg);
+ void callRuntime(const char *functionName, const void *funcPtr);
+ void callRuntimeUnchecked(const char *functionName, const void *funcPtr);
+
+
+private:
+ void passAccumulatorAsArg_internal(int arg, bool doPush);
+ static Address argStackAddress(int arg);
+
+private:
+ const Value* constantTable;
+ struct JumpTarget { JSC::MacroAssemblerBase::Jump jump; int offset; };
+ std::vector<JumpTarget> jumpsToLink;
+ struct ExceptionHanlderTarget { JSC::MacroAssemblerBase::DataLabelPtr label; int offset; };
+ std::vector<ExceptionHanlderTarget> ehTargets;
+ QHash<int, JSC::MacroAssemblerBase::Label> labelForOffset;
+ QHash<const void *, const char *> functions;
+ std::vector<Jump> catchyJumps;
+ Label functionExit;
+
+#ifndef QT_NO_DEBUG
+ enum { NoCall = -1 };
+ int remainingArgcForCall = NoCall;
+#endif
+ int argcOnStackForCall = 0;
+};
+
+} // JIT namespace
+} // QV4 namespace
+
+QT_END_NAMESPACE
+
+#endif // V4_ENABLE_JIT
+
+#endif // QV4PLATFORMASSEMBLER_P_H
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 3379d9a0e4..c7d8f3c72c 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -41,7 +41,8 @@
#include <QFile>
#include "qv4engine_p.h"
-#include "qv4assembler_p.h"
+#include "qv4baselineassembler_p.h"
+#include "qv4assemblercommon_p.h"
#include <private/qv4function_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4stackframe_p.h>
@@ -60,7 +61,9 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {
-#define callHelper(x) PlatformAssemblerCommon::callRuntime(#x, reinterpret_cast<void *>(&x))
+#define ASM_GENERATE_RUNTIME_CALL(function, destination) \
+ pasm()->GENERATE_RUNTIME_CALL(function, destination)
+#define callHelper(x) PlatformAssemblerCommon::callRuntimeUnchecked(#x, reinterpret_cast<void *>(&x))
const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
@@ -74,568 +77,19 @@ static ReturnedValue toInt32Helper(ReturnedValue v)
return Encode(Value::fromReturnedValue(v).toInt32());
}
-#if defined(Q_PROCESSOR_X86_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-#if defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD) || defined(Q_OS_DARWIN)
-
-struct PlatformAssembler_X86_64_SysV : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
-{
- static const RegisterID NoRegister = RegisterID(-1);
-
- static const RegisterID ReturnValueRegister = RegisterID::eax;
- static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
- static const RegisterID AccumulatorRegister = RegisterID::eax;
- static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
- static const RegisterID ScratchRegister = RegisterID::r10;
- static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg5Reg, so do not use while setting up a call!
- static const RegisterID JSStackFrameRegister = RegisterID::r12;
- static const RegisterID CppStackFrameRegister = RegisterID::r13;
- static const RegisterID EngineRegister = RegisterID::r14;
- static const RegisterID StackPointerRegister = RegisterID::esp;
- static const RegisterID FramePointerRegister = RegisterID::ebp;
- static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
-
- static const RegisterID Arg0Reg = RegisterID::edi;
- static const RegisterID Arg1Reg = RegisterID::esi;
- static const RegisterID Arg2Reg = RegisterID::edx;
- static const RegisterID Arg3Reg = RegisterID::ecx;
- static const RegisterID Arg4Reg = RegisterID::r8;
- static const RegisterID Arg5Reg = RegisterID::r9;
- static const RegisterID Arg6Reg = NoRegister;
- static const RegisterID Arg7Reg = NoRegister;
- static const int ArgInRegCount = 6;
-
- void popValue()
- {
- addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
- }
-
- void generatePlatformFunctionEntry()
- {
- push(RegisterID::ebp);
- move(RegisterID::esp, RegisterID::ebp);
- move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
- push(JSStackFrameRegister);
- push(CppStackFrameRegister);
- push(EngineRegister);
- move(Arg0Reg, CppStackFrameRegister);
- move(Arg1Reg, EngineRegister);
- }
-
- void generatePlatformFunctionExit()
- {
- pop(EngineRegister);
- pop(CppStackFrameRegister);
- pop(JSStackFrameRegister);
- pop(); // exceptionHandler
- pop(RegisterID::ebp);
- ret();
- }
-
- void callAbsolute(const void *funcPtr)
- {
- move(TrustedImmPtr(funcPtr), ScratchRegister);
- call(ScratchRegister);
- }
-
- void pushAligned(RegisterID reg)
- {
- subPtr(TrustedImm32(PointerSize), StackPointerRegister);
- push(reg);
- }
-
- void popAligned(RegisterID reg)
- {
- pop(reg);
- addPtr(TrustedImm32(PointerSize), StackPointerRegister);
- }
-};
-
-typedef PlatformAssembler_X86_64_SysV PlatformAssemblerBase;
-
-#endif
-#if defined(Q_OS_WIN)
-
-struct PlatformAssembler_Win64 : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
-{
- static const RegisterID NoRegister = RegisterID(-1);
-
- static const RegisterID ReturnValueRegister = RegisterID::eax;
- static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
- static const RegisterID AccumulatorRegister = RegisterID::eax;
- static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
- static const RegisterID ScratchRegister = RegisterID::r10;
- static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg3Reg, so do not use while setting up a call!
- static const RegisterID JSStackFrameRegister = RegisterID::r12;
- static const RegisterID CppStackFrameRegister = RegisterID::r13;
- static const RegisterID EngineRegister = RegisterID::r14;
- static const RegisterID StackPointerRegister = RegisterID::esp;
- static const RegisterID FramePointerRegister = RegisterID::ebp;
- static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
-
- static const RegisterID Arg0Reg = RegisterID::ecx;
- static const RegisterID Arg1Reg = RegisterID::edx;
- static const RegisterID Arg2Reg = RegisterID::r8;
- static const RegisterID Arg3Reg = RegisterID::r9;
- static const RegisterID Arg4Reg = NoRegister;
- static const RegisterID Arg5Reg = NoRegister;
- static const RegisterID Arg6Reg = NoRegister;
- static const RegisterID Arg7Reg = NoRegister;
- static const int ArgInRegCount = 4;
-
- void popValue()
- {
- addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
- }
-
- void generatePlatformFunctionEntry()
- {
- push(RegisterID::ebp);
- move(RegisterID::esp, RegisterID::ebp);
- move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
- push(JSStackFrameRegister);
- push(CppStackFrameRegister);
- push(EngineRegister);
- move(Arg0Reg, CppStackFrameRegister);
- move(Arg1Reg, EngineRegister);
- }
-
- void generatePlatformFunctionExit()
- {
- pop(EngineRegister);
- pop(CppStackFrameRegister);
- pop(JSStackFrameRegister);
- pop(); // exceptionHandler
- pop(RegisterID::ebp);
- ret();
- }
-
- void callAbsolute(const void *funcPtr)
- {
- move(TrustedImmPtr(funcPtr), ScratchRegister);
- subPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
- call(ScratchRegister);
- addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
- }
-
- void pushAligned(RegisterID reg)
- {
- subPtr(TrustedImm32(PointerSize), StackPointerRegister);
- push(reg);
- }
-
- void popAligned(RegisterID reg)
- {
- pop(reg);
- addPtr(TrustedImm32(PointerSize), StackPointerRegister);
- }
-};
-
-typedef PlatformAssembler_Win64 PlatformAssemblerBase;
-
-#endif
-#endif
-
-#if (defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_X86_64)) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-
-struct PlatformAssembler_X86_All : JSC::MacroAssembler<JSC::MacroAssemblerX86>
-{
- static const RegisterID NoRegister = RegisterID(-1);
-
- static const RegisterID ReturnValueRegisterValue = RegisterID::eax;
- static const RegisterID ReturnValueRegisterTag = RegisterID::edx;
- static const RegisterID ScratchRegister = RegisterID::ecx;
- static const RegisterID AccumulatorRegisterValue = ReturnValueRegisterValue;
- static const RegisterID AccumulatorRegisterTag = ReturnValueRegisterTag;
- static const RegisterID JSStackFrameRegister = RegisterID::ebx;
- static const RegisterID CppStackFrameRegister = RegisterID::esi;
- static const RegisterID EngineRegister = RegisterID::edi;
- static const RegisterID StackPointerRegister = RegisterID::esp;
- static const RegisterID FramePointerRegister = RegisterID::ebp;
- static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
-
- static const RegisterID Arg0Reg = NoRegister;
- static const RegisterID Arg1Reg = NoRegister;
- static const RegisterID Arg2Reg = NoRegister;
- static const RegisterID Arg3Reg = NoRegister;
- static const RegisterID Arg4Reg = NoRegister;
- static const RegisterID Arg5Reg = NoRegister;
- static const RegisterID Arg6Reg = NoRegister;
- static const RegisterID Arg7Reg = NoRegister;
- static const int ArgInRegCount = 0;
-
- void popValue()
- {
- addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
- }
-
- void generatePlatformFunctionEntry()
- {
- push(RegisterID::ebp);
- move(RegisterID::esp, RegisterID::ebp);
- move(TrustedImmPtr(nullptr), AccumulatorRegisterValue); push(AccumulatorRegisterValue); // exceptionHandler
- push(JSStackFrameRegister);
- push(CppStackFrameRegister);
- push(EngineRegister);
- // Ensure the stack is 16-byte aligned in order for compiler generated aligned SSE2
- // instructions to be able to target the stack.
- subPtr(TrustedImm32(8), StackPointerRegister);
- loadPtr(Address(FramePointerRegister, 2 * PointerSize), CppStackFrameRegister);
- loadPtr(Address(FramePointerRegister, 3 * PointerSize), EngineRegister);
- }
-
- void generatePlatformFunctionExit()
- {
- addPtr(TrustedImm32(8), StackPointerRegister);
- pop(EngineRegister);
- pop(CppStackFrameRegister);
- pop(JSStackFrameRegister);
- pop(); // exceptionHandler
- pop(RegisterID::ebp);
- ret();
- }
-
- void callAbsolute(const void *funcPtr)
- {
- move(TrustedImmPtr(funcPtr), ScratchRegister);
- call(ScratchRegister);
- }
-
- void pushAligned(RegisterID reg)
- {
- subPtr(TrustedImm32(PointerSize), StackPointerRegister);
- push(reg);
- }
-
- void popAligned(RegisterID reg)
- {
- pop(reg);
- addPtr(TrustedImm32(PointerSize), StackPointerRegister);
- }
-};
-
-typedef PlatformAssembler_X86_All PlatformAssemblerBase;
-
-#endif
-
-#if defined(Q_PROCESSOR_ARM_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-
-struct PlatformAssembler_ARM64 : JSC::MacroAssembler<JSC::MacroAssemblerARM64>
-{
- static const RegisterID NoRegister = RegisterID(-1);
-
- static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
- static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
- static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
- static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
- static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
- static const RegisterID ScratchRegister2 = JSC::ARM64Registers::x7; // Note: overlaps with Arg7Reg, so do not use while setting up a call!
- static const RegisterID JSStackFrameRegister = JSC::ARM64Registers::x19;
- static const RegisterID CppStackFrameRegister = JSC::ARM64Registers::x20;
- static const RegisterID EngineRegister = JSC::ARM64Registers::x21;
- static const RegisterID StackPointerRegister = JSC::ARM64Registers::sp;
- static const RegisterID FramePointerRegister = JSC::ARM64Registers::fp;
- static const FPRegisterID FPScratchRegister = JSC::ARM64Registers::q1;
-
- static const RegisterID Arg0Reg = JSC::ARM64Registers::x0;
- static const RegisterID Arg1Reg = JSC::ARM64Registers::x1;
- static const RegisterID Arg2Reg = JSC::ARM64Registers::x2;
- static const RegisterID Arg3Reg = JSC::ARM64Registers::x3;
- static const RegisterID Arg4Reg = JSC::ARM64Registers::x4;
- static const RegisterID Arg5Reg = JSC::ARM64Registers::x5;
- static const RegisterID Arg6Reg = JSC::ARM64Registers::x6;
- static const RegisterID Arg7Reg = JSC::ARM64Registers::x7;
- static const int ArgInRegCount = 8;
-
- void push(RegisterID src)
- {
- pushToSave(src);
- }
-
- void pop(RegisterID dest)
- {
- popToRestore(dest);
- }
-
- void pop()
- {
- add64(TrustedImm32(16), stackPointerRegister);
- }
-
- void popValue()
- {
- pop();
- }
-
- void generatePlatformFunctionEntry()
- {
- pushPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
- move(RegisterID::sp, RegisterID::fp);
- move(TrustedImmPtr(nullptr), AccumulatorRegister); // exceptionHandler
- pushPair(JSStackFrameRegister, AccumulatorRegister);
- pushPair(EngineRegister, CppStackFrameRegister);
- move(Arg0Reg, CppStackFrameRegister);
- move(Arg1Reg, EngineRegister);
- }
-
- void generatePlatformFunctionExit()
- {
- move(AccumulatorRegister, ReturnValueRegister);
- popPair(EngineRegister, CppStackFrameRegister);
- popPair(JSStackFrameRegister, AccumulatorRegister);
- popPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
- ret();
- }
-
- void callAbsolute(const void *funcPtr)
- {
- move(TrustedImmPtr(funcPtr), ScratchRegister);
- call(ScratchRegister);
- }
-
- void pushAligned(RegisterID reg)
- {
- pushToSave(reg);
- }
-
- void popAligned(RegisterID reg)
- {
- popToRestore(reg);
- }
-};
-
-typedef PlatformAssembler_ARM64 PlatformAssemblerBase;
-
-#endif
-
-#if defined(Q_PROCESSOR_ARM_32) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-
-struct PlatformAssembler_ARM32 : JSC::MacroAssembler<JSC::MacroAssemblerARMv7>
-{
- static const RegisterID NoRegister = RegisterID(-1);
-
- static const RegisterID ReturnValueRegisterValue = JSC::ARMRegisters::r0;
- static const RegisterID ReturnValueRegisterTag = JSC::ARMRegisters::r1;
- static const RegisterID ScratchRegister = JSC::ARMRegisters::r2;
- static const RegisterID AccumulatorRegisterValue = JSC::ARMRegisters::r4;
- static const RegisterID AccumulatorRegisterTag = JSC::ARMRegisters::r5;
- // r6 is used by MacroAssemblerARMv7
- static const RegisterID JSStackFrameRegister = JSC::ARMRegisters::r8;
- static const RegisterID CppStackFrameRegister = JSC::ARMRegisters::r10;
-#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
- static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
- static const RegisterID EngineRegister = JSC::ARMRegisters::r11;
-#else // Thumbs down
- static const RegisterID FramePointerRegister = JSC::ARMRegisters::r11;
- static const RegisterID EngineRegister = JSC::ARMRegisters::r7;
-#endif
- static const RegisterID StackPointerRegister = JSC::ARMRegisters::r13;
- static const FPRegisterID FPScratchRegister = JSC::ARMRegisters::d1;
-
- static const RegisterID Arg0Reg = JSC::ARMRegisters::r0;
- static const RegisterID Arg1Reg = JSC::ARMRegisters::r1;
- static const RegisterID Arg2Reg = JSC::ARMRegisters::r2;
- static const RegisterID Arg3Reg = JSC::ARMRegisters::r3;
- static const RegisterID Arg4Reg = NoRegister;
- static const RegisterID Arg5Reg = NoRegister;
- static const RegisterID Arg6Reg = NoRegister;
- static const RegisterID Arg7Reg = NoRegister;
- static const int ArgInRegCount = 4;
-
- void popValue()
- {
- addPtr(TrustedImm32(sizeof(ReturnedValue)), StackPointerRegister);
- }
-
- void generatePlatformFunctionEntry()
- {
- push(JSC::ARMRegisters::lr);
- push(FramePointerRegister);
- move(StackPointerRegister, FramePointerRegister);
- push(TrustedImm32(0)); // exceptionHandler
- push(AccumulatorRegisterValue);
- push(AccumulatorRegisterTag);
- push(addressTempRegister);
- push(JSStackFrameRegister);
- push(CppStackFrameRegister);
- push(EngineRegister);
- subPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
- move(Arg0Reg, CppStackFrameRegister);
- move(Arg1Reg, EngineRegister);
- }
-
- void generatePlatformFunctionExit()
- {
- move(AccumulatorRegisterValue, ReturnValueRegisterValue);
- move(AccumulatorRegisterTag, ReturnValueRegisterTag);
- addPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
- pop(EngineRegister);
- pop(CppStackFrameRegister);
- pop(JSStackFrameRegister);
- pop(addressTempRegister);
- pop(AccumulatorRegisterTag);
- pop(AccumulatorRegisterValue);
- pop(); // exceptionHandler
- pop(FramePointerRegister);
- pop(JSC::ARMRegisters::lr);
- ret();
- }
-
- void callAbsolute(const void *funcPtr)
- {
- move(TrustedImmPtr(funcPtr), dataTempRegister);
- call(dataTempRegister);
- }
-
- void pushAligned(RegisterID reg)
- {
- subPtr(TrustedImm32(PointerSize), StackPointerRegister);
- push(reg);
- }
-
- void popAligned(RegisterID reg)
- {
- pop(reg);
- addPtr(TrustedImm32(PointerSize), StackPointerRegister);
- }
-};
-
-typedef PlatformAssembler_ARM32 PlatformAssemblerBase;
-
-#endif
-
-struct PlatformAssemblerCommon : PlatformAssemblerBase
-{
- const Value* constantTable;
- struct JumpTarget { JSC::MacroAssemblerBase::Jump jump; int offset; };
- std::vector<JumpTarget> patches;
- struct ExceptionHanlderTarget { JSC::MacroAssemblerBase::DataLabelPtr label; int offset; };
- std::vector<ExceptionHanlderTarget> ehTargets;
- QHash<int, JSC::MacroAssemblerBase::Label> labelsByOffset;
- QHash<const void *, const char *> functions;
- std::vector<Jump> catchyJumps;
- Label functionExit;
-
- Address exceptionHandlerAddress() const
- {
- return Address(FramePointerRegister, -1 * PointerSize);
- }
-
- Address contextAddress() const
- {
- return Address(JSStackFrameRegister, offsetof(CallData, context));
- }
-
- RegisterID registerForArg(int arg) const
- {
- Q_ASSERT(arg >= 0);
- Q_ASSERT(arg < ArgInRegCount);
- switch (arg) {
- case 0: return Arg0Reg;
- case 1: return Arg1Reg;
- case 2: return Arg2Reg;
- case 3: return Arg3Reg;
- case 4: return Arg4Reg;
- case 5: return Arg5Reg;
- case 6: return Arg6Reg;
- case 7: return Arg7Reg;
- default:
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
- }
- }
-
- void callRuntime(const char *functionName, const void *funcPtr)
- {
- functions.insert(funcPtr, functionName);
- callAbsolute(funcPtr);
- }
-
- Address loadFunctionPtr(RegisterID target)
- {
- Address addr(CppStackFrameRegister, offsetof(CppStackFrame, v4Function));
- loadPtr(addr, target);
- return Address(target);
- }
-
- Address loadCompilationUnitPtr(RegisterID target)
- {
- Address addr = loadFunctionPtr(target);
- addr.offset = offsetof(QV4::Function, compilationUnit);
- loadPtr(addr, target);
- return Address(target);
- }
-
- Address loadConstAddress(int constIndex, RegisterID baseReg = ScratchRegister)
- {
- Address addr = loadCompilationUnitPtr(baseReg);
- addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, constants);
- loadPtr(addr, baseReg);
- addr.offset = constIndex * int(sizeof(QV4::Value));
- return addr;
- }
-
- Address loadStringAddress(int stringId)
- {
- Address addr = loadCompilationUnitPtr(ScratchRegister);
- addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, runtimeStrings);
- loadPtr(addr, ScratchRegister);
- return Address(ScratchRegister, stringId * PointerSize);
- }
-
- void passAsArg(RegisterID src, int arg)
- {
- move(src, registerForArg(arg));
- }
-
- void generateCatchTrampoline(std::function<void()> loadUndefined)
- {
- for (Jump j : catchyJumps)
- j.link(this);
-
- loadPtr(exceptionHandlerAddress(), ScratchRegister);
- Jump exitFunction = branchPtr(Equal, ScratchRegister, TrustedImmPtr(0));
- jump(ScratchRegister);
- exitFunction.link(this);
- loadUndefined();
-
- if (functionExit.isSet())
- jump(functionExit);
- else
- generateFunctionExit();
- }
-
- void addCatchyJump(Jump j)
- {
- Q_ASSERT(j.isSet());
- catchyJumps.push_back(j);
- }
-
- void generateFunctionEntry()
- {
- generatePlatformFunctionEntry();
- loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
- }
-
- void generateFunctionExit()
- {
- if (functionExit.isSet()) {
- jump(functionExit);
- return;
- }
-
- functionExit = label();
- generatePlatformFunctionExit();
- }
-};
-
#if QT_POINTER_SIZE == 8 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-struct PlatformAssembler64 : PlatformAssemblerCommon
+class PlatformAssembler64 : public PlatformAssemblerCommon
{
+public:
+ PlatformAssembler64(const Value *constantTable)
+ : PlatformAssemblerCommon(constantTable)
+ {}
+
void callRuntime(const char *functionName, const void *funcPtr,
- Assembler::CallResultDestination dest)
+ CallResultDestination dest)
{
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
- if (dest == Assembler::ResultInAccumulator)
+ if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -652,7 +106,7 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
void copyConst(int constIndex, Address dest)
{
//###
- if (constantTable[constIndex].isUndefined()) {
+ if (constant(constIndex).isUndefined()) {
loadUndefined(ScratchRegister);
} else {
load64(loadConstAddress(constIndex, ScratchRegister), ScratchRegister);
@@ -710,7 +164,7 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
void jumpNotUndefined(int offset)
{
auto jump = branch64(NotEqual, AccumulatorRegister, TrustedImm64(0));
- patches.push_back({ jump, offset });
+ addJumpToOffset(jump, offset);
}
Jump jumpEmpty()
@@ -780,8 +234,8 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
move(AccumulatorRegister, registerForArg(0));
- callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
- Assembler::ResultInAccumulator);
+ callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ saveReturnValueInAccumulator();
isInt.link(this);
}
@@ -821,6 +275,26 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
return branch32(Equal, TrustedImm32(3), ScratchRegister);
}
+ void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load64(lhsAddr, ScratchRegister);
+ Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
+ Jump equal = branch32(Equal, TrustedImm32(rhs), ScratchRegister);
+ addJumpToOffset(equal, offset);
+ isUndef.link(this);
+ }
+
+ void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load64(lhsAddr, ScratchRegister);
+ Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
+ addJumpToOffset(isUndef, offset);
+ Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
+ addJumpToOffset(notEqual, offset);
+ }
+
void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
{
if (sourceReg == NoRegister)
@@ -896,13 +370,18 @@ typedef PlatformAssembler64 PlatformAssembler;
#endif
#if QT_POINTER_SIZE == 4 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-struct PlatformAssembler32 : PlatformAssemblerCommon
+class PlatformAssembler32 : public PlatformAssemblerCommon
{
+public:
+ PlatformAssembler32(const Value *constantTable)
+ : PlatformAssemblerCommon(constantTable)
+ {}
+
void callRuntime(const char *functionName, const void *funcPtr,
- Assembler::CallResultDestination dest)
+ CallResultDestination dest)
{
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
- if (dest == Assembler::ResultInAccumulator)
+ if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -921,7 +400,7 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
void copyConst(int constIndex, Address destRegAddr)
{
//###
- if (constantTable[constIndex].isUndefined()) {
+ if (constant(constIndex).isUndefined()) {
move(TrustedImm32(0), ScratchRegister);
store32(ScratchRegister, destRegAddr);
destRegAddr.offset += 4;
@@ -1005,8 +484,7 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntime("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper),
- Assembler::ResultInAccumulator);
+ callRuntimeUnchecked("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper));
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
@@ -1058,8 +536,8 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
- Assembler::ResultInAccumulator);
+ callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
popAligned(lhsTarget);
@@ -1079,8 +557,8 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
- Assembler::ResultInAccumulator);
+ callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
@@ -1148,7 +626,7 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
move(AccumulatorRegisterTag, ScratchRegister);
or32(AccumulatorRegisterValue, ScratchRegister);
auto jump = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
- patches.push_back({ jump, offset });
+ addJumpToOffset(jump, offset);
}
Jump jumpEmpty()
@@ -1195,6 +673,34 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
done.link(this);
}
+ void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqInt = branch32(NotEqual, ScratchRegister, TrustedImm32(rhs));
+ Jump notEqUndefVal = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
+ addJumpToOffset(notEqUndefVal, offset);
+ lhsAddr.offset += 4;
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqUndefTag = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
+ addJumpToOffset(notEqUndefTag, offset);
+ notEqInt.link(this);
+ }
+
+ void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
+ addJumpToOffset(notEqual, offset);
+ Jump notUndefValue = branch32(NotEqual, TrustedImm32(0), ScratchRegister);
+ lhsAddr.offset += 4;
+ load32(lhsAddr, ScratchRegister);
+ Jump equalUndef = branch32(Equal, TrustedImm32(0), ScratchRegister);
+ addJumpToOffset(equalUndef, offset);
+ notUndefValue.link(this);
+ }
+
void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
{
if (sourceReg != NoRegister)
@@ -1274,6 +780,8 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
typedef PlatformAssembler32 PlatformAssembler;
#endif
+#define pasm() reinterpret_cast<PlatformAssembler *>(this->d)
+
typedef PlatformAssembler::TrustedImmPtr TrustedImmPtr;
typedef PlatformAssembler::TrustedImm32 TrustedImm32;
typedef PlatformAssembler::TrustedImm64 TrustedImm64;
@@ -1281,196 +789,72 @@ typedef PlatformAssembler::Address Address;
typedef PlatformAssembler::RegisterID RegisterID;
typedef PlatformAssembler::FPRegisterID FPRegisterID;
-#define pasm() reinterpret_cast<PlatformAssembler *>(this->d)
-
static Address regAddr(int reg)
{
return Address(PlatformAssembler::JSStackFrameRegister, reg * int(sizeof(QV4::Value)));
}
-Assembler::Assembler(const Value *constantTable)
- : d(new PlatformAssembler)
+BaselineAssembler::BaselineAssembler(const Value *constantTable)
+ : d(new PlatformAssembler(constantTable))
{
- pasm()->constantTable = constantTable;
}
-Assembler::~Assembler()
+BaselineAssembler::~BaselineAssembler()
{
delete pasm();
}
-void Assembler::generatePrologue()
+void BaselineAssembler::generatePrologue()
{
pasm()->generateFunctionEntry();
}
-void Assembler::generateEpilogue()
+void BaselineAssembler::generateEpilogue()
{
pasm()->generateCatchTrampoline();
}
-namespace {
-class QIODevicePrintStream: public FilePrintStream
-{
- Q_DISABLE_COPY(QIODevicePrintStream)
-
-public:
- explicit QIODevicePrintStream(QIODevice *dest)
- : FilePrintStream(nullptr)
- , dest(dest)
- , buf(4096, '0')
- {
- Q_ASSERT(dest);
- }
-
- ~QIODevicePrintStream()
- {}
-
- void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
- {
- const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
- if (written > 0)
- dest->write(buf.constData(), written);
- memset(buf.data(), 0, qMin(written, buf.size()));
- }
-
- void flush()
- {}
-
-private:
- QIODevice *dest;
- QByteArray buf;
-};
-} // anonymous namespace
-
-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 QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
- int idx = 0;
- while (idx >= 0) {
- idx = processedOutput.indexOf(ptrString, idx);
- if (idx < 0)
- break;
- idx = processedOutput.indexOf('\n', idx);
- if (idx < 0)
- break;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value());
- }
- }
-
- qDebug("%s", processedOutput.constData());
-}
-
-static QByteArray functionName(Function *function)
+void BaselineAssembler::link(Function *function)
{
- QByteArray name = function->name()->toQString().toUtf8();
- if (name.isEmpty()) {
- name = QByteArray::number(reinterpret_cast<quintptr>(function), 16);
- name.prepend("QV4::Function(0x");
- name.append(')');
- }
- return name;
+ pasm()->link(function);
}
-void Assembler::link(Function *function)
+void BaselineAssembler::addLabel(int offset)
{
- for (const auto &jumpTarget : pasm()->patches)
- jumpTarget.jump.linkTo(pasm()->labelsByOffset[jumpTarget.offset], pasm());
-
- JSC::JSGlobalData dummy(function->internalClass->engine->executableAllocator);
- JSC::LinkBuffer<PlatformAssembler::MacroAssembler> linkBuffer(dummy, pasm(), nullptr);
-
- for (const auto &ehTarget : pasm()->ehTargets) {
- auto targetLabel = pasm()->labelsByOffset.value(ehTarget.offset);
- linkBuffer.patch(ehTarget.label, linkBuffer.locationOf(targetLabel));
- }
-
- JSC::MacroAssemblerCodeRef codeRef;
-
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
- if (showCode) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- WTF::setDataFile(new QIODevicePrintStream(&buf));
-
- QByteArray name = functionName(function);
- codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
-
- WTF::setDataFile(stderr);
- printDisassembledOutputWithCalls(buf.data(), pasm()->functions);
- } else {
- codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
- }
-
- function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef);
- function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress());
-
- // This implements writing of JIT'd addresses so that perf can find the
- // symbol names.
- //
- // Perf expects the mapping to be in a certain place and have certain
- // content, for more information, see:
- // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
- static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
- if (Q_UNLIKELY(doProfile)) {
- static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map")
- .arg(QCoreApplication::applicationPid()));
- static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly);
- if (!isOpen) {
- qWarning("QV4::JIT::Assembler: Cannot write perf map file.");
- doProfile = false;
- } else {
- perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(
- codeRef.code().executableAddress()), 16));
- perfMapFile.putChar(' ');
- perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16));
- perfMapFile.putChar(' ');
- perfMapFile.write(functionName(function));
- perfMapFile.putChar('\n');
- perfMapFile.flush();
- }
- }
-}
-
-void Assembler::addLabel(int offset)
-{
- pasm()->labelsByOffset[offset] = pasm()->label();
+ pasm()->addLabelForOffset(offset);
}
-void Assembler::loadConst(int constIndex)
+void BaselineAssembler::loadConst(int constIndex)
{
//###
- if (pasm()->constantTable[constIndex].isUndefined()) {
+ if (pasm()->constant(constIndex).isUndefined()) {
pasm()->loadUndefined();
} else {
pasm()->loadAccumulator(pasm()->loadConstAddress(constIndex));
}
}
-void Assembler::copyConst(int constIndex, int destReg)
+void BaselineAssembler::copyConst(int constIndex, int destReg)
{
pasm()->copyConst(constIndex, regAddr(destReg));
}
-void Assembler::loadReg(int reg)
+void BaselineAssembler::loadReg(int reg)
{
pasm()->loadAccumulator(regAddr(reg));
}
-void JIT::Assembler::moveReg(int sourceReg, int destReg)
+void JIT::BaselineAssembler::moveReg(int sourceReg, int destReg)
{
pasm()->moveReg(regAddr(sourceReg), regAddr(destReg));
}
-void Assembler::storeReg(int reg)
+void BaselineAssembler::storeReg(int reg)
{
pasm()->storeAccumulator(regAddr(reg));
}
-void Assembler::loadLocal(int index, int level)
+void BaselineAssembler::loadLocal(int index, int level)
{
Heap::CallContext ctx;
Q_UNUSED(ctx)
@@ -1482,7 +866,7 @@ void Assembler::loadLocal(int index, int level)
pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
}
-void Assembler::storeLocal(int index, int level)
+void BaselineAssembler::storeLocal(int index, int level)
{
Heap::CallContext ctx;
Q_UNUSED(ctx)
@@ -1494,22 +878,22 @@ void Assembler::storeLocal(int index, int level)
pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
}
-void Assembler::loadString(int stringId)
+void BaselineAssembler::loadString(int stringId)
{
pasm()->loadString(stringId);
}
-void Assembler::loadValue(ReturnedValue value)
+void BaselineAssembler::loadValue(ReturnedValue value)
{
pasm()->loadValue(value);
}
-void JIT::Assembler::storeHeapObject(int reg)
+void BaselineAssembler::storeHeapObject(int reg)
{
pasm()->storeHeapObject(PlatformAssembler::ReturnValueRegisterValue, regAddr(reg));
}
-void JIT::Assembler::loadImport(int index)
+void BaselineAssembler::loadImport(int index)
{
Address addr = pasm()->loadCompilationUnitPtr(PlatformAssembler::ScratchRegister);
addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, imports);
@@ -1519,21 +903,21 @@ void JIT::Assembler::loadImport(int index)
pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister));
}
-void Assembler::toNumber()
+void BaselineAssembler::toNumber()
{
pasm()->toNumber();
}
-void Assembler::uminus()
+void BaselineAssembler::uminus()
{
saveAccumulatorInFrame();
- prepareCallWithArgCount(1);
- passAccumulatorAsArg(0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_uMinus, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(1);
+ pasm()->passAccumulatorAsArg(0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_uMinus, CallResultDestination::InAccumulator);
checkException();
}
-void Assembler::ucompl()
+void BaselineAssembler::ucompl()
{
pasm()->toInt32();
pasm()->xor32(TrustedImm32(-1), PlatformAssembler::AccumulatorRegisterValue);
@@ -1550,7 +934,7 @@ static ReturnedValue incHelper(const Value v)
return Encode(d + 1.);
}
-void Assembler::inc()
+void BaselineAssembler::inc()
{
auto done = pasm()->unopIntPath([this](){
auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
@@ -1582,7 +966,7 @@ static ReturnedValue decHelper(const Value v)
return Encode(d - 1.);
}
-void Assembler::dec()
+void BaselineAssembler::dec()
{
auto done = pasm()->unopIntPath([this](){
auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
@@ -1604,7 +988,7 @@ void Assembler::dec()
done.link(pasm());
}
-void Assembler::unot()
+void BaselineAssembler::unot()
{
pasm()->toBoolean([this](PlatformAssembler::RegisterID resultReg){
pasm()->compare32(PlatformAssembler::Equal, resultReg,
@@ -1613,7 +997,7 @@ void Assembler::unot()
});
}
-void Assembler::add(int lhs)
+void BaselineAssembler::add(int lhs)
{
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
@@ -1626,18 +1010,18 @@ void Assembler::add(int lhs)
// slow path:
saveAccumulatorInFrame();
- prepareCallWithArgCount(3);
- passAccumulatorAsArg(2);
- passRegAsArg(lhs, 1);
- passEngineAsArg(0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_add, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(3);
+ pasm()->passAccumulatorAsArg(2);
+ pasm()->passJSSlotAsArg(lhs, 1);
+ pasm()->passEngineAsArg(0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_add, CallResultDestination::InAccumulator);
checkException();
// done.
done.link(pasm());
}
-void Assembler::bitAnd(int lhs)
+void BaselineAssembler::bitAnd(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1645,7 +1029,7 @@ void Assembler::bitAnd(int lhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::bitOr(int lhs)
+void BaselineAssembler::bitOr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1653,7 +1037,7 @@ void Assembler::bitOr(int lhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::bitXor(int lhs)
+void BaselineAssembler::bitXor(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1661,7 +1045,7 @@ void Assembler::bitXor(int lhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::ushr(int lhs)
+void BaselineAssembler::ushr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1682,7 +1066,7 @@ void Assembler::ushr(int lhs)
done.link(pasm());
}
-void Assembler::shr(int lhs)
+void BaselineAssembler::shr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1692,7 +1076,7 @@ void Assembler::shr(int lhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::shl(int lhs)
+void BaselineAssembler::shl(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
@@ -1702,28 +1086,28 @@ void Assembler::shl(int lhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::bitAndConst(int rhs)
+void BaselineAssembler::bitAndConst(int rhs)
{
pasm()->toInt32();
pasm()->and32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::bitOrConst(int rhs)
+void BaselineAssembler::bitOrConst(int rhs)
{
pasm()->toInt32();
pasm()->or32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::bitXorConst(int rhs)
+void BaselineAssembler::bitXorConst(int rhs)
{
pasm()->toInt32();
pasm()->xor32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::ushrConst(int rhs)
+void BaselineAssembler::ushrConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
@@ -1748,7 +1132,7 @@ void Assembler::ushrConst(int rhs)
}
}
-void Assembler::shrConst(int rhs)
+void BaselineAssembler::shrConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
@@ -1757,7 +1141,7 @@ void Assembler::shrConst(int rhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::shlConst(int rhs)
+void BaselineAssembler::shlConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
@@ -1766,7 +1150,7 @@ void Assembler::shlConst(int rhs)
pasm()->setAccumulatorTag(IntegerTag);
}
-void Assembler::mul(int lhs)
+void BaselineAssembler::mul(int lhs)
{
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
auto overflowed = pasm()->branchMul32(PlatformAssembler::Overflow,
@@ -1779,37 +1163,37 @@ void Assembler::mul(int lhs)
// slow path:
saveAccumulatorInFrame();
- prepareCallWithArgCount(2);
- passAccumulatorAsArg(1);
- passRegAsArg(lhs, 0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_mul, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(2);
+ pasm()->passAccumulatorAsArg(1);
+ pasm()->passJSSlotAsArg(lhs, 0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_mul, CallResultDestination::InAccumulator);
checkException();
// done.
done.link(pasm());
}
-void Assembler::div(int lhs)
+void BaselineAssembler::div(int lhs)
{
saveAccumulatorInFrame();
- prepareCallWithArgCount(2);
- passAccumulatorAsArg(1);
- passRegAsArg(lhs, 0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_div, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(2);
+ pasm()->passAccumulatorAsArg(1);
+ pasm()->passJSSlotAsArg(lhs, 0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_div, CallResultDestination::InAccumulator);
checkException();
}
-void Assembler::mod(int lhs)
+void BaselineAssembler::mod(int lhs)
{
saveAccumulatorInFrame();
- prepareCallWithArgCount(2);
- passAccumulatorAsArg(1);
- passRegAsArg(lhs, 0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_mod, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(2);
+ pasm()->passAccumulatorAsArg(1);
+ pasm()->passJSSlotAsArg(lhs, 0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_mod, CallResultDestination::InAccumulator);
checkException();
}
-void Assembler::sub(int lhs)
+void BaselineAssembler::sub(int lhs)
{
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
@@ -1822,30 +1206,30 @@ void Assembler::sub(int lhs)
// slow path:
saveAccumulatorInFrame();
- prepareCallWithArgCount(2);
- passAccumulatorAsArg(1);
- passRegAsArg(lhs, 0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_sub, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(2);
+ pasm()->passAccumulatorAsArg(1);
+ pasm()->passJSSlotAsArg(lhs, 0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_sub, CallResultDestination::InAccumulator);
checkException();
// done.
done.link(pasm());
}
-void Assembler::cmpeqNull()
+void BaselineAssembler::cmpeqNull()
{
pasm()->isNullOrUndefined();
pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}
-void Assembler::cmpneNull()
+void BaselineAssembler::cmpneNull()
{
pasm()->isNullOrUndefined();
pasm()->xor32(TrustedImm32(1), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}
-void Assembler::cmpeqInt(int lhs)
+void BaselineAssembler::cmpeqInt(int lhs)
{
auto isIntOrBool = pasm()->isIntOrBool();
saveAccumulatorInFrame();
@@ -1854,8 +1238,9 @@ void Assembler::cmpeqInt(int lhs)
pasm()->push(PlatformAssembler::StackPointerRegister);
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
- passAccumulatorAsArg_internal(0, true);
- pasm()->callRuntime("Runtime::method_equal", (void*)Runtime::method_equal, ResultInAccumulator);
+ pasm()->pushAccumulatorAsArg(0);
+ pasm()->callRuntimeUnchecked("Runtime::method_equal", (void*)Runtime::method_equal);
+ pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
pasm()->popValueAligned();
@@ -1868,7 +1253,7 @@ void Assembler::cmpeqInt(int lhs)
done.link(pasm());
}
-void Assembler::cmpneInt(int lhs)
+void BaselineAssembler::cmpneInt(int lhs)
{
auto isIntOrBool = pasm()->isIntOrBool();
saveAccumulatorInFrame();
@@ -1877,8 +1262,9 @@ void Assembler::cmpneInt(int lhs)
pasm()->push(PlatformAssembler::StackPointerRegister);
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
- passAccumulatorAsArg_internal(0, true);
- pasm()->callRuntime("Runtime::method_notEqual", (void*)Runtime::method_notEqual, ResultInAccumulator);
+ pasm()->pushAccumulatorAsArg(0);
+ pasm()->callRuntimeUnchecked("Runtime::method_notEqual", (void*)Runtime::method_notEqual);
+ pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
pasm()->popValueAligned();
@@ -1891,7 +1277,7 @@ void Assembler::cmpneInt(int lhs)
done.link(pasm());
}
-void Assembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
+void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
{
auto c = static_cast<PlatformAssembler::RelationalCondition>(cond);
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){
@@ -1904,11 +1290,11 @@ void Assembler::cmp(int cond, CmpFunc function, const char *functionName, int lh
// slow path:
saveAccumulatorInFrame();
- prepareCallWithArgCount(2);
- passAccumulatorAsArg(1);
- passRegAsArg(lhs, 0);
+ pasm()->prepareCallWithArgCount(2);
+ pasm()->passAccumulatorAsArg(1);
+ pasm()->passJSSlotAsArg(lhs, 0);
- callRuntime(functionName, reinterpret_cast<void*>(function), ResultInAccumulator);
+ callRuntime(functionName, reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
checkException();
pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
@@ -1916,49 +1302,49 @@ void Assembler::cmp(int cond, CmpFunc function, const char *functionName, int lh
done.link(pasm());
}
-void Assembler::cmpeq(int lhs)
+void BaselineAssembler::cmpeq(int lhs)
{
cmp(PlatformAssembler::Equal, &Runtime::method_compareEqual,
"Runtime::method_compareEqual", lhs);
}
-void Assembler::cmpne(int lhs)
+void BaselineAssembler::cmpne(int lhs)
{
cmp(PlatformAssembler::NotEqual, &Runtime::method_compareNotEqual,
"Runtime::method_compareNotEqual", lhs);
}
-void Assembler::cmpgt(int lhs)
+void BaselineAssembler::cmpgt(int lhs)
{
cmp(PlatformAssembler::GreaterThan, &Runtime::method_compareGreaterThan,
"Runtime::method_compareGreaterThan", lhs);
}
-void Assembler::cmpge(int lhs)
+void BaselineAssembler::cmpge(int lhs)
{
cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::method_compareGreaterEqual,
"Runtime::method_compareGreaterEqual", lhs);
}
-void Assembler::cmplt(int lhs)
+void BaselineAssembler::cmplt(int lhs)
{
cmp(PlatformAssembler::LessThan, &Runtime::method_compareLessThan,
"Runtime::method_compareLessThan", lhs);
}
-void Assembler::cmple(int lhs)
+void BaselineAssembler::cmple(int lhs)
{
cmp(PlatformAssembler::LessThanOrEqual, &Runtime::method_compareLessEqual,
"Runtime::method_compareLessEqual", lhs);
}
-void Assembler::cmpStrictEqual(int lhs)
+void BaselineAssembler::cmpStrictEqual(int lhs)
{
cmp(PlatformAssembler::Equal, &RuntimeHelpers::strictEqual,
"RuntimeHelpers::strictEqual", lhs);
}
-void Assembler::cmpStrictNotEqual(int lhs)
+void BaselineAssembler::cmpStrictNotEqual(int lhs)
{
cmp(PlatformAssembler::Equal, &RuntimeHelpers::strictEqual,
"RuntimeHelpers::strictEqual", lhs);
@@ -1966,211 +1352,104 @@ void Assembler::cmpStrictNotEqual(int lhs)
pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}
-void Assembler::jump(int offset)
+void BaselineAssembler::jump(int offset)
{
- pasm()->patches.push_back({ pasm()->jump(), offset });
+ pasm()->addJumpToOffset(pasm()->jump(), offset);
}
-void Assembler::jumpTrue(int offset)
+void BaselineAssembler::jumpTrue(int offset)
{
pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
auto jump = pasm()->branch32(PlatformAssembler::NotEqual, TrustedImm32(0), resultReg);
- pasm()->patches.push_back({ jump, offset });
+ pasm()->addJumpToOffset(jump, offset);
});
}
-void Assembler::jumpFalse(int offset)
+void BaselineAssembler::jumpFalse(int offset)
{
pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
auto jump = pasm()->branch32(PlatformAssembler::Equal, TrustedImm32(0), resultReg);
- pasm()->patches.push_back({ jump, offset });
+ pasm()->addJumpToOffset(jump, offset);
});
}
-void Assembler::jumpNoException(int offset)
+void BaselineAssembler::jumpNoException(int offset)
{
auto jump = pasm()->branch32(
PlatformAssembler::Equal,
PlatformAssembler::Address(PlatformAssembler::EngineRegister,
offsetof(EngineBase, hasException)),
TrustedImm32(0));
- pasm()->patches.push_back({ jump, offset });
+ pasm()->addJumpToOffset(jump, offset);
}
-void Assembler::jumpNotUndefined(int offset)
+void BaselineAssembler::jumpNotUndefined(int offset)
{
pasm()->jumpNotUndefined(offset);
}
-void Assembler::prepareCallWithArgCount(int argc)
+void BaselineAssembler::prepareCallWithArgCount(int argc)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(remainingArgcForCall == NoCall);
- remainingArgcForCall = argc;
-#endif
-
- if (argc > PlatformAssembler::ArgInRegCount) {
- argcOnStackForCall = int(WTF::roundUpToMultipleOf(16, size_t(argc - PlatformAssembler::ArgInRegCount) * PlatformAssembler::PointerSize));
- pasm()->subPtr(TrustedImm32(argcOnStackForCall), PlatformAssembler::StackPointerRegister);
- }
+ pasm()->prepareCallWithArgCount(argc);
}
-void Assembler::storeInstructionPointer(int instructionOffset)
+void BaselineAssembler::storeInstructionPointer(int instructionOffset)
{
- PlatformAssembler::Address addr(PlatformAssembler::CppStackFrameRegister,
- offsetof(QV4::CppStackFrame, instructionPointer));
- pasm()->store32(TrustedImm32(instructionOffset), addr);
+ pasm()->storeInstructionPointer(instructionOffset);
}
-Address argStackAddress(int arg)
+void BaselineAssembler::passAccumulatorAsArg(int arg)
{
- int offset = arg - PlatformAssembler::ArgInRegCount;
- Q_ASSERT(offset >= 0);
- return Address(PlatformAssembler::StackPointerRegister, offset * PlatformAssembler::PointerSize);
+ pasm()->passAccumulatorAsArg(arg);
}
-void Assembler::passAccumulatorAsArg(int arg)
+void BaselineAssembler::passFunctionAsArg(int arg)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- passAccumulatorAsArg_internal(arg, false);
-}
-
-void Assembler::passAccumulatorAsArg_internal(int arg, bool push)
-{
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->addPtr(TrustedImm32(offsetof(CallData, accumulator)),
- PlatformAssembler::JSStackFrameRegister,
- pasm()->registerForArg(arg));
- } else {
- pasm()->addPtr(TrustedImm32(offsetof(CallData, accumulator)),
- PlatformAssembler::JSStackFrameRegister,
- PlatformAssembler::ScratchRegister);
- if (push)
- pasm()->push(PlatformAssembler::ScratchRegister);
- else
- pasm()->storePtr(PlatformAssembler::ScratchRegister,
- argStackAddress(arg));
- }
-}
-
-void Assembler::passFunctionAsArg(int arg)
-{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->loadFunctionPtr(pasm()->registerForArg(arg));
- } else {
- pasm()->loadFunctionPtr(PlatformAssembler::ScratchRegister);
- pasm()->storePtr(PlatformAssembler::ScratchRegister,
- argStackAddress(arg));
- }
+ pasm()->passFunctionAsArg(arg);
}
-void Assembler::passEngineAsArg(int arg)
+void BaselineAssembler::passEngineAsArg(int arg)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->move(PlatformAssembler::EngineRegister, pasm()->registerForArg(arg));
- } else {
- pasm()->storePtr(PlatformAssembler::EngineRegister, argStackAddress(arg));
- }
+ pasm()->passEngineAsArg(arg);
}
-void Assembler::passRegAsArg(int reg, int arg)
+void BaselineAssembler::passJSSlotAsArg(int reg, int arg)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->addPtr(TrustedImm32(reg * int(sizeof(QV4::Value))),
- PlatformAssembler::JSStackFrameRegister,
- pasm()->registerForArg(arg));
- } else {
- pasm()->addPtr(TrustedImm32(reg * int(sizeof(QV4::Value))),
- PlatformAssembler::JSStackFrameRegister,
- PlatformAssembler::ScratchRegister);
- pasm()->storePtr(PlatformAssembler::ScratchRegister,
- argStackAddress(arg));
- }
+ pasm()->passJSSlotAsArg(reg, arg);
}
-void JIT::Assembler::passCppFrameAsArg(int arg)
+void BaselineAssembler::passCppFrameAsArg(int arg)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->move(PlatformAssembler::CppStackFrameRegister, pasm()->registerForArg(arg));
- } else {
- pasm()->store32(PlatformAssembler::CppStackFrameRegister, argStackAddress(arg));
- }
+ pasm()->passCppFrameAsArg(arg);
}
-void Assembler::passInt32AsArg(int value, int arg)
+void BaselineAssembler::passInt32AsArg(int value, int arg)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(arg < remainingArgcForCall);
- --remainingArgcForCall;
-#endif
-
- if (arg < PlatformAssembler::ArgInRegCount) {
- pasm()->move(TrustedImm32(value), pasm()->registerForArg(arg));
- } else {
- pasm()->store32(TrustedImm32(value), argStackAddress(arg));
- }
+ pasm()->passInt32AsArg(value, arg);
}
-void Assembler::callRuntime(const char *functionName, const void *funcPtr,
- Assembler::CallResultDestination dest)
+void BaselineAssembler::callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest)
{
-#ifndef QT_NO_DEBUG
- Q_ASSERT(remainingArgcForCall == 0);
- remainingArgcForCall = NoCall;
-#endif
pasm()->callRuntime(functionName, funcPtr, dest);
- if (argcOnStackForCall > 0) {
- pasm()->addPtr(TrustedImm32(argcOnStackForCall), PlatformAssembler::StackPointerRegister);
- argcOnStackForCall = 0;
- }
}
-void Assembler::saveAccumulatorInFrame()
+void BaselineAssembler::saveAccumulatorInFrame()
{
pasm()->storeAccumulator(PlatformAssembler::Address(PlatformAssembler::JSStackFrameRegister,
offsetof(CallData, accumulator)));
}
-void Assembler::checkException()
+void BaselineAssembler::checkException()
{
- pasm()->addCatchyJump(
- pasm()->branch32(
- PlatformAssembler::NotEqual,
- PlatformAssembler::Address(PlatformAssembler::EngineRegister,
- offsetof(EngineBase, hasException)),
- TrustedImm32(0)));
+ pasm()->checkException();
}
-void Assembler::gotoCatchException()
+void BaselineAssembler::gotoCatchException()
{
pasm()->addCatchyJump(pasm()->jump());
}
-void Assembler::getException()
+void BaselineAssembler::getException()
{
Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
@@ -2191,7 +1470,7 @@ void Assembler::getException()
done.link(pasm());
}
-void Assembler::setException()
+void BaselineAssembler::setException()
{
auto noException = pasm()->jumpEmpty();
Address addr(PlatformAssembler::EngineRegister, offsetof(EngineBase, exceptionValue));
@@ -2203,19 +1482,19 @@ void Assembler::setException()
noException.link(pasm());
}
-void Assembler::setUnwindHandler(int offset)
+void BaselineAssembler::setUnwindHandler(int offset)
{
auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
- pasm()->ehTargets.push_back({ l, offset });
+ pasm()->addEHTarget(l, offset);
}
-void Assembler::clearUnwindHandler()
+void BaselineAssembler::clearUnwindHandler()
{
pasm()->storePtr(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
}
-void JIT::Assembler::unwindDispatch()
+void JIT::BaselineAssembler::unwindDispatch()
{
checkException();
pasm()->load32(Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)), PlatformAssembler::ScratchRegister);
@@ -2232,25 +1511,25 @@ void JIT::Assembler::unwindDispatch()
noUnwind.link(pasm());
}
-void JIT::Assembler::unwindToLabel(int level, int offset)
+void JIT::BaselineAssembler::unwindToLabel(int level, int offset)
{
auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLabel)));
- pasm()->ehTargets.push_back({ l, offset });
+ pasm()->addEHTarget(l, offset);
pasm()->store32(TrustedImm32(level), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)));
gotoCatchException();
}
-void Assembler::pushCatchContext(int index, int name)
+void BaselineAssembler::pushCatchContext(int index, int name)
{
- prepareCallWithArgCount(3);
- passInt32AsArg(name, 2);
- passInt32AsArg(index, 1);
- passRegAsArg(CallData::Context, 0);
- IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_createCatchContext, ResultInAccumulator);
+ pasm()->prepareCallWithArgCount(3);
+ pasm()->passInt32AsArg(name, 2);
+ pasm()->passInt32AsArg(index, 1);
+ pasm()->passJSSlotAsArg(CallData::Context, 0);
+ ASM_GENERATE_RUNTIME_CALL(Runtime::method_createCatchContext, CallResultDestination::InAccumulator);
pasm()->storeAccumulator(pasm()->contextAddress());
}
-void Assembler::popContext()
+void BaselineAssembler::popContext()
{
Heap::CallContext ctx;
Q_UNUSED(ctx)
@@ -2259,7 +1538,7 @@ void Assembler::popContext()
pasm()->storeHeapObject(PlatformAssembler::ScratchRegister, regAddr(CallData::Context));
}
-void Assembler::ret()
+void BaselineAssembler::ret()
{
pasm()->generateFunctionExit();
}
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4baselineassembler_p.h
index 1379c72f9a..4b64f91cd4 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4baselineassembler_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** 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.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QV4ASSEMBLER_P_H
-#define QV4ASSEMBLER_P_H
+#ifndef QV4BASELINEASSEMBLER_P_H
+#define QV4BASELINEASSEMBLER_P_H
//
// W A R N I N G
@@ -63,22 +63,15 @@ namespace JIT {
#define JIT_STRINGIFYx(s) #s
#define JIT_STRINGIFY(s) JIT_STRINGIFYx(s)
-#define IN_JIT_GENERATE_RUNTIME_CALL(function, destination) \
+#define GENERATE_RUNTIME_CALL(function, destination) \
callRuntime(JIT_STRINGIFY(function), \
reinterpret_cast<void *>(&function), \
destination)
-#define JIT_GENERATE_RUNTIME_CALL(function, destination) \
- as->IN_JIT_GENERATE_RUNTIME_CALL(function, destination)
-class Assembler {
+class BaselineAssembler {
public:
- enum CallResultDestination {
- IgnoreResult,
- ResultInAccumulator,
- };
-
- Assembler(const Value* constantTable);
- ~Assembler();
+ BaselineAssembler(const Value* constantTable);
+ ~BaselineAssembler();
// codegen infrastructure
void generatePrologue();
@@ -151,10 +144,10 @@ public:
void passAccumulatorAsArg(int arg);
void passFunctionAsArg(int arg);
void passEngineAsArg(int arg);
- void passRegAsArg(int reg, int arg);
+ void passJSSlotAsArg(int reg, int arg);
void passCppFrameAsArg(int arg);
void passInt32AsArg(int value, int arg);
- void callRuntime(const char *functionName, const void *funcPtr, Assembler::CallResultDestination dest);
+ void callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest);
void saveAccumulatorInFrame();
// exception/context stuff
@@ -175,16 +168,9 @@ public:
protected:
void *d;
-#ifndef QT_NO_DEBUG
- enum { NoCall = -1 };
- int remainingArgcForCall = NoCall;
-#endif
- int argcOnStackForCall = 0;
-
private:
typedef unsigned(*CmpFunc)(const Value&,const Value&);
void cmp(int cond, CmpFunc function, const char *functionName, int lhs);
- void passAccumulatorAsArg_internal(int arg, bool push);
};
} // namespace JIT
@@ -192,4 +178,4 @@ private:
QT_END_NAMESPACE
-#endif // QV4ASSEMBLER_P_H
+#endif // QV4BASELINEASSEMBLER_P_H
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index 2e0f357574..b729f21059 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -39,7 +39,7 @@
#include "qv4baselinejit_p.h"
#include "qv4jithelpers_p.h"
-#include "qv4assembler_p.h"
+#include "qv4baselineassembler_p.h"
#include <private/qv4lookup_p.h>
#include <private/qv4generatorobject_p.h>
@@ -52,7 +52,7 @@ using namespace QV4::Moth;
BaselineJIT::BaselineJIT(Function *function)
: function(function)
- , as(new Assembler(function->compilationUnit->constants))
+ , as(new BaselineAssembler(function->compilationUnit->constants))
{}
BaselineJIT::~BaselineJIT()
@@ -75,6 +75,8 @@ void BaselineJIT::generate()
#define STORE_IP() as->storeInstructionPointer(nextInstructionOffset())
#define STORE_ACC() as->saveAccumulatorInFrame()
+#define BASELINEJIT_GENERATE_RUNTIME_CALL(function, destination) \
+ as->GENERATE_RUNTIME_CALL(function, destination)
void BaselineJIT::generate_Ret()
{
@@ -177,7 +179,7 @@ void BaselineJIT::generate_MoveRegExp(int regExpId, int destReg)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(regExpId, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_regexpLiteral, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_regexpLiteral, CallResultDestination::InAccumulator);
as->storeReg(destReg);
}
@@ -186,7 +188,7 @@ void BaselineJIT::generate_LoadClosure(int value)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(value, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_closure, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_closure, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_LoadName(int name)
@@ -195,7 +197,7 @@ void BaselineJIT::generate_LoadName(int name)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadName, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadName, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -205,7 +207,7 @@ void BaselineJIT::generate_LoadGlobalLookup(int index)
as->passInt32AsArg(index, 2);
as->passFunctionAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::loadGlobalLookup, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::loadGlobalLookup, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -217,7 +219,7 @@ void BaselineJIT::generate_StoreNameSloppy(int name)
as->passAccumulatorAsArg(2);
as->passInt32AsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameSloppy, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameSloppy, CallResultDestination::Ignore);
as->checkException();
}
@@ -229,7 +231,7 @@ void BaselineJIT::generate_StoreNameStrict(int name)
as->passAccumulatorAsArg(2);
as->passInt32AsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameStrict, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameStrict, CallResultDestination::Ignore);
as->checkException();
}
@@ -239,9 +241,9 @@ void BaselineJIT::generate_LoadElement(int base)
STORE_ACC();
as->prepareCallWithArgCount(3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadElement, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadElement, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -251,10 +253,10 @@ void BaselineJIT::generate_StoreElement(int base, int index)
STORE_ACC();
as->prepareCallWithArgCount(4);
as->passAccumulatorAsArg(3);
- as->passRegAsArg(index, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(index, 2);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeElement, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeElement, CallResultDestination::Ignore);
as->checkException();
}
@@ -266,7 +268,7 @@ void BaselineJIT::generate_LoadProperty(int name)
as->passInt32AsArg(name, 2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -279,7 +281,7 @@ void BaselineJIT::generate_GetLookup(int index)
as->passInt32AsArg(index, 2);
as->passFunctionAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::getLookup, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::getLookup, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -290,9 +292,9 @@ void BaselineJIT::generate_StoreProperty(int name, int base)
as->prepareCallWithArgCount(4);
as->passAccumulatorAsArg(3);
as->passInt32AsArg(name, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeProperty, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeProperty, CallResultDestination::Ignore);
as->checkException();
}
@@ -302,10 +304,10 @@ void BaselineJIT::generate_SetLookup(int index, int base)
STORE_ACC();
as->prepareCallWithArgCount(4);
as->passAccumulatorAsArg(3);
- as->passRegAsArg(base, 2);
+ as->passJSSlotAsArg(base, 2);
as->passInt32AsArg(index, 1);
as->passFunctionAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::setLookup, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::setLookup, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -314,9 +316,9 @@ void BaselineJIT::generate_LoadSuperProperty(int property)
STORE_IP();
STORE_ACC();
as->prepareCallWithArgCount(2);
- as->passRegAsArg(property, 1);
+ as->passJSSlotAsArg(property, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadSuperProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadSuperProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -326,9 +328,9 @@ void BaselineJIT::generate_StoreSuperProperty(int property)
STORE_ACC();
as->prepareCallWithArgCount(3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(property, 1);
+ as->passJSSlotAsArg(property, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeSuperProperty, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeSuperProperty, CallResultDestination::Ignore);
as->checkException();
}
@@ -339,9 +341,9 @@ void BaselineJIT::generate_StoreScopeObjectProperty(int base, int propertyIndex)
as->prepareCallWithArgCount(4);
as->passAccumulatorAsArg(3);
as->passInt32AsArg(propertyIndex, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlScopeObjectProperty, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlScopeObjectProperty, CallResultDestination::Ignore);
as->checkException();
}
@@ -351,9 +353,9 @@ void BaselineJIT::generate_StoreContextObjectProperty(int base, int propertyInde
as->prepareCallWithArgCount(4);
as->passAccumulatorAsArg(3);
as->passInt32AsArg(propertyIndex, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlContextObjectProperty, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlContextObjectProperty, CallResultDestination::Ignore);
as->checkException();
}
@@ -363,9 +365,9 @@ void BaselineJIT::generate_LoadScopeObjectProperty(int propertyIndex, int base,
as->prepareCallWithArgCount(4);
as->passInt32AsArg(captureRequired, 3);
as->passInt32AsArg(propertyIndex, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlScopeObjectProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlScopeObjectProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -375,9 +377,9 @@ void BaselineJIT::generate_LoadContextObjectProperty(int propertyIndex, int base
as->prepareCallWithArgCount(4);
as->passInt32AsArg(captureRequired, 3);
as->passInt32AsArg(propertyIndex, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContextObjectProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContextObjectProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -386,9 +388,9 @@ void BaselineJIT::generate_LoadIdObject(int index, int base)
STORE_IP();
as->prepareCallWithArgCount(3);
as->passInt32AsArg(index, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlIdObject, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlIdObject, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -409,10 +411,10 @@ void BaselineJIT::generate_CallValue(int name, int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(4);
as->passInt32AsArg(argc, 3);
- as->passRegAsArg(argv, 2);
- as->passRegAsArg(name, 1);
+ as->passJSSlotAsArg(argv, 2);
+ as->passJSSlotAsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callValue, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callValue, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -421,11 +423,11 @@ void BaselineJIT::generate_CallProperty(int name, int base, int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passInt32AsArg(name, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -434,11 +436,11 @@ void BaselineJIT::generate_CallPropertyLookup(int lookupIndex, int base, int arg
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passInt32AsArg(lookupIndex, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callPropertyLookup, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callPropertyLookup, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -447,11 +449,11 @@ void BaselineJIT::generate_CallElement(int base, int index, int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
- as->passRegAsArg(index, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(argv, 3);
+ as->passJSSlotAsArg(index, 2);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callElement, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callElement, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -460,10 +462,10 @@ void BaselineJIT::generate_CallName(int name, int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(4);
as->passInt32AsArg(argc, 3);
- as->passRegAsArg(argv, 2);
+ as->passJSSlotAsArg(argv, 2);
as->passInt32AsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callName, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callName, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -472,9 +474,9 @@ void BaselineJIT::generate_CallPossiblyDirectEval(int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(3);
as->passInt32AsArg(argc, 2);
- as->passRegAsArg(argv, 1);
+ as->passJSSlotAsArg(argv, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callPossiblyDirectEval, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callPossiblyDirectEval, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -483,10 +485,10 @@ void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv)
STORE_IP();
as->prepareCallWithArgCount(4);
as->passInt32AsArg(argc, 3);
- as->passRegAsArg(argv, 2);
+ as->passJSSlotAsArg(argv, 2);
as->passInt32AsArg(index, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callGlobalLookup, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callGlobalLookup, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -495,11 +497,11 @@ void BaselineJIT::generate_CallScopeObjectProperty(int propIdx, int base, int ar
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passInt32AsArg(propIdx, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlScopeObjectProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlScopeObjectProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -508,11 +510,11 @@ void BaselineJIT::generate_CallContextObjectProperty(int propIdx, int base, int
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passInt32AsArg(propIdx, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(base, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlContextObjectProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlContextObjectProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -522,11 +524,11 @@ void BaselineJIT::generate_CallWithSpread(int func, int thisObject, int argc, in
STORE_IP();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
- as->passRegAsArg(thisObject, 2);
- as->passRegAsArg(func, 1);
+ as->passJSSlotAsArg(argv, 3);
+ as->passJSSlotAsArg(thisObject, 2);
+ as->passJSSlotAsArg(func, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_callWithSpread, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_callWithSpread, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -537,11 +539,11 @@ void BaselineJIT::generate_Construct(int func, int argc, int argv)
STORE_ACC();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(func, 1);
+ as->passJSSlotAsArg(func, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_construct, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_construct, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -551,11 +553,11 @@ void BaselineJIT::generate_ConstructWithSpread(int func, int argc, int argv)
STORE_ACC();
as->prepareCallWithArgCount(5);
as->passInt32AsArg(argc, 4);
- as->passRegAsArg(argv, 3);
+ as->passJSSlotAsArg(argv, 3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(func, 1);
+ as->passJSSlotAsArg(func, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_constructWithSpread, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_constructWithSpread, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -585,7 +587,7 @@ void BaselineJIT::generate_ThrowException()
as->prepareCallWithArgCount(2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_throwException, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_throwException, CallResultDestination::Ignore);
as->gotoCatchException();
}
@@ -596,7 +598,7 @@ void BaselineJIT::generate_CreateCallContext()
{
as->prepareCallWithArgCount(1);
as->passCppFrameAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, Assembler::IgnoreResult); // keeps result in return value register
+ BASELINEJIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, CallResultDestination::Ignore); // keeps result in return value register
as->storeHeapObject(CallData::Context);
}
@@ -607,9 +609,9 @@ void BaselineJIT::generate_PushWithContext()
STORE_IP();
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(2);
- as->passRegAsArg(0, 1);
+ as->passJSSlotAsArg(0, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_createWithContext, Assembler::IgnoreResult); // keeps result in return value register
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createWithContext, CallResultDestination::Ignore); // keeps result in return value register
as->checkException();
as->storeHeapObject(CallData::Context);
}
@@ -619,16 +621,16 @@ void BaselineJIT::generate_PushBlockContext(int index)
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(2);
as->passInt32AsArg(index, 1);
- as->passRegAsArg(0, 0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::pushBlockContext, Assembler::IgnoreResult);
+ as->passJSSlotAsArg(0, 0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::pushBlockContext, CallResultDestination::Ignore);
}
void BaselineJIT::generate_CloneBlockContext()
{
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(1);
- as->passRegAsArg(CallData::Context, 0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::cloneBlockContext, Assembler::IgnoreResult);
+ as->passJSSlotAsArg(CallData::Context, 0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::cloneBlockContext, CallResultDestination::Ignore);
}
void BaselineJIT::generate_PushScriptContext(int index)
@@ -637,8 +639,8 @@ void BaselineJIT::generate_PushScriptContext(int index)
as->prepareCallWithArgCount(3);
as->passInt32AsArg(index, 2);
as->passEngineAsArg(1);
- as->passRegAsArg(0, 0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::pushScriptContext, Assembler::IgnoreResult);
+ as->passJSSlotAsArg(0, 0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::pushScriptContext, CallResultDestination::Ignore);
}
void BaselineJIT::generate_PopScriptContext()
@@ -646,8 +648,8 @@ void BaselineJIT::generate_PopScriptContext()
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(2);
as->passEngineAsArg(1);
- as->passRegAsArg(0, 0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::popScriptContext, Assembler::IgnoreResult);
+ as->passJSSlotAsArg(0, 0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::popScriptContext, CallResultDestination::Ignore);
}
void BaselineJIT::generate_PopContext() { as->popContext(); }
@@ -659,7 +661,7 @@ void BaselineJIT::generate_GetIterator(int iterator)
as->passInt32AsArg(iterator, 2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_getIterator, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_getIterator, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -667,10 +669,10 @@ void BaselineJIT::generate_IteratorNext(int value)
{
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(3);
- as->passRegAsArg(value, 2);
+ as->passJSSlotAsArg(value, 2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorNext, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorNext, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -678,10 +680,10 @@ void BaselineJIT::generate_IteratorClose(int done)
{
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(3);
- as->passRegAsArg(done, 2);
+ as->passJSSlotAsArg(done, 2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorClose, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorClose, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -691,7 +693,7 @@ void BaselineJIT::generate_DestructureRestElement()
as->prepareCallWithArgCount(2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_destructureRestElement, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_destructureRestElement, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -699,10 +701,10 @@ void BaselineJIT::generate_DeleteProperty(int base, int index)
{
STORE_IP();
as->prepareCallWithArgCount(3);
- as->passRegAsArg(index, 2);
- as->passRegAsArg(base, 1);
+ as->passJSSlotAsArg(index, 2);
+ as->passJSSlotAsArg(base, 1);
as->passFunctionAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::deleteProperty, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::deleteProperty, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -712,7 +714,7 @@ void BaselineJIT::generate_DeleteName(int name)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(name, 1);
as->passFunctionAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::deleteName, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::deleteName, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -721,7 +723,7 @@ void BaselineJIT::generate_TypeofName(int name)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(name, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofName, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofName, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_TypeofValue()
@@ -730,7 +732,7 @@ void BaselineJIT::generate_TypeofValue()
as->prepareCallWithArgCount(2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofValue, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofValue, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_DeclareVar(int varName, int isDeletable)
@@ -739,52 +741,52 @@ void BaselineJIT::generate_DeclareVar(int varName, int isDeletable)
as->passInt32AsArg(varName, 2);
as->passInt32AsArg(isDeletable, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_declareVar, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_declareVar, CallResultDestination::Ignore);
}
void BaselineJIT::generate_DefineArray(int argc, int args)
{
as->prepareCallWithArgCount(3);
as->passInt32AsArg(argc, 2);
- as->passRegAsArg(args, 1);
+ as->passJSSlotAsArg(args, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_arrayLiteral, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_arrayLiteral, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_DefineObjectLiteral(int internalClassId, int argc, int args)
{
as->prepareCallWithArgCount(4);
- as->passRegAsArg(args, 3);
+ as->passJSSlotAsArg(args, 3);
as->passInt32AsArg(argc, 2);
as->passInt32AsArg(internalClassId, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_objectLiteral, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_objectLiteral, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_CreateClass(int classIndex, int heritage, int computedNames)
{
as->prepareCallWithArgCount(4);
- as->passRegAsArg(computedNames, 3);
- as->passRegAsArg(heritage, 2);
+ as->passJSSlotAsArg(computedNames, 3);
+ as->passJSSlotAsArg(heritage, 2);
as->passInt32AsArg(classIndex, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_createClass, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createClass, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_CreateMappedArgumentsObject()
{
as->prepareCallWithArgCount(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_createMappedArgumentsObject,
- Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createMappedArgumentsObject,
+ CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_CreateUnmappedArgumentsObject()
{
as->prepareCallWithArgCount(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_createUnmappedArgumentsObject,
- Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createUnmappedArgumentsObject,
+ CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_CreateRestParameter(int argIndex)
@@ -792,24 +794,24 @@ void BaselineJIT::generate_CreateRestParameter(int argIndex)
as->prepareCallWithArgCount(2);
as->passInt32AsArg(argIndex, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_createRestParameter, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createRestParameter, CallResultDestination::InAccumulator);
}
void BaselineJIT::generate_ConvertThisToObject()
{
as->prepareCallWithArgCount(2);
- as->passRegAsArg(CallData::This, 1);
+ as->passJSSlotAsArg(CallData::This, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::convertThisToObject, Assembler::IgnoreResult);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::convertThisToObject, CallResultDestination::Ignore);
as->checkException();
}
void BaselineJIT::generate_LoadSuperConstructor()
{
as->prepareCallWithArgCount(2);
- as->passRegAsArg(CallData::Function, 1);
+ as->passJSSlotAsArg(CallData::Function, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::loadSuperConstructor, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::loadSuperConstructor, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -819,7 +821,7 @@ void BaselineJIT::generate_ToObject()
as->prepareCallWithArgCount(2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::toObject, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::toObject, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -848,9 +850,9 @@ void BaselineJIT::generate_CmpIn(int lhs)
STORE_ACC();
as->prepareCallWithArgCount(3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(lhs, 1);
+ as->passJSSlotAsArg(lhs, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_in, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_in, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -859,9 +861,9 @@ void BaselineJIT::generate_CmpInstanceOf(int lhs)
STORE_ACC();
as->prepareCallWithArgCount(3);
as->passAccumulatorAsArg(2);
- as->passRegAsArg(lhs, 1);
+ as->passJSSlotAsArg(lhs, 1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_instanceof, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_instanceof, CallResultDestination::InAccumulator);
as->checkException();
}
@@ -892,8 +894,8 @@ void BaselineJIT::generate_Exp(int lhs) {
STORE_ACC();
as->prepareCallWithArgCount(2);
as->passAccumulatorAsArg(1);
- as->passRegAsArg(lhs, 0);
- JIT_GENERATE_RUNTIME_CALL(Helpers::exp, Assembler::ResultInAccumulator);
+ as->passJSSlotAsArg(lhs, 0);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::exp, CallResultDestination::InAccumulator);
as->checkException();
}
void BaselineJIT::generate_Mul(int lhs) { as->mul(lhs); }
@@ -909,7 +911,7 @@ void BaselineJIT::generate_Sub(int lhs) { as->sub(lhs); }
// as->passAccumulatorAsArg(2);
// as->passRegAsArg(lhs, 1);
// as->passEngineAsArg(0);
-// as->callRuntime("binopContext", op, Assembler::ResultInAccumulator);
+// as->callRuntime("binopContext", op, CallResultDestination::InAccumulator);
// as->checkException();
//}
@@ -917,7 +919,7 @@ void BaselineJIT::generate_LoadQmlContext(int result)
{
as->prepareCallWithArgCount(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContext, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContext, CallResultDestination::InAccumulator);
as->storeReg(result);
}
@@ -925,7 +927,7 @@ void BaselineJIT::generate_LoadQmlImportedScripts(int result)
{
as->prepareCallWithArgCount(1);
as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlImportedScripts, Assembler::ResultInAccumulator);
+ BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlImportedScripts, CallResultDestination::InAccumulator);
as->storeReg(result);
}
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index 6f066bb9a5..07a1853816 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {
-class Assembler;
+class BaselineAssembler;
#ifdef V4_ENABLE_JIT
class BaselineJIT final: public Moth::ByteCodeHandler
@@ -221,7 +221,7 @@ protected:
private:
QV4::Function *function;
- QScopedPointer<Assembler> as;
+ QScopedPointer<BaselineAssembler> as;
std::vector<int> labels;
};
#endif // V4_ENABLE_JIT
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index b4dac505cd..e812894a97 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -381,7 +381,16 @@ enum class ObjectLiteralArgument {
Setter
};
-}
+namespace JIT {
+
+enum class CallResultDestination {
+ Ignore,
+ InAccumulator,
+};
+
+} // JIT namespace
+
+} // QV4 namespace
Q_DECLARE_TYPEINFO(QV4::PropertyAttributes, Q_PRIMITIVE_TYPE);