aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4isel_masm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jit/qv4isel_masm.cpp')
-rw-r--r--src/qml/jit/qv4isel_masm.cpp275
1 files changed, 121 insertions, 154 deletions
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 859ecfbe64..71069d64a5 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -145,13 +145,10 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
Label endOfCode = label();
{
- QHashIterator<IR::BasicBlock *, QVector<Jump> > it(_patches);
- while (it.hasNext()) {
- it.next();
- IR::BasicBlock *block = it.key();
- Label target = _addrs.value(block);
+ for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
Q_ASSERT(target.isSet());
- foreach (Jump jump, it.value())
+ for (Jump jump : qAsConst(_patches.at(i)))
jump.linkTo(target, this);
}
}
@@ -159,31 +156,21 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
JSC::JSGlobalData dummy(_executableAllocator);
JSC::LinkBuffer linkBuffer(dummy, this, 0);
- QHash<void*, const char*> functions;
- foreach (CallToLink ctl, _callsToLink) {
- linkBuffer.link(ctl.call, ctl.externalFunction);
- functions[linkBuffer.locationOf(ctl.label).dataLocation()] = ctl.functionName;
- }
-
- foreach (const DataLabelPatch &p, _dataLabelPatches)
+ for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
// link exception handlers
- foreach(Jump jump, exceptionPropagationJumps)
+ for (Jump jump : qAsConst(exceptionPropagationJumps))
linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
{
- QHashIterator<IR::BasicBlock *, QVector<DataLabelPtr> > it(_labelPatches);
- while (it.hasNext()) {
- it.next();
- IR::BasicBlock *block = it.key();
- Label target = _addrs.value(block);
+ for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
Q_ASSERT(target.isSet());
- foreach (DataLabelPtr label, it.value())
+ for (DataLabelPtr label : _labelPatches.at(i))
linkBuffer.patch(label, linkBuffer.locationOf(target));
}
}
- _constTable.finalize(linkBuffer, _isel);
*codeSize = linkBuffer.offsetOf(endOfCode);
@@ -193,6 +180,12 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
if (showCode) {
+ QHash<void*, const char*> functions;
+#ifndef QT_NO_DEBUG
+ for (CallInfo call : qAsConst(_callInfos))
+ functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
+#endif
+
QBuffer buf;
buf.open(QIODevice::WriteOnly);
WTF::setDataFile(new QIODevicePrintStream(&buf));
@@ -258,14 +251,15 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
return codeRef;
}
-InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, Compiler::JSUnitGenerator *jsGenerator)
- : EvalInstructionSelection(execAllocator, module, jsGenerator)
+InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
+ : EvalInstructionSelection(execAllocator, module, jsGenerator, iselFactory)
, _block(0)
, _as(0)
, compilationUnit(new CompilationUnit)
, qmlEngine(qmlEngine)
{
compilationUnit->codeRefs.resize(module->functions.size());
+ module->unitFlags |= QV4::CompiledData::Unit::ContainsMachineCode;
}
InstructionSelection::~InstructionSelection()
@@ -344,7 +338,7 @@ void InstructionSelection::run(int functionIndex)
continue;
_as->registerBlock(_block, nextBlock);
- foreach (IR::Stmt *s, _block->statements()) {
+ for (IR::Stmt *s : _block->statements()) {
if (s->location.isValid()) {
if (int(s->location.startLine) != lastLine) {
_as->loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), Assembler::ScratchRegister);
@@ -353,7 +347,7 @@ void InstructionSelection::run(int functionIndex)
lastLine = s->location.startLine;
}
}
- s->accept(this);
+ visit(s);
}
}
@@ -370,16 +364,6 @@ void InstructionSelection::run(int functionIndex)
qSwap(_removableJumps, removableJumps);
}
-const void *InstructionSelection::addConstantTable(QVector<Primitive> *values)
-{
- compilationUnit->constantValues.append(*values);
- values->clear();
-
- QVector<QV4::Primitive> &finalValues = compilationUnit->constantValues.last();
- finalValues.squeeze();
- return finalValues.constData();
-}
-
QQmlRefPointer<QV4::CompiledData::CompilationUnit> InstructionSelection::backendCompileStep()
{
QQmlRefPointer<QV4::CompiledData::CompilationUnit> result;
@@ -393,12 +377,12 @@ void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args
if (useFastLookups && func->global) {
uint index = registerGlobalGetterLookup(*func->id);
- generateFunctionCall(result, Runtime::callGlobalLookup,
+ generateRuntimeCall(result, callGlobalLookup,
Assembler::EngineRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
} else {
- generateFunctionCall(result, Runtime::callActivationProperty,
+ generateRuntimeCall(result, callActivationProperty,
Assembler::EngineRegister,
Assembler::StringToIndex(*func->id),
baseAddressForCallData());
@@ -410,11 +394,11 @@ void InstructionSelection::callBuiltinTypeofQmlContextProperty(IR::Expr *base,
int propertyIndex, IR::Expr *result)
{
if (kind == IR::Member::MemberOfQmlScopeObject) {
- generateFunctionCall(result, Runtime::typeofScopeObjectProperty, Assembler::EngineRegister,
+ generateRuntimeCall(result, typeofScopeObjectProperty, Assembler::EngineRegister,
Assembler::PointerToValue(base),
Assembler::TrustedImm32(propertyIndex));
} else if (kind == IR::Member::MemberOfQmlContextObject) {
- generateFunctionCall(result, Runtime::typeofContextObjectProperty,
+ generateRuntimeCall(result, typeofContextObjectProperty,
Assembler::EngineRegister, Assembler::PointerToValue(base),
Assembler::TrustedImm32(propertyIndex));
} else {
@@ -425,46 +409,46 @@ void InstructionSelection::callBuiltinTypeofQmlContextProperty(IR::Expr *base,
void InstructionSelection::callBuiltinTypeofMember(IR::Expr *base, const QString &name,
IR::Expr *result)
{
- generateFunctionCall(result, Runtime::typeofMember, Assembler::EngineRegister,
+ generateRuntimeCall(result, typeofMember, Assembler::EngineRegister,
Assembler::PointerToValue(base), Assembler::StringToIndex(name));
}
void InstructionSelection::callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index,
IR::Expr *result)
{
- generateFunctionCall(result, Runtime::typeofElement,
+ generateRuntimeCall(result, typeofElement,
Assembler::EngineRegister,
Assembler::PointerToValue(base), Assembler::PointerToValue(index));
}
void InstructionSelection::callBuiltinTypeofName(const QString &name, IR::Expr *result)
{
- generateFunctionCall(result, Runtime::typeofName, Assembler::EngineRegister,
+ generateRuntimeCall(result, typeofName, Assembler::EngineRegister,
Assembler::StringToIndex(name));
}
void InstructionSelection::callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result)
{
- generateFunctionCall(result, Runtime::typeofValue, Assembler::EngineRegister,
+ generateRuntimeCall(result, typeofValue, Assembler::EngineRegister,
Assembler::PointerToValue(value));
}
void InstructionSelection::callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result)
{
- generateFunctionCall(result, Runtime::deleteMember, Assembler::EngineRegister,
+ generateRuntimeCall(result, deleteMember, Assembler::EngineRegister,
Assembler::Reference(base), Assembler::StringToIndex(name));
}
void InstructionSelection::callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index,
IR::Expr *result)
{
- generateFunctionCall(result, Runtime::deleteElement, Assembler::EngineRegister,
+ generateRuntimeCall(result, deleteElement, Assembler::EngineRegister,
Assembler::Reference(base), Assembler::PointerToValue(index));
}
void InstructionSelection::callBuiltinDeleteName(const QString &name, IR::Expr *result)
{
- generateFunctionCall(result, Runtime::deleteName, Assembler::EngineRegister,
+ generateRuntimeCall(result, deleteName, Assembler::EngineRegister,
Assembler::StringToIndex(name));
}
@@ -475,7 +459,7 @@ void InstructionSelection::callBuiltinDeleteValue(IR::Expr *result)
void InstructionSelection::callBuiltinThrow(IR::Expr *arg)
{
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::throwException, Assembler::EngineRegister,
+ generateRuntimeCall(Assembler::ReturnValueRegister, throwException, Assembler::EngineRegister,
Assembler::PointerToValue(arg));
}
@@ -486,13 +470,13 @@ void InstructionSelection::callBuiltinReThrow()
void InstructionSelection::callBuiltinUnwindException(IR::Expr *result)
{
- generateFunctionCall(result, Runtime::unwindException, Assembler::EngineRegister);
+ generateRuntimeCall(result, unwindException, Assembler::EngineRegister);
}
void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionName)
{
- generateFunctionCall(Assembler::Void, Runtime::pushCatchScope, Assembler::EngineRegister, Assembler::StringToIndex(exceptionName));
+ generateRuntimeCall(Assembler::Void, pushCatchScope, Assembler::EngineRegister, Assembler::StringToIndex(exceptionName));
}
void InstructionSelection::callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result)
@@ -500,7 +484,7 @@ void InstructionSelection::callBuiltinForeachIteratorObject(IR::Expr *arg, IR::E
Q_ASSERT(arg);
Q_ASSERT(result);
- generateFunctionCall(result, Runtime::foreachIterator, Assembler::EngineRegister, Assembler::PointerToValue(arg));
+ generateRuntimeCall(result, foreachIterator, Assembler::EngineRegister, Assembler::PointerToValue(arg));
}
void InstructionSelection::callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result)
@@ -508,24 +492,24 @@ void InstructionSelection::callBuiltinForeachNextPropertyname(IR::Expr *arg, IR:
Q_ASSERT(arg);
Q_ASSERT(result);
- generateFunctionCall(result, Runtime::foreachNextPropertyName, Assembler::Reference(arg));
+ generateRuntimeCall(result, foreachNextPropertyName, Assembler::Reference(arg));
}
void InstructionSelection::callBuiltinPushWithScope(IR::Expr *arg)
{
Q_ASSERT(arg);
- generateFunctionCall(Assembler::Void, Runtime::pushWithScope, Assembler::Reference(arg), Assembler::EngineRegister);
+ generateRuntimeCall(Assembler::Void, pushWithScope, Assembler::Reference(arg), Assembler::EngineRegister);
}
void InstructionSelection::callBuiltinPopScope()
{
- generateFunctionCall(Assembler::Void, Runtime::popScope, Assembler::EngineRegister);
+ generateRuntimeCall(Assembler::Void, popScope, Assembler::EngineRegister);
}
void InstructionSelection::callBuiltinDeclareVar(bool deletable, const QString &name)
{
- generateFunctionCall(Assembler::Void, Runtime::declareVar, Assembler::EngineRegister,
+ generateRuntimeCall(Assembler::Void, declareVar, Assembler::EngineRegister,
Assembler::TrustedImm32(deletable), Assembler::StringToIndex(name));
}
@@ -534,7 +518,7 @@ void InstructionSelection::callBuiltinDefineArray(IR::Expr *result, IR::ExprList
Q_ASSERT(result);
int length = prepareVariableArguments(args);
- generateFunctionCall(result, Runtime::arrayLiteral, Assembler::EngineRegister,
+ generateRuntimeCall(result, arrayLiteral, Assembler::EngineRegister,
baseAddressForCallArguments(), Assembler::TrustedImm32(length));
}
@@ -614,19 +598,19 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Expr *result, int
it = it->next;
}
- generateFunctionCall(result, Runtime::objectLiteral, Assembler::EngineRegister,
+ generateRuntimeCall(result, objectLiteral, Assembler::EngineRegister,
baseAddressForCallArguments(), Assembler::TrustedImm32(classId),
Assembler::TrustedImm32(arrayValueCount), Assembler::TrustedImm32(arrayGetterSetterCount | (needSparseArray << 30)));
}
void InstructionSelection::callBuiltinSetupArgumentObject(IR::Expr *result)
{
- generateFunctionCall(result, Runtime::setupArgumentsObject, Assembler::EngineRegister);
+ generateRuntimeCall(result, setupArgumentsObject, Assembler::EngineRegister);
}
void InstructionSelection::callBuiltinConvertThisToObject()
{
- generateFunctionCall(Assembler::Void, Runtime::convertThisToObject, Assembler::EngineRegister);
+ generateRuntimeCall(Assembler::Void, convertThisToObject, Assembler::EngineRegister);
}
void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
@@ -635,11 +619,11 @@ void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Ex
prepareCallData(args, 0);
if (value->asConst())
- generateFunctionCall(result, Runtime::callValue, Assembler::EngineRegister,
+ generateRuntimeCall(result, callValue, Assembler::EngineRegister,
Assembler::PointerToValue(value),
baseAddressForCallData());
else
- generateFunctionCall(result, Runtime::callValue, Assembler::EngineRegister,
+ generateRuntimeCall(result, callValue, Assembler::EngineRegister,
Assembler::Reference(value),
baseAddressForCallData());
}
@@ -659,17 +643,17 @@ void InstructionSelection::loadThisObject(IR::Expr *temp)
void InstructionSelection::loadQmlContext(IR::Expr *temp)
{
- generateFunctionCall(temp, Runtime::getQmlContext, Assembler::EngineRegister);
+ generateRuntimeCall(temp, getQmlContext, Assembler::EngineRegister);
}
void InstructionSelection::loadQmlImportedScripts(IR::Expr *temp)
{
- generateFunctionCall(temp, Runtime::getQmlImportedScripts, Assembler::EngineRegister);
+ generateRuntimeCall(temp, getQmlImportedScripts, Assembler::EngineRegister);
}
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *temp)
{
- generateFunctionCall(temp, Runtime::getQmlSingleton, Assembler::EngineRegister, Assembler::StringToIndex(name));
+ generateRuntimeCall(temp, getQmlSingleton, Assembler::EngineRegister, Assembler::StringToIndex(name));
}
void InstructionSelection::loadConst(IR::Const *sourceConst, IR::Expr *target)
@@ -716,7 +700,7 @@ void InstructionSelection::loadString(const QString &str, IR::Expr *target)
void InstructionSelection::loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target)
{
int id = registerRegExp(sourceRegexp);
- generateFunctionCall(target, Runtime::regexpLiteral, Assembler::EngineRegister, Assembler::TrustedImm32(id));
+ generateRuntimeCall(target, regexpLiteral, Assembler::EngineRegister, Assembler::TrustedImm32(id));
}
void InstructionSelection::getActivationProperty(const IR::Name *name, IR::Expr *target)
@@ -726,20 +710,20 @@ void InstructionSelection::getActivationProperty(const IR::Name *name, IR::Expr
generateLookupCall(target, index, qOffsetOf(QV4::Lookup, globalGetter), Assembler::EngineRegister, Assembler::Void);
return;
}
- generateFunctionCall(target, Runtime::getActivationProperty, Assembler::EngineRegister, Assembler::StringToIndex(*name->id));
+ generateRuntimeCall(target, getActivationProperty, Assembler::EngineRegister, Assembler::StringToIndex(*name->id));
}
void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
{
// ### should use a lookup call here
- generateFunctionCall(Assembler::Void, Runtime::setActivationProperty,
+ generateRuntimeCall(Assembler::Void, setActivationProperty,
Assembler::EngineRegister, Assembler::StringToIndex(targetName), Assembler::PointerToValue(source));
}
void InstructionSelection::initClosure(IR::Closure *closure, IR::Expr *target)
{
int id = closure->value;
- generateFunctionCall(target, Runtime::closure, Assembler::EngineRegister, Assembler::TrustedImm32(id));
+ generateRuntimeCall(target, closure, Assembler::EngineRegister, Assembler::TrustedImm32(id));
}
void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::Expr *target)
@@ -748,19 +732,19 @@ void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::
uint index = registerGetterLookup(name);
generateLookupCall(target, index, qOffsetOf(QV4::Lookup, getter), Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::Void);
} else {
- generateFunctionCall(target, Runtime::getProperty, Assembler::EngineRegister,
+ generateRuntimeCall(target, getProperty, Assembler::EngineRegister,
Assembler::PointerToValue(base), Assembler::StringToIndex(name));
}
}
-void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, IR::Expr *target)
+void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target)
{
if (kind == IR::Member::MemberOfQmlScopeObject)
- generateFunctionCall(target, Runtime::getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
+ generateRuntimeCall(target, getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index), Assembler::TrustedImm32(captureRequired));
else if (kind == IR::Member::MemberOfQmlContextObject)
- generateFunctionCall(target, Runtime::getQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
+ generateRuntimeCall(target, getQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index), Assembler::TrustedImm32(captureRequired));
else if (kind == IR::Member::MemberOfIdObjectsArray)
- generateFunctionCall(target, Runtime::getQmlIdObject, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
+ generateRuntimeCall(target, getQmlIdObject, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
else
Q_ASSERT(false);
}
@@ -768,12 +752,12 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::Mem
void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target)
{
if (attachedPropertiesId != 0)
- generateFunctionCall(target, Runtime::getQmlAttachedProperty, Assembler::EngineRegister, Assembler::TrustedImm32(attachedPropertiesId), Assembler::TrustedImm32(propertyIndex));
+ generateRuntimeCall(target, getQmlAttachedProperty, Assembler::EngineRegister, Assembler::TrustedImm32(attachedPropertiesId), Assembler::TrustedImm32(propertyIndex));
else if (isSingleton)
- generateFunctionCall(target, Runtime::getQmlSingletonQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(propertyIndex),
+ generateRuntimeCall(target, getQmlSingletonQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(propertyIndex),
Assembler::TrustedImm32(captureRequired));
else
- generateFunctionCall(target, Runtime::getQmlQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(propertyIndex),
+ generateRuntimeCall(target, getQmlQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(propertyIndex),
Assembler::TrustedImm32(captureRequired));
}
@@ -787,7 +771,7 @@ void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
Assembler::PointerToValue(targetBase),
Assembler::PointerToValue(source));
} else {
- generateFunctionCall(Assembler::Void, Runtime::setProperty, Assembler::EngineRegister,
+ generateRuntimeCall(Assembler::Void, setProperty, Assembler::EngineRegister,
Assembler::PointerToValue(targetBase), Assembler::StringToIndex(targetName),
Assembler::PointerToValue(source));
}
@@ -796,10 +780,10 @@ void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
void InstructionSelection::setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex)
{
if (kind == IR::Member::MemberOfQmlScopeObject)
- generateFunctionCall(Assembler::Void, Runtime::setQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
+ generateRuntimeCall(Assembler::Void, setQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
else if (kind == IR::Member::MemberOfQmlContextObject)
- generateFunctionCall(Assembler::Void, Runtime::setQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
+ generateRuntimeCall(Assembler::Void, setQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
else
Q_ASSERT(false);
@@ -807,7 +791,7 @@ void InstructionSelection::setQmlContextProperty(IR::Expr *source, IR::Expr *tar
void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex)
{
- generateFunctionCall(Assembler::Void, Runtime::setQmlQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
+ generateRuntimeCall(Assembler::Void, setQmlQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
}
@@ -821,7 +805,7 @@ void InstructionSelection::getElement(IR::Expr *base, IR::Expr *index, IR::Expr
return;
}
- generateFunctionCall(target, Runtime::getElement, Assembler::EngineRegister,
+ generateRuntimeCall(target, getElement, Assembler::EngineRegister,
Assembler::PointerToValue(base), Assembler::PointerToValue(index));
}
@@ -834,7 +818,7 @@ void InstructionSelection::setElement(IR::Expr *source, IR::Expr *targetBase, IR
Assembler::PointerToValue(source));
return;
}
- generateFunctionCall(Assembler::Void, Runtime::setElement, Assembler::EngineRegister,
+ generateRuntimeCall(Assembler::Void, setElement, Assembler::EngineRegister,
Assembler::PointerToValue(targetBase), Assembler::PointerToValue(targetIndex),
Assembler::PointerToValue(source));
}
@@ -981,9 +965,15 @@ void InstructionSelection::swapValues(IR::Expr *source, IR::Expr *target)
}
#define setOp(op, opName, operation) \
- do { op = operation; opName = isel_stringIfy(operation); } while (0)
+ do { \
+ op = RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \
+ needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
+ } while (0)
#define setOpContext(op, opName, operation) \
- do { opContext = operation; opName = isel_stringIfy(operation); } while (0)
+ do { \
+ opContext = RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \
+ needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
+ } while (0)
void InstructionSelection::unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target)
{
@@ -1003,12 +993,12 @@ void InstructionSelection::callQmlContextProperty(IR::Expr *base, IR::Member::Me
prepareCallData(args, base);
if (kind == IR::Member::MemberOfQmlScopeObject)
- generateFunctionCall(result, Runtime::callQmlScopeObjectProperty,
+ generateRuntimeCall(result, callQmlScopeObjectProperty,
Assembler::EngineRegister,
Assembler::TrustedImm32(propertyIndex),
baseAddressForCallData());
else if (kind == IR::Member::MemberOfQmlContextObject)
- generateFunctionCall(result, Runtime::callQmlContextObjectProperty,
+ generateRuntimeCall(result, callQmlContextObjectProperty,
Assembler::EngineRegister,
Assembler::TrustedImm32(propertyIndex),
baseAddressForCallData());
@@ -1025,12 +1015,12 @@ void InstructionSelection::callProperty(IR::Expr *base, const QString &name, IR:
if (useFastLookups) {
uint index = registerGetterLookup(name);
- generateFunctionCall(result, Runtime::callPropertyLookup,
+ generateRuntimeCall(result, callPropertyLookup,
Assembler::EngineRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
} else {
- generateFunctionCall(result, Runtime::callProperty, Assembler::EngineRegister,
+ generateRuntimeCall(result, callProperty, Assembler::EngineRegister,
Assembler::StringToIndex(name),
baseAddressForCallData());
}
@@ -1042,7 +1032,7 @@ void InstructionSelection::callSubscript(IR::Expr *base, IR::Expr *index, IR::Ex
Q_ASSERT(base != 0);
prepareCallData(args, base);
- generateFunctionCall(result, Runtime::callElement, Assembler::EngineRegister,
+ generateRuntimeCall(result, callElement, Assembler::EngineRegister,
Assembler::PointerToValue(index),
baseAddressForCallData());
}
@@ -1118,7 +1108,7 @@ void InstructionSelection::convertTypeToDouble(IR::Expr *source, IR::Expr *targe
Assembler::TrustedImm32(Value::NotDouble_Mask));
#endif
- generateFunctionCall(target, Runtime::toDouble, Assembler::PointerToValue(source));
+ generateRuntimeCall(target, toDouble, Assembler::PointerToValue(source));
Assembler::Jump noDoubleDone = _as->jump();
// it is a double:
@@ -1183,7 +1173,7 @@ void InstructionSelection::convertTypeToBool(IR::Expr *source, IR::Expr *target)
case IR::StringType:
case IR::VarType:
default:
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toBoolean,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toBoolean,
Assembler::PointerToValue(source));
_as->storeBool(Assembler::ReturnValueRegister, target);
break;
@@ -1220,7 +1210,7 @@ void InstructionSelection::convertTypeToSInt32(IR::Expr *source, IR::Expr *targe
// not an int:
fallback.link(_as);
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toInt,
_as->loadAddress(Assembler::ScratchRegister, source));
isIntConvertible.link(_as);
@@ -1258,7 +1248,7 @@ void InstructionSelection::convertTypeToSInt32(IR::Expr *source, IR::Expr *targe
// not an int:
fallback.link(_as);
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toInt,
_as->loadAddress(Assembler::ScratchRegister, source));
_as->storeInt32(Assembler::ReturnValueRegister, target);
@@ -1271,7 +1261,7 @@ void InstructionSelection::convertTypeToSInt32(IR::Expr *source, IR::Expr *targe
_as->branchTruncateDoubleToInt32(_as->toDoubleRegister(source),
Assembler::ReturnValueRegister,
Assembler::BranchIfTruncateSuccessful);
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::doubleToInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, doubleToInt,
Assembler::PointerToValue(source));
success.link(_as);
_as->storeInt32(Assembler::ReturnValueRegister, target);
@@ -1289,7 +1279,7 @@ void InstructionSelection::convertTypeToSInt32(IR::Expr *source, IR::Expr *targe
break;
case IR::StringType:
default:
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toInt,
_as->loadAddress(Assembler::ScratchRegister, source));
_as->storeInt32(Assembler::ReturnValueRegister, target);
break;
@@ -1314,7 +1304,7 @@ void InstructionSelection::convertTypeToUInt32(IR::Expr *source, IR::Expr *targe
// not an int:
isNoInt.link(_as);
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toUInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toUInt,
_as->loadAddress(Assembler::ScratchRegister, source));
_as->storeInt32(Assembler::ReturnValueRegister, target);
@@ -1325,7 +1315,7 @@ void InstructionSelection::convertTypeToUInt32(IR::Expr *source, IR::Expr *targe
Assembler::Jump success =
_as->branchTruncateDoubleToUint32(reg, Assembler::ReturnValueRegister,
Assembler::BranchIfTruncateSuccessful);
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::doubleToUInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, doubleToUInt,
Assembler::PointerToValue(source));
success.link(_as);
_as->storeUInt32(Assembler::ReturnValueRegister, target);
@@ -1336,7 +1326,7 @@ void InstructionSelection::convertTypeToUInt32(IR::Expr *source, IR::Expr *targe
_as->storeUInt32(Assembler::ReturnValueRegister, target);
break;
case IR::StringType:
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toUInt,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toUInt,
Assembler::PointerToValue(source));
_as->storeUInt32(Assembler::ReturnValueRegister, target);
break;
@@ -1356,13 +1346,13 @@ void InstructionSelection::constructActivationProperty(IR::Name *func, IR::ExprL
if (useFastLookups && func->global) {
uint index = registerGlobalGetterLookup(*func->id);
- generateFunctionCall(result, Runtime::constructGlobalLookup,
+ generateRuntimeCall(result, constructGlobalLookup,
Assembler::EngineRegister,
Assembler::TrustedImm32(index), baseAddressForCallData());
return;
}
- generateFunctionCall(result, Runtime::constructActivationProperty,
+ generateRuntimeCall(result, constructActivationProperty,
Assembler::EngineRegister,
Assembler::StringToIndex(*func->id),
baseAddressForCallData());
@@ -1374,14 +1364,14 @@ void InstructionSelection::constructProperty(IR::Expr *base, const QString &name
prepareCallData(args, base);
if (useFastLookups) {
uint index = registerGetterLookup(name);
- generateFunctionCall(result, Runtime::constructPropertyLookup,
+ generateRuntimeCall(result, constructPropertyLookup,
Assembler::EngineRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
return;
}
- generateFunctionCall(result, Runtime::constructProperty, Assembler::EngineRegister,
+ generateRuntimeCall(result, constructProperty, Assembler::EngineRegister,
Assembler::StringToIndex(name),
baseAddressForCallData());
}
@@ -1391,7 +1381,7 @@ void InstructionSelection::constructValue(IR::Expr *value, IR::ExprList *args, I
Q_ASSERT(value != 0);
prepareCallData(args, 0);
- generateFunctionCall(result, Runtime::constructValue,
+ generateRuntimeCall(result, constructValue,
Assembler::EngineRegister,
Assembler::Reference(value),
baseAddressForCallData());
@@ -1427,7 +1417,7 @@ void InstructionSelection::visitCJump(IR::CJump *s)
booleanConversion.link(_as);
reg = Assembler::ReturnValueRegister;
- generateFunctionCall(reg, Runtime::toBoolean, Assembler::Reference(s->cond));
+ generateRuntimeCall(reg, toBoolean, Assembler::Reference(s->cond));
testBoolean.link(_as);
}
@@ -1437,7 +1427,7 @@ void InstructionSelection::visitCJump(IR::CJump *s)
} else if (IR::Const *c = s->cond->asConst()) {
// TODO: SSA optimization for constant condition evaluation should remove this.
// See also visitCJump() in RegAllocInfo.
- generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toBoolean,
+ generateRuntimeCall(Assembler::ReturnValueRegister, toBoolean,
Assembler::PointerToValue(c));
_as->generateCJumpOnNonZero(Assembler::ReturnValueRegister, _block, s->iftrue, s->iffalse);
return;
@@ -1459,21 +1449,22 @@ void InstructionSelection::visitCJump(IR::CJump *s)
return;
}
- Runtime::CompareOperation op = 0;
- Runtime::CompareOperationContext opContext = 0;
+ RuntimeCall op;
+ RuntimeCall opContext;
const char *opName = 0;
+ bool needsExceptionCheck;
switch (b->op) {
default: Q_UNREACHABLE(); Q_ASSERT(!"todo"); break;
- case IR::OpGt: setOp(op, opName, Runtime::compareGreaterThan); break;
- case IR::OpLt: setOp(op, opName, Runtime::compareLessThan); break;
- case IR::OpGe: setOp(op, opName, Runtime::compareGreaterEqual); break;
- case IR::OpLe: setOp(op, opName, Runtime::compareLessEqual); break;
- case IR::OpEqual: setOp(op, opName, Runtime::compareEqual); break;
- case IR::OpNotEqual: setOp(op, opName, Runtime::compareNotEqual); break;
- case IR::OpStrictEqual: setOp(op, opName, Runtime::compareStrictEqual); break;
- case IR::OpStrictNotEqual: setOp(op, opName, Runtime::compareStrictNotEqual); break;
- case IR::OpInstanceof: setOpContext(op, opName, Runtime::compareInstanceof); break;
- case IR::OpIn: setOpContext(op, opName, Runtime::compareIn); break;
+ case IR::OpGt: setOp(op, opName, compareGreaterThan); break;
+ case IR::OpLt: setOp(op, opName, compareLessThan); break;
+ case IR::OpGe: setOp(op, opName, compareGreaterEqual); break;
+ case IR::OpLe: setOp(op, opName, compareLessEqual); break;
+ case IR::OpEqual: setOp(op, opName, compareEqual); break;
+ case IR::OpNotEqual: setOp(op, opName, compareNotEqual); break;
+ case IR::OpStrictEqual: setOp(op, opName, compareStrictEqual); break;
+ case IR::OpStrictNotEqual: setOp(op, opName, compareStrictNotEqual); break;
+ case IR::OpInstanceof: setOpContext(op, opName, compareInstanceof); break;
+ case IR::OpIn: setOpContext(op, opName, compareIn); break;
} // switch
// TODO: in SSA optimization, do constant expression evaluation.
@@ -1481,13 +1472,15 @@ void InstructionSelection::visitCJump(IR::CJump *s)
// if (true === true) .....
// Of course, after folding the CJUMP to a JUMP, dead-code (dead-basic-block)
// elimination (which isn't there either) would remove the whole else block.
- if (opContext)
- _as->generateFunctionCallImp(Assembler::ReturnValueRegister, opName, opContext,
+ if (opContext.isValid())
+ _as->generateFunctionCallImp(needsExceptionCheck,
+ Assembler::ReturnValueRegister, opName, opContext,
Assembler::EngineRegister,
Assembler::PointerToValue(b->left),
Assembler::PointerToValue(b->right));
else
- _as->generateFunctionCallImp(Assembler::ReturnValueRegister, opName, op,
+ _as->generateFunctionCallImp(needsExceptionCheck,
+ Assembler::ReturnValueRegister, opName, op,
Assembler::PointerToValue(b->left),
Assembler::PointerToValue(b->right));
@@ -1695,7 +1688,7 @@ void InstructionSelection::calculateRegistersToSave(const RegisterInformation &u
regularRegistersToSave.clear();
fpRegistersToSave.clear();
- foreach (const RegisterInfo &ri, Assembler::getRegisterInfo()) {
+ for (const RegisterInfo &ri : Assembler::getRegisterInfo()) {
#if defined(RESTORE_EBX_ON_CALL)
if (ri.isRegularRegister() && ri.reg<JSC::X86Registers::RegisterID>() == JSC::X86Registers::ebx) {
regularRegistersToSave.append(ri);
@@ -1724,38 +1717,6 @@ bool operator==(const Primitive &v1, const Primitive &v2)
} // QV4 namespace
QT_END_NAMESPACE
-int Assembler::ConstantTable::add(const Primitive &v)
-{
- int idx = _values.indexOf(v);
- if (idx == -1) {
- idx = _values.size();
- _values.append(v);
- }
- return idx;
-}
-
-Assembler::Address Assembler::ConstantTable::loadValueAddress(IR::Const *c, RegisterID baseReg)
-{
- return loadValueAddress(convertToValue(c), baseReg);
-}
-
-Assembler::Address Assembler::ConstantTable::loadValueAddress(const Primitive &v, RegisterID baseReg)
-{
- _toPatch.append(_as->moveWithPatch(TrustedImmPtr(0), baseReg));
- Address addr(baseReg);
- addr.offset = add(v) * sizeof(QV4::Primitive);
- Q_ASSERT(addr.offset >= 0);
- return addr;
-}
-
-void Assembler::ConstantTable::finalize(JSC::LinkBuffer &linkBuffer, InstructionSelection *isel)
-{
- const void *tablePtr = isel->addConstantTable(&_values);
-
- foreach (DataLabelPtr label, _toPatch)
- linkBuffer.patch(label, const_cast<void *>(tablePtr));
-}
-
bool InstructionSelection::visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Expr *right,
IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
{
@@ -1805,7 +1766,7 @@ void InstructionSelection::visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *tr
IR::Expr *left = binop->left;
IR::Expr *right = binop->right;
- _as->generateFunctionCallImp(Assembler::ReturnValueRegister, "Runtime::compareStrictEqual", Runtime::compareStrictEqual,
+ generateRuntimeCall(Assembler::ReturnValueRegister, compareStrictEqual,
Assembler::PointerToValue(left), Assembler::PointerToValue(right));
_as->generateCJumpOnCompare(binop->op == IR::OpStrictEqual ? Assembler::NotEqual : Assembler::Equal,
Assembler::ReturnValueRegister, Assembler::TrustedImm32(0),
@@ -2006,12 +1967,18 @@ void InstructionSelection::visitCJumpEqual(IR::Binop *binop, IR::BasicBlock *tru
IR::Expr *left = binop->left;
IR::Expr *right = binop->right;
- _as->generateFunctionCallImp(Assembler::ReturnValueRegister, "Runtime::compareEqual", Runtime::compareEqual,
+ generateRuntimeCall(Assembler::ReturnValueRegister, compareEqual,
Assembler::PointerToValue(left), Assembler::PointerToValue(right));
_as->generateCJumpOnCompare(binop->op == IR::OpEqual ? Assembler::NotEqual : Assembler::Equal,
Assembler::ReturnValueRegister, Assembler::TrustedImm32(0),
_block, trueBlock, falseBlock);
}
+QQmlRefPointer<CompiledData::CompilationUnit> ISelFactory::createUnitForLoading()
+{
+ QQmlRefPointer<CompiledData::CompilationUnit> result;
+ result.adopt(new JIT::CompilationUnit);
+ return result;
+}
#endif // ENABLE(ASSEMBLER)