6#include <QLoggingCategory>
10#include <private/qv4function_p.h>
11#include <private/qv4functiontable_p.h>
12#include <private/qv4runtime_p.h>
14#include <assembler/MacroAssemblerCodeRef.h>
15#include <assembler/LinkBuffer.h>
20#undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES
29class QIODevicePrintStream:
public FilePrintStream
31 Q_DISABLE_COPY(QIODevicePrintStream)
34 explicit QIODevicePrintStream(
QIODevice *dest)
42 ~QIODevicePrintStream()
45 void vprintf(
const char*
format, va_list argList)
override WTF_ATTRIBUTE_PRINTF(2, 0)
51 while (written < printed) {
52 const qint64 result = dest->write(
buf.constData() + written, printed - written);
60 memset(
buf.data(), 0,
size_t(written));
72static void printDisassembledOutputWithCalls(
QByteArray processedOutput,
81 idx = processedOutput.
indexOf(ptrString, idx);
84 idx = processedOutput.
indexOf(
'\n', idx);
87 const char *functionName =
it.value();
88 processedOutput = processedOutput.
insert(
90 functionName ? functionName : symbols[
it.
key()])));
94 auto lines = processedOutput.
split(
'\n');
95 for (
const auto &
line : lines)
99JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon()
102void PlatformAssemblerCommon::link(
Function *function,
const char *jitKind)
104 for (
const auto &jumpTarget : jumpsToLink)
107 JSC::JSGlobalData dummy(
function->internalClass->engine->executableAllocator);
108 JSC::LinkBuffer<MacroAssembler> linkBuffer(dummy,
this,
nullptr);
110 for (
const auto &ehTarget : ehTargets) {
111 auto targetLabel = labelForOffset.value(ehTarget.offset);
112 linkBuffer.patch(ehTarget.label, linkBuffer.locationOf(targetLabel));
115 JSC::MacroAssemblerCodeRef codeRef;
117 static const bool showCode = lcAsm().isDebugEnabled();
121 WTF::setDataFile(
new QIODevicePrintStream(&
buf));
126 codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind,
name.constData());
128 WTF::setDataFile(stderr);
129 printDisassembledOutputWithCalls(
buf.data(), functions);
131 codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
134 function->codeRef =
new JSC::MacroAssemblerCodeRef(codeRef);
143void PlatformAssemblerCommon::prepareCallWithArgCount(
int argc)
146 Q_ASSERT(remainingArgcForCall == NoCall);
147 remainingArgcForCall = argc;
150 if (argc > ArgInRegCount) {
151 argcOnStackForCall = int(WTF::roundUpToMultipleOf(16,
size_t(argc - ArgInRegCount) * PointerSize));
152 subPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
156void PlatformAssemblerCommon::storeInstructionPointer(
int instructionOffset)
159 store32(TrustedImm32(instructionOffset),
addr);
162PlatformAssemblerCommon::Address PlatformAssemblerCommon::argStackAddress(
int arg)
166 return Address(StackPointerRegister,
offset * PointerSize);
169void PlatformAssemblerCommon::passAccumulatorAsArg(
int arg)
173 --remainingArgcForCall;
176 passAccumulatorAsArg_internal(
arg,
false);
179void JIT::PlatformAssemblerCommon::pushAccumulatorAsArg(
int arg)
181 passAccumulatorAsArg_internal(
arg,
true);
184void PlatformAssemblerCommon::passAccumulatorAsArg_internal(
int arg,
bool doPush)
186 if (
arg < ArgInRegCount) {
187 addPtr(TrustedImm32(offsetof(CallData, accumulator)), JSStackFrameRegister, registerForArg(
arg));
189 addPtr(TrustedImm32(offsetof(CallData, accumulator)), JSStackFrameRegister, ScratchRegister);
191 push(ScratchRegister);
193 storePtr(ScratchRegister, argStackAddress(
arg));
197void PlatformAssemblerCommon::passFunctionAsArg(
int arg)
201 --remainingArgcForCall;
204 if (
arg < ArgInRegCount) {
205 loadFunctionPtr(registerForArg(
arg));
207 loadFunctionPtr(ScratchRegister);
208 storePtr(ScratchRegister, argStackAddress(
arg));
212void PlatformAssemblerCommon::passEngineAsArg(
int arg)
216 --remainingArgcForCall;
219 if (
arg < ArgInRegCount) {
220 move(EngineRegister, registerForArg(
arg));
222 storePtr(EngineRegister, argStackAddress(
arg));
226void PlatformAssemblerCommon::passJSSlotAsArg(
int reg,
int arg)
228 Address
addr(JSStackFrameRegister, reg *
int(
sizeof(
QV4::Value)));
232void JIT::PlatformAssemblerCommon::passAddressAsArg(Address
addr,
int arg)
236 --remainingArgcForCall;
239 if (
arg < ArgInRegCount) {
240 addPtr(TrustedImm32(
addr.offset),
addr.base, registerForArg(
arg));
242 addPtr(TrustedImm32(
addr.offset),
addr.base, ScratchRegister);
243 storePtr(ScratchRegister, argStackAddress(
arg));
247void PlatformAssemblerCommon::passCppFrameAsArg(
int arg)
251 --remainingArgcForCall;
254 if (
arg < ArgInRegCount)
255 move(CppStackFrameRegister, registerForArg(
arg));
257 store32(CppStackFrameRegister, argStackAddress(
arg));
260void PlatformAssemblerCommon::passInt32AsArg(
int value,
int arg)
264 --remainingArgcForCall;
267 if (
arg < ArgInRegCount)
268 move(TrustedImm32(
value), registerForArg(
arg));
270 store32(TrustedImm32(
value), argStackAddress(
arg));
273void JIT::PlatformAssemblerCommon::passPointerAsArg(
void *
ptr,
int arg)
277 --remainingArgcForCall;
280 if (
arg < ArgInRegCount)
281 move(TrustedImmPtr(
ptr), registerForArg(
arg));
283 storePtr(TrustedImmPtr(
ptr), argStackAddress(
arg));
286void PlatformAssemblerCommon::callRuntime(
const void *funcPtr,
const char *functionName)
289 Q_ASSERT(remainingArgcForCall == 0);
290 remainingArgcForCall = NoCall;
292 callRuntimeUnchecked(funcPtr, functionName);
293 if (argcOnStackForCall > 0) {
294 addPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
295 argcOnStackForCall = 0;
299void PlatformAssemblerCommon::callRuntimeUnchecked(
const void *funcPtr,
const char *functionName)
302 functions.
insert(funcPtr, functionName);
303 callAbsolute(funcPtr);
306void PlatformAssemblerCommon::tailCallRuntime(
const void *funcPtr,
const char *functionName)
309 functions.
insert(funcPtr, functionName);
310 setTailCallArg(EngineRegister, 1);
311 setTailCallArg(CppStackFrameRegister, 0);
313 generatePlatformFunctionExit(
true);
314 jumpAbsolute(funcPtr);
317void PlatformAssemblerCommon::setTailCallArg(RegisterID
src,
int arg)
319 if (
arg < ArgInRegCount) {
320 move(
src, registerForArg(
arg));
328JSC::MacroAssemblerBase::Address PlatformAssemblerCommon::jsAlloca(
int slotCount)
330 Address jsStackTopAddr(EngineRegister, offsetof(EngineBase, jsStackTop));
331 RegisterID jsStackTop = AccumulatorRegisterValue;
332 loadPtr(jsStackTopAddr, jsStackTop);
333 addPtr(TrustedImm32(
sizeof(Value) * slotCount), jsStackTop);
334 storePtr(jsStackTop, jsStackTopAddr);
335 return Address(jsStackTop, 0);
338void PlatformAssemblerCommon::storeInt32AsValue(
int srcInt, Address destAddr)
340 store32(TrustedImm32(srcInt),
\inmodule QtCore \reentrant
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray & insert(qsizetype i, QByteArrayView data)
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
\inmodule QtCore \reentrant
QByteArray toUtf8() const &
QSet< QString >::iterator it
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
QTextStream & flush(QTextStream &stream)
Calls QTextStream::flush() on stream and returns stream.
Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static void jump(QtMsgType t, const QMessageLogContext &context, const QString &m)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
static ControlElement< T > * ptr(QWidget *widget)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
static QString prettyName(const Function *function, const void *address)
ReturnedValue(* JittedCode)(CppStackFrame *, ExecutionEngine *)
static QHash< const void *, const char * > symbolTable()