diff options
| author | Lars Knoll <lars.knoll@qt.io> | 2017-06-19 14:04:37 +0200 |
|---|---|---|
| committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-06-20 10:08:36 +0000 |
| commit | 2a612d76550e37d292e724a6873ef31fbb2f6710 (patch) | |
| tree | 67a9b8c1ae41998de7bcb2f9720fd2029eff863e /src/qml/compiler/qv4codegen.cpp | |
| parent | 809d624d0f70874e9acc4617b29f3d97cb27d131 (diff) | |
Handle loads/stores of References better
This is still not ideal and creates too many move
instructions, but at least it avoids repeated loads
and stores into temps to the largest part.
Change-Id: I5286a6598461b229aa12cf88b711922e69f46b70
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
| -rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 143 |
1 files changed, 94 insertions, 49 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index a484892b7c..52bffa53bc 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2320,6 +2320,7 @@ bool Codegen::visit(TypeOfExpression *ast) instr.result = _expr.result.asLValue(); bytecodeGenerator->addInstruction(instr); } + return false; } @@ -3202,6 +3203,47 @@ void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const Q #endif // V4_BOOTSTRAP +Codegen::Reference::Reference(const Codegen::Reference &other) +{ + *this = other; +} + +Codegen::Reference &Codegen::Reference::operator =(const Reference &other) +{ + other.writeBack(); + + type = other.type; + base = other.base; + + switch (type) { + case Invalid: + break; + case Temp: + case Local: + case Argument: + break; + case Name: + case Member: + nameIndex = other.nameIndex; + break; + case Subscript: + subscript = other.subscript; + break; + case Const: + constant = other.constant; + break; + case Closure: + closureId = other.closureId; + break; + } + + // keep loaded reference + tempIndex = other.tempIndex; + needsWriteBack = false; + codegen = other.codegen; + return *this; +} + Codegen::Reference::~Reference() { writeBack(); @@ -3253,20 +3295,17 @@ void Codegen::Reference::storeConsume(Reference &r) const void Codegen::Reference::store(const Reference &r) const { Q_ASSERT(type != Const); + Q_ASSERT(!needsWriteBack); if (*this == r) return; - writeBack(); - Moth::Param b = base; if (!isSimple()) { if (tempIndex < 0) tempIndex = codegen->bytecodeGenerator->newTemp(); if (!r.isSimple() && r.tempIndex == -1) { - r.tempIndex = tempIndex; - r.asRValue(); // trigger load - r.tempIndex = -1; + r.load(tempIndex); needsWriteBack = true; return; } @@ -3291,56 +3330,18 @@ void Codegen::Reference::store(const Reference &r) const Moth::Param Codegen::Reference::asRValue() const { - writeBack(); // because of possible side effects + Q_ASSERT(!needsWriteBack); Q_ASSERT(type != Invalid); if (type <= Argument) return base; // need a temp to hold the value - if (tempIndex < 0) - tempIndex = codegen->bytecodeGenerator->newTemp(); - Moth::Param temp = Moth::Param::createTemp(tempIndex); - if (type == Const) { - Instruction::MoveConst move; - move.source = constant; - move.result = temp; - codegen->bytecodeGenerator->addInstruction(move); - } else if (type == Name) { - Instruction::LoadName load; - load.name = nameIndex; - load.result = temp; - codegen->bytecodeGenerator->addInstruction(load); - } else if (type == Member) { -// if (useFastLookups) { -// Instruction::GetLookup load; -// load.base = getParam(base); -// load.index = registerGetterLookup(name); -// load.result = getResultParam(target); -// addInstruction(load); -// return; -// } - Instruction::LoadProperty load; - load.base = base; - load.name = nameIndex; - load.result = temp; - codegen->bytecodeGenerator->addInstruction(load); - } else if (type == Subscript) { - Instruction::LoadElement load; - load.base = base; - load.index = subscript; - load.result = temp; - codegen->bytecodeGenerator->addInstruction(load); - } else if (type == Closure) { - Instruction::LoadClosure load; - load.value = closureId; - load.result = temp; - codegen->bytecodeGenerator->addInstruction(load); - } else { - Q_ASSERT(false); - Q_UNREACHABLE(); - } - return temp; + if (tempIndex >= 0) + return Moth::Param::createTemp(tempIndex); + tempIndex = codegen->bytecodeGenerator->newTemp(); + load(tempIndex); + return Moth::Param::createTemp(tempIndex); } Moth::Param Codegen::Reference::asLValue() const @@ -3396,3 +3397,47 @@ void Codegen::Reference::writeBack() const Q_UNREACHABLE(); } } + +void Codegen::Reference::load(uint tmp) const +{ + Moth::Param temp = Moth::Param::createTemp(tmp); + if (type == Const) { + Instruction::MoveConst move; + move.source = constant; + move.result = temp; + codegen->bytecodeGenerator->addInstruction(move); + } else if (type == Name) { + Instruction::LoadName load; + load.name = nameIndex; + load.result = temp; + codegen->bytecodeGenerator->addInstruction(load); + } else if (type == Member) { +// if (useFastLookups) { +// Instruction::GetLookup load; +// load.base = getParam(base); +// load.index = registerGetterLookup(name); +// load.result = getResultParam(target); +// addInstruction(load); +// return; +// } + Instruction::LoadProperty load; + load.base = base; + load.name = nameIndex; + load.result = temp; + codegen->bytecodeGenerator->addInstruction(load); + } else if (type == Subscript) { + Instruction::LoadElement load; + load.base = base; + load.index = subscript; + load.result = temp; + codegen->bytecodeGenerator->addInstruction(load); + } else if (type == Closure) { + Instruction::LoadClosure load; + load.value = closureId; + load.result = temp; + codegen->bytecodeGenerator->addInstruction(load); + } else { + Q_ASSERT(false); + Q_UNREACHABLE(); + } +} |
