diff options
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 16 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 25 | ||||
-rw-r--r-- | src/qml/jit/qv4binop.cpp | 8 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 43 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script_p.h | 4 |
11 files changed, 42 insertions, 74 deletions
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 8503317430..924f2e15e2 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -43,6 +43,7 @@ #include <private/qv4string_p.h> #include <private/qv4value_p.h> #include <private/qv4alloca_p.h> +#include <wtf/MathExtras.h> QV4::Compiler::StringTableGenerator::StringTableGenerator() { @@ -378,6 +379,9 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp nextOffset += unit.regexpTableSize * sizeof(CompiledData::RegExp); unit.constantTableSize = constants.size(); + + // Ensure we load constants from well-aligned addresses into for example SSE registers. + nextOffset = static_cast<quint32>(WTF::roundUpToMultipleOf(16, nextOffset)); unit.offsetToConstantTable = nextOffset; nextOffset += unit.constantTableSize * sizeof(ReturnedValue); diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 08e4f0a8c0..625f5b5e5a 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -148,8 +148,7 @@ bool CompilationUnit::memoryMapCode(QString *errorString) const Assembler::VoidType Assembler::Void; Assembler::Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator) - : _constTable(this) - , _function(function) + : _function(function) , _nextBlock(0) , _executableAllocator(executableAllocator) , _isel(isel) @@ -279,6 +278,19 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s return Pointer(reg, id * sizeof(QV4::String*)); } +Assembler::Address Assembler::loadConstant(IR::Const *c, RegisterID baseReg) +{ + return loadConstant(convertToValue(c), baseReg); +} + +Assembler::Address Assembler::loadConstant(const Primitive &v, RegisterID baseReg) +{ + loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg); + loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg); + const int index = _isel->jsUnitGenerator()->registerConstant(v.asReturnedValue()); + return Address(baseReg, index * sizeof(QV4::Value)); +} + void Assembler::loadStringRef(RegisterID reg, const QString &string) { const int id = _isel->registerString(string); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 669b0b2ff4..d76a21c74c 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -89,7 +89,6 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit // Coderef + execution engine QVector<JSC::MacroAssemblerCodeRef> codeRefs; - QList<QVector<QV4::Primitive> > constantValues; }; struct LookupCall { @@ -297,22 +296,6 @@ public: int savedRegCount; }; - class ConstantTable - { - public: - ConstantTable(Assembler *as): _as(as) {} - - int add(const QV4::Primitive &v); - Address loadValueAddress(IR::Const *c, RegisterID baseReg); - Address loadValueAddress(const QV4::Primitive &v, RegisterID baseReg); - void finalize(JSC::LinkBuffer &linkBuffer, InstructionSelection *isel); - - private: - Assembler *_as; - QVector<QV4::Primitive> _values; - QVector<DataLabelPtr> _toPatch; - }; - struct VoidType { VoidType() {} }; static const VoidType Void; @@ -382,6 +365,8 @@ public: Pointer loadTempAddress(IR::Temp *t); Pointer loadArgLocalAddress(RegisterID baseReg, IR::ArgLocal *al); Pointer loadStringAddress(RegisterID reg, const QString &string); + Address loadConstant(IR::Const *c, RegisterID baseReg); + Address loadConstant(const Primitive &v, RegisterID baseReg); void loadStringRef(RegisterID reg, const QString &string); Pointer stackSlotPointer(IR::Temp *t) const { @@ -1029,7 +1014,7 @@ public: move(TrustedImm64(i), ReturnValueRegister); move64ToDouble(ReturnValueRegister, target); #else - JSC::MacroAssembler::loadDouble(constantTable().loadValueAddress(c, ScratchRegister), target); + JSC::MacroAssembler::loadDouble(loadConstant(c, ScratchRegister), target); #endif return target; } @@ -1093,7 +1078,7 @@ public: // it's not in signed int range, so load it as a double, and truncate it down loadDouble(addr, FPGpr0); - Address inversionAddress = constantTable().loadValueAddress(QV4::Primitive::fromDouble(double(INT_MAX) + 1), scratchReg); + Address inversionAddress = loadConstant(QV4::Primitive::fromDouble(double(INT_MAX) + 1), scratchReg); subDouble(inversionAddress, FPGpr0); Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg); canNeverHappen.link(this); @@ -1111,14 +1096,12 @@ public: void setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave); const StackLayout &stackLayout() const { return *_stackLayout.data(); } - ConstantTable &constantTable() { return _constTable; } Label exceptionReturnLabel; IR::BasicBlock * catchBlock; QVector<Jump> exceptionPropagationJumps; private: QScopedPointer<const StackLayout> _stackLayout; - ConstantTable _constTable; IR::Function *_function; QHash<IR::BasicBlock *, Label> _addrs; QHash<IR::BasicBlock *, QVector<Jump> > _patches; diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index c09fc6fdca..45cc9259c3 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -162,7 +162,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X + constant -> Y = X; Y += [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Assembler::Address addr = as->constantTable().loadValueAddress(c, Assembler::ScratchRegister); + Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister); as->addDouble(addr, targetReg); break; } @@ -184,7 +184,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X * constant -> Y = X; Y *= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Assembler::Address addr = as->constantTable().loadValueAddress(c, Assembler::ScratchRegister); + Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister); as->mulDouble(addr, targetReg); break; } @@ -203,7 +203,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X - constant -> Y = X; Y -= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Assembler::Address addr = as->constantTable().loadValueAddress(c, Assembler::ScratchRegister); + Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister); as->subDouble(addr, targetReg); break; } @@ -231,7 +231,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X / constant -> Y = X; Y /= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Assembler::Address addr = as->constantTable().loadValueAddress(c, Assembler::ScratchRegister); + Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister); as->divDouble(addr, targetReg); break; } diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 4066ab213c..da28df817d 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -177,7 +177,6 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize) linkBuffer.patch(label, linkBuffer.locationOf(target)); } } - _constTable.finalize(linkBuffer, _isel); *codeSize = linkBuffer.offsetOf(endOfCode); @@ -370,16 +369,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; @@ -1719,38 +1708,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) { diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index 4b35a72e01..93453f71be 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -81,7 +81,6 @@ public: virtual void run(int functionIndex); - const void *addConstantTable(QVector<QV4::Primitive> *values); protected: virtual QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep(); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 97b3e26a26..60717c9491 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -73,6 +73,7 @@ Heap::CallContext *ExecutionContext::newCallContext(const FunctionObject *functi c->compilationUnit = function->function()->compilationUnit; c->lookups = c->compilationUnit->runtimeLookups; + c->constantTable = c->compilationUnit->data->constants(); c->locals = (Value *)((quintptr(c + 1) + 7) & ~7); const CompiledData::Function *compiledFunction = function->function()->compiledFunction; @@ -172,6 +173,7 @@ Heap::WithContext::WithContext(ExecutionContext *outerContext, Object *with) outer = outerContext; callData = outer->callData; lookups = outer->lookups; + constantTable = outer->constantTable; compilationUnit = outer->compilationUnit; withObject = with; @@ -184,6 +186,7 @@ Heap::CatchContext::CatchContext(ExecutionContext *outerContext, String *excepti strictMode = outer->strictMode; callData = outer->callData; lookups = outer->lookups; + constantTable = outer->constantTable; compilationUnit = outer->compilationUnit; this->exceptionVarName = exceptionVarName; @@ -197,6 +200,7 @@ Heap::QmlContext::QmlContext(QV4::ExecutionContext *outerContext, QV4::QmlContex strictMode = false; callData = outer->callData; lookups = outer->lookups; + constantTable = outer->constantTable; compilationUnit = outer->compilationUnit; this->qml = qml->d(); diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 2e6773a927..368605ca4a 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -108,6 +108,7 @@ struct ExecutionContext : Base { ExecutionEngine *engine; Pointer<ExecutionContext> outer; Lookup *lookups; + const QV4::Value *constantTable; CompiledData::CompilationUnit *compilationUnit; ContextType type : 8; @@ -118,9 +119,10 @@ struct ExecutionContext : Base { inline ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t) : engine(engine) - , outer(0) - , lookups(0) - , compilationUnit(0) + , outer(nullptr) + , lookups(nullptr) + , constantTable(nullptr) + , compilationUnit(nullptr) , type(t) , strictMode(false) , lineNumber(-1) diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 6b9c552350..805087e389 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -535,6 +535,7 @@ void SimpleScriptFunction::construct(const Managed *that, Scope &scope, CallData ctx.function = f->d(); ctx.compilationUnit = f->function()->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; + ctx.constantTable = ctx.compilationUnit->data->constants(); ctx.outer = f->scope(); ctx.locals = scope.alloc(f->varCount()); for (int i = callData->argc; i < (int)f->formalParameterCount(); ++i) @@ -572,6 +573,7 @@ void SimpleScriptFunction::call(const Managed *that, Scope &scope, CallData *cal ctx.function = f->d(); ctx.compilationUnit = f->function()->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; + ctx.constantTable = ctx.compilationUnit->data->constants(); ctx.outer = f->scope(); ctx.locals = scope.alloc(f->varCount()); for (int i = callData->argc; i < (int)f->formalParameterCount(); ++i) diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index a2e379ec1a..46adaf7e79 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -222,6 +222,7 @@ ReturnedValue Script::run() ContextStateSaver stateSaver(valueScope, scope); scope->d()->strictMode = vmFunction->isStrict(); scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups; + scope->d()->constantTable = vmFunction->compilationUnit->data->constants(); scope->d()->compilationUnit = vmFunction->compilationUnit; return Q_V4_PROFILE(engine, vmFunction); diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index e81bc3049c..2e87a7692b 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -71,6 +71,7 @@ struct ContextStateSaver { Value *savedContext; bool strictMode; Lookup *lookups; + const QV4::Value *constantTable; CompiledData::CompilationUnit *compilationUnit; int lineNumber; @@ -78,6 +79,7 @@ struct ContextStateSaver { : savedContext(scope.alloc(1)) , strictMode(context->d()->strictMode) , lookups(context->d()->lookups) + , constantTable(context->d()->constantTable) , compilationUnit(context->d()->compilationUnit) , lineNumber(context->d()->lineNumber) { @@ -87,6 +89,7 @@ struct ContextStateSaver { : savedContext(scope.alloc(1)) , strictMode(context->strictMode) , lookups(context->lookups) + , constantTable(context->constantTable) , compilationUnit(context->compilationUnit) , lineNumber(context->lineNumber) { @@ -98,6 +101,7 @@ struct ContextStateSaver { Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(savedContext->m()); ctx->strictMode = strictMode; ctx->lookups = lookups; + ctx->constantTable = constantTable; ctx->compilationUnit = compilationUnit; ctx->lineNumber = lineNumber; } |