aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-15 13:15:43 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-23 13:19:01 +0000
commit6f1e2722b9eef73a4fe19951b47c4b172642a2ba (patch)
tree01e58c038a7d63ed9206c834c4f6df1fb51db142
parent3e6d5d9cd1de1373f67f2ff31373a59c37f7b576 (diff)
Simplify Push and PopContext instructions
There's no need for a temp register to store the old context in, as PopContext can simply retrieve the old context from the current one. Change-Id: Ife9cfdff7fa8e47fc71e844a7798de88dbc79e26 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/compiler/qv4codegen.cpp2
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp43
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h4
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h21
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp6
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h8
-rw-r--r--src/qml/jit/qv4assembler.cpp11
-rw-r--r--src/qml/jit/qv4assembler_p.h4
-rw-r--r--src/qml/jit/qv4jit.cpp22
-rw-r--r--src/qml/jit/qv4jit_p.h8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp6
11 files changed, 60 insertions, 75 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index b46891572e..860a1307f2 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2482,7 +2482,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
statementList(body);
- _context->emitBlockFooter(this, -1);
+ _context->emitBlockFooter(this);
if (hasError || !endsWithReturn(_module, body)) {
bytecodeGenerator->setLocation(ast->lastSourceLocation());
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index bfe0d4b131..c4f7e51f6c 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -159,36 +159,32 @@ Context::ResolvedName Context::resolveName(const QString &name)
return result;
}
-int Context::emitBlockHeader(Codegen *codegen)
+void Context::emitBlockHeader(Codegen *codegen)
{
using Instruction = Moth::Instruction;
Moth::BytecodeGenerator *bytecodeGenerator = codegen->generator();
setupFunctionIndices(bytecodeGenerator);
- int contextReg = -1;
- if (requiresExecutionContext && blockIndex < 0) {
- codegen->module()->blocks.append(this);
- blockIndex = codegen->module()->blocks.count() - 1;
- }
+ if (requiresExecutionContext) {
+ if (blockIndex < 0) {
+ codegen->module()->blocks.append(this);
+ blockIndex = codegen->module()->blocks.count() - 1;
+ }
- if (requiresExecutionContext && contextType == ContextType::Global) {
- Instruction::PushScriptContext scriptContext;
- scriptContext.index = blockIndex;
- bytecodeGenerator->addInstruction(scriptContext);
- } else if (requiresExecutionContext ||
- contextType == ContextType::Binding) { // we don't really need this for bindings, but we do for signal handlers, and we don't know if the code is a signal handler or not.
- if (contextType == ContextType::Block || (contextType == ContextType::Eval && !isStrict)) {
+ if (contextType == ContextType::Global) {
+ Instruction::PushScriptContext scriptContext;
+ scriptContext.index = blockIndex;
+ bytecodeGenerator->addInstruction(scriptContext);
+ } else if (contextType == ContextType::Block || (contextType == ContextType::Eval && !isStrict)) {
if (isCatchBlock) {
Instruction::PushCatchContext catchContext;
catchContext.index = blockIndex;
- catchContext.reg = contextReg = bytecodeGenerator->newRegister();
catchContext.name = codegen->registerString(caughtVariable);
bytecodeGenerator->addInstruction(catchContext);
} else {
Instruction::PushBlockContext blockContext;
blockContext.index = blockIndex;
- blockContext.reg = contextReg = bytecodeGenerator->newRegister();
bytecodeGenerator->addInstruction(blockContext);
}
} else {
@@ -196,6 +192,7 @@ int Context::emitBlockHeader(Codegen *codegen)
bytecodeGenerator->addInstruction(createContext);
}
}
+
if (usesThis && !isStrict) {
// make sure we convert this to an object
Instruction::ConvertThisToObject convert;
@@ -250,25 +247,23 @@ int Context::emitBlockHeader(Codegen *codegen)
r.storeConsumeAccumulator();
}
}
-
- return contextReg;
}
-void Context::emitBlockFooter(Codegen *codegen, int oldContextReg)
+void Context::emitBlockFooter(Codegen *codegen)
{
using Instruction = Moth::Instruction;
Moth::BytecodeGenerator *bytecodeGenerator = codegen->generator();
- if (requiresExecutionContext && contextType == ContextType::Global) {
+ if (!requiresExecutionContext)
+ return;
+
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty structs.
+ if (contextType == ContextType::Global)
bytecodeGenerator->addInstruction(Instruction::PopScriptContext());
+ else
+ bytecodeGenerator->addInstruction(Instruction::PopContext());
QT_WARNING_POP
- } else if (oldContextReg != -1) {
- Instruction::PopContext popContext;
- popContext.reg = oldContextReg;
- bytecodeGenerator->addInstruction(popContext);
- }
}
void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 6838610d1c..95fca2c2c8 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -279,8 +279,8 @@ struct Context {
bool isValid() const { return type != Unresolved; }
};
ResolvedName resolveName(const QString &name);
- int emitBlockHeader(Compiler::Codegen *codegen);
- void emitBlockFooter(Compiler::Codegen *codegen, int oldContextReg);
+ void emitBlockHeader(Compiler::Codegen *codegen);
+ void emitBlockFooter(Compiler::Codegen *codegen);
void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator);
};
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
index 89791330f9..db109533eb 100644
--- a/src/qml/compiler/qv4compilercontrolflow_p.h
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -306,11 +306,9 @@ struct ControlFlowWith : public ControlFlowUnwind
: ControlFlowUnwind(cg, With)
{
setupExceptionHandler();
- savedContextRegister = Moth::StackSlot::createRegister(generator()->newRegister());
// assumes the with object is in the accumulator
Instruction::PushWithContext pushScope;
- pushScope.reg = savedContextRegister;
generator()->addInstruction(pushScope);
generator()->setExceptionHandler(&unwindLabel);
}
@@ -321,12 +319,10 @@ struct ControlFlowWith : public ControlFlowUnwind
generator()->setExceptionHandler(parentExceptionHandler());
Instruction::PopContext pop;
- pop.reg = savedContextRegister;
generator()->addInstruction(pop);
emitUnwindHandler();
}
- Moth::StackSlot savedContextRegister;
};
struct ControlFlowBlock : public ControlFlowUnwind
@@ -335,9 +331,9 @@ struct ControlFlowBlock : public ControlFlowUnwind
: ControlFlowUnwind(cg, Block)
{
block = cg->enterBlock(ast);
- savedContextRegister = block->emitBlockHeader(cg);
+ block->emitBlockHeader(cg);
- if (savedContextRegister != -1) {
+ if (block->requiresExecutionContext) {
setupExceptionHandler();
generator()->setExceptionHandler(&unwindLabel);
}
@@ -345,24 +341,23 @@ struct ControlFlowBlock : public ControlFlowUnwind
virtual ~ControlFlowBlock() {
// emit code for unwinding
- if (savedContextRegister != -1) {
+ if (block->requiresExecutionContext ) {
unwindLabel.link();
generator()->setExceptionHandler(parentExceptionHandler());
}
- block->emitBlockFooter(cg, savedContextRegister);
+ block->emitBlockFooter(cg);
- if (savedContextRegister != -1)
+ if (block->requiresExecutionContext )
emitUnwindHandler();
cg->leaveBlock();
}
virtual Handler getHandler(HandlerType type, const QString &label = QString()) {
- if (savedContextRegister == -1)
+ if (!block->requiresExecutionContext )
return getParentHandler(type, label);
return ControlFlowUnwind::getHandler(type, label);
}
- int savedContextRegister = -1;
Context *block;
};
@@ -414,7 +409,7 @@ struct ControlFlowCatch : public ControlFlowUnwind
Context *block = cg->enterBlock(catchExpression);
- int savedContextReg = block->emitBlockHeader(cg);
+ block->emitBlockHeader(cg);
// clear the unwind temp for exceptions, we want to resume normal code flow afterwards
Reference::storeConstOnStack(cg, QV4::Encode::undefined(), controlFlowTemp);
@@ -430,7 +425,7 @@ struct ControlFlowCatch : public ControlFlowUnwind
// exceptions inside catch and break/return statements go here
catchUnwindLabel.link();
- block->emitBlockFooter(cg, savedContextReg);
+ block->emitBlockFooter(cg);
cg->leaveBlock();
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 5e7fe816b2..95bc459df0 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -404,15 +404,14 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(CreateCallContext)
MOTH_BEGIN_INSTR(PushCatchContext)
- d << dumpRegister(reg, nFormals) << ", " << index << ", " << name;
+ d << index << ", " << name;
MOTH_END_INSTR(PushCatchContext)
MOTH_BEGIN_INSTR(PushWithContext)
- d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(PushWithContext)
MOTH_BEGIN_INSTR(PushBlockContext)
- d << dumpRegister(reg, nFormals) << ", " << index;
+ d << index;
MOTH_END_INSTR(PushBlockContext)
MOTH_BEGIN_INSTR(CloneBlockContext)
@@ -426,7 +425,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(PopScriptContext)
MOTH_BEGIN_INSTR(PopContext)
- d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(PopContext)
MOTH_BEGIN_INSTR(GetIterator)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 83ff11a128..54a7f5f13e 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -114,13 +114,13 @@ QT_BEGIN_NAMESPACE
#define INSTR_GetException(op) INSTRUCTION(op, GetException, 0)
#define INSTR_SetException(op) INSTRUCTION(op, SetException, 0)
#define INSTR_CreateCallContext(op) INSTRUCTION(op, CreateCallContext, 0)
-#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 3, reg, index, name)
-#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 1, reg)
-#define INSTR_PushBlockContext(op) INSTRUCTION(op, PushBlockContext, 2, reg, index)
+#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2, index, name)
+#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 0)
+#define INSTR_PushBlockContext(op) INSTRUCTION(op, PushBlockContext, 1, index)
#define INSTR_CloneBlockContext(op) INSTRUCTION(op, CloneBlockContext, 0)
#define INSTR_PushScriptContext(op) INSTRUCTION(op, PushScriptContext, 1, index)
#define INSTR_PopScriptContext(op) INSTRUCTION(op, PopScriptContext, 0)
-#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 1, reg)
+#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 0)
#define INSTR_GetIterator(op) INSTRUCTION(op, GetIterator, 1, iterator)
#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 1, value)
#define INSTR_IteratorClose(op) INSTRUCTION(op, IteratorClose, 1, done)
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index 736dfd0908..45dc87db19 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -2241,9 +2241,8 @@ void Assembler::clearExceptionHandler()
pasm()->storePtr(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
}
-void Assembler::pushCatchContext(int reg, int index, int name)
+void Assembler::pushCatchContext(int index, int name)
{
- pasm()->copyReg(pasm()->contextAddress(), regAddr(reg));
prepareCallWithArgCount(3);
passInt32AsArg(name, 2);
passInt32AsArg(index, 1);
@@ -2252,9 +2251,13 @@ void Assembler::pushCatchContext(int reg, int index, int name)
pasm()->storeAccumulator(pasm()->contextAddress());
}
-void Assembler::popContext(int reg)
+void Assembler::popContext()
{
- pasm()->copyReg(regAddr(reg), pasm()->contextAddress());
+ Heap::CallContext ctx;
+ Q_UNUSED(ctx)
+ pasm()->loadPointerFromValue(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
+ pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset));
+ pasm()->storeAccumulator(regAddr(CallData::Context));
}
void Assembler::ret()
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 99ae48e5ed..a1596e1640 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -164,8 +164,8 @@ public:
void setException();
void setExceptionHandler(int offset);
void clearExceptionHandler();
- void pushCatchContext(int reg, int index, int name);
- void popContext(int reg);
+ void pushCatchContext(int index, int name);
+ void popContext();
// other stuff
void ret();
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index 15ece7e903..2bc60bff70 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -617,44 +617,40 @@ void BaselineJIT::generate_CreateCallContext()
as->storeHeapObject(CallData::Context);
}
-void BaselineJIT::generate_PushCatchContext(int reg, int index, int name) { as->pushCatchContext(reg, index, name); }
+void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); }
-static void pushWithContextHelper(ExecutionEngine *engine, QV4::Value *stack, int reg)
+static void pushWithContextHelper(ExecutionEngine *engine, QV4::Value *stack)
{
QV4::Value &accumulator = stack[CallData::Accumulator];
accumulator = accumulator.toObject(engine);
if (engine->hasException)
return;
- stack[reg] = stack[CallData::Context];
ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
stack[CallData::Context] = Runtime::method_createWithContext(c, accumulator);
}
-void BaselineJIT::generate_PushWithContext(int reg)
+void BaselineJIT::generate_PushWithContext()
{
STORE_IP();
as->saveAccumulatorInFrame();
- as->prepareCallWithArgCount(3);
- as->passInt32AsArg(reg, 2);
+ as->prepareCallWithArgCount(2);
as->passRegAsArg(0, 1);
as->passEngineAsArg(0);
JIT_GENERATE_RUNTIME_CALL(pushWithContextHelper, Assembler::IgnoreResult);
as->checkException();
}
-static void pushBlockContextHelper(QV4::Value *stack, int reg, int index)
+static void pushBlockContextHelper(QV4::Value *stack, int index)
{
- stack[reg] = stack[CallData::Context];
ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
stack[CallData::Context] = Runtime::method_createBlockContext(c, index);
}
-void BaselineJIT::generate_PushBlockContext(int reg, int index)
+void BaselineJIT::generate_PushBlockContext(int index)
{
as->saveAccumulatorInFrame();
- as->prepareCallWithArgCount(3);
- as->passInt32AsArg(index, 2);
- as->passInt32AsArg(reg, 1);
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(index, 1);
as->passRegAsArg(0, 0);
JIT_GENERATE_RUNTIME_CALL(pushBlockContextHelper, Assembler::IgnoreResult);
}
@@ -701,7 +697,7 @@ void BaselineJIT::generate_PopScriptContext()
JIT_GENERATE_RUNTIME_CALL(popScriptContextHelper, Assembler::IgnoreResult);
}
-void BaselineJIT::generate_PopContext(int reg) { as->popContext(reg); }
+void BaselineJIT::generate_PopContext() { as->popContext(); }
void BaselineJIT::generate_GetIterator(int iterator)
{
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index d48041d954..8aa0cb430e 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -178,13 +178,13 @@ public:
void generate_GetException() override;
void generate_SetException() override;
void generate_CreateCallContext() override;
- void generate_PushCatchContext(int reg, int index, int name) override;
- void generate_PushWithContext(int reg) override;
- void generate_PushBlockContext(int reg, int index) override;
+ void generate_PushCatchContext(int index, int name) override;
+ void generate_PushWithContext() override;
+ void generate_PushBlockContext(int index) override;
void generate_CloneBlockContext() override;
void generate_PushScriptContext(int index) override;
void generate_PopScriptContext() override;
- void generate_PopContext(int reg) override;
+ void generate_PopContext() override;
void generate_GetIterator(int iterator) override;
void generate_IteratorNext(int value) override;
void generate_IteratorClose(int done) override;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index f39fd39a98..84d5d6e6e4 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -909,7 +909,6 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code)
MOTH_END_INSTR(SetException)
MOTH_BEGIN_INSTR(PushCatchContext)
- STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
STACK_VALUE(CallData::Context) = Runtime::method_createCatchContext(c, index, name);
MOTH_END_INSTR(PushCatchContext)
@@ -923,14 +922,12 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code)
STORE_ACC();
accumulator = accumulator.toObject(engine);
CHECK_EXCEPTION;
- STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
STACK_VALUE(CallData::Context) = Runtime::method_createWithContext(c, accumulator);
MOTH_END_INSTR(PushWithContext)
MOTH_BEGIN_INSTR(PushBlockContext)
STORE_ACC();
- STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
STACK_VALUE(CallData::Context) = Runtime::method_createBlockContext(c, index);
MOTH_END_INSTR(PushBlockContext)
@@ -950,7 +947,8 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code)
MOTH_END_INSTR(PopScriptContext)
MOTH_BEGIN_INSTR(PopContext)
- STACK_VALUE(CallData::Context) = STACK_VALUE(reg);
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ STACK_VALUE(CallData::Context) = c->d()->outer;
MOTH_END_INSTR(PopContext)
MOTH_BEGIN_INSTR(GetIterator)