summaryrefslogtreecommitdiff
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-11 11:26:32 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-12 19:05:44 +0200
commitbf22c55036f6429ccfc849ea71f33e757fae47fa (patch)
tree7f0baad7694255ceeb9c5f50139f51875f771113 /src/qml/compiler
parentb8d0d3cbdd69291bd750912a6d8d6703a7feeb6a (diff)
downloadqtdeclarative-bf22c55036f6429ccfc849ea71f33e757fae47fa.tar.gz
Fix passing of exception table pointers to ARM runtime on unwinding
Our synthetic exception unwind table for ARM is located at (char *)codeStart + function->codeSize; This relies on function->codeSize to contain the number of bytes of instructions the function has, not the size of the MacroAssemblerCodeRef (which contains the size of the entire area). This patch fixes the calculation of function->codeSize and also replaces the QHash for the IR::Function* -> CodeRef mapping in the masm backend with a simple vector that's perfectly sufficient. Bug spotted by Petr Nejedly Change-Id: I78a53599085c613c6d97aa2490922f54e0bb4f63 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp22
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h7
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp3
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_p.cpp4
-rw-r--r--src/qml/compiler/qv4isel_p.h2
6 files changed, 21 insertions, 19 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 54823b3464..d40f3c2ff5 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -80,7 +80,7 @@ void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
QV4::Function *runtimeFunction = new QV4::Function(engine, this, compiledFunction,
(Value (*)(QV4::ExecutionContext *, const uchar *)) codeRefs[i].code().executableAddress(),
- codeRefs[i].size());
+ codeSizes[i]);
runtimeFunctions[i] = runtimeFunction;
}
@@ -465,10 +465,10 @@ void Assembler::recordLineNumber(int lineNumber)
}
-JSC::MacroAssemblerCodeRef Assembler::link()
+JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
{
-#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
Label endOfCode = label();
+#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
// Let the ARM exception table follow right after that
for (int i = 0, nops = UnwindHelper::unwindInfoSize() / 2; i < nops; ++i)
nop();
@@ -519,8 +519,9 @@ JSC::MacroAssemblerCodeRef Assembler::link()
}
_constTable.finalize(linkBuffer, _isel);
+ *codeSize = linkBuffer.offsetOf(endOfCode);
#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
- UnwindHelper::writeARMUnwindInfo(linkBuffer.debugAddress(), linkBuffer.offsetOf(endOfCode));
+ UnwindHelper::writeARMUnwindInfo(linkBuffer.debugAddress(), *codeSize);
#endif
JSC::MacroAssemblerCodeRef codeRef;
@@ -583,6 +584,8 @@ InstructionSelection::InstructionSelection(QV4::ExecutableAllocator *execAllocat
, _as(0)
{
compilationUnit = new CompilationUnit;
+ compilationUnit->codeRefs.resize(module->functions.size());
+ compilationUnit->codeSizes.resize(module->functions.size());
}
InstructionSelection::~InstructionSelection()
@@ -590,8 +593,9 @@ InstructionSelection::~InstructionSelection()
delete _as;
}
-void InstructionSelection::run(V4IR::Function *function)
+void InstructionSelection::run(int functionIndex)
{
+ V4IR::Function *function = irModule->functions[functionIndex];
QVector<Lookup> lookups;
QSet<V4IR::BasicBlock*> reentryBlocks;
qSwap(_function, function);
@@ -679,8 +683,8 @@ void InstructionSelection::run(V4IR::Function *function)
}
}
- JSC::MacroAssemblerCodeRef codeRef =_as->link();
- codeRefs[_function] = codeRef;
+ JSC::MacroAssemblerCodeRef codeRef =_as->link(&compilationUnit->codeSizes[functionIndex]);
+ compilationUnit->codeRefs[functionIndex] = codeRef;
qSwap(_function, function);
qSwap(_reentryBlocks, reentryBlocks);
@@ -701,10 +705,6 @@ void *InstructionSelection::addConstantTable(QVector<Value> *values)
QV4::CompiledData::CompilationUnit *InstructionSelection::backendCompileStep()
{
compilationUnit->data = generateUnit();
- compilationUnit->codeRefs.resize(irModule->functions.size());
- int i = 0;
- foreach (V4IR::Function *irFunction, irModule->functions)
- compilationUnit->codeRefs[i++] = codeRefs[irFunction];
return compilationUnit;
}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index 80e1993f04..aa7ba86dbb 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -73,6 +73,8 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit
QVector<JSC::MacroAssemblerCodeRef> codeRefs;
QList<QVector<QV4::Value> > constantValues;
+ QVector<int> codeSizes; // corresponding to the endOfCode labels. MacroAssemblerCodeRef's size may
+ // be larger, as for example on ARM we append the exception handling table.
};
class Assembler : public JSC::MacroAssembler
@@ -1195,7 +1197,7 @@ public:
return scratchReg;
}
- JSC::MacroAssemblerCodeRef link();
+ JSC::MacroAssemblerCodeRef link(int *codeSize);
void recordLineNumber(int lineNumber);
@@ -1238,7 +1240,7 @@ public:
InstructionSelection(QV4::ExecutableAllocator *execAllocator, V4IR::Module *module);
~InstructionSelection();
- virtual void run(V4IR::Function *function);
+ virtual void run(int functionIndex);
void *addConstantTable(QVector<QV4::Value> *values);
protected:
@@ -1448,7 +1450,6 @@ private:
QSet<V4IR::BasicBlock*> _reentryBlocks;
CompilationUnit *compilationUnit;
- QHash<V4IR::Function*, JSC::MacroAssemblerCodeRef> codeRefs;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 1546f19ec8..8e11fc68d4 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -205,8 +205,9 @@ InstructionSelection::~InstructionSelection()
{
}
-void InstructionSelection::run(V4IR::Function *function)
+void InstructionSelection::run(int functionIndex)
{
+ V4IR::Function *function = irModule->functions[functionIndex];
V4IR::BasicBlock *block = 0, *nextBlock = 0;
QHash<V4IR::BasicBlock *, QVector<ptrdiff_t> > patches;
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index 826d559dbc..435ebc41ca 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -74,7 +74,7 @@ public:
InstructionSelection(QV4::ExecutableAllocator *execAllocator, V4IR::Module *module);
~InstructionSelection();
- virtual void run(V4IR::Function *function);
+ virtual void run(int functionIndex);
protected:
virtual QV4::CompiledData::CompilationUnit *backendCompileStep();
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 66f8ca5327..df879f5796 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -78,8 +78,8 @@ QV4::CompiledData::CompilationUnit *EvalInstructionSelection::compile()
Function *rootFunction = irModule->rootFunction;
if (!rootFunction)
return 0;
- foreach (V4IR::Function *f, irModule->functions)
- run(f);
+ for (int i = 0; i < irModule->functions.size(); ++i)
+ run(i);
return backendCompileStep();
}
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index ef601cd152..450a0f072a 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -70,7 +70,7 @@ public:
void setUseFastLookups(bool b) { useFastLookups = b; }
protected:
- virtual void run(V4IR::Function *function) = 0;
+ virtual void run(int functionIndex) = 0;
virtual QV4::CompiledData::CompilationUnit *backendCompileStep() = 0;
protected: