aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4compiler.cpp4
-rw-r--r--src/qml/jit/qv4assembler.cpp16
-rw-r--r--src/qml/jit/qv4assembler_p.h25
-rw-r--r--src/qml/jit/qv4binop.cpp8
-rw-r--r--src/qml/jit/qv4isel_masm.cpp43
-rw-r--r--src/qml/jit/qv4isel_masm_p.h1
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4context_p.h8
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4script.cpp1
-rw-r--r--src/qml/jsruntime/qv4script_p.h4
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;
}