#include <private/qv4function_p.h>
#include <private/qv4lookup_p.h>
#include <private/qv4regexpobject_p.h>
+#include <private/qv4unwindhelper_p.h>
namespace QV4 {
namespace CompiledData {
+namespace {
+ bool functionSortHelper(QV4::Function *lhs, QV4::Function *rhs)
+ {
+ return reinterpret_cast<quintptr>(lhs->code) < reinterpret_cast<quintptr>(rhs->code);
+ }
+}
+
CompilationUnit::~CompilationUnit()
{
engine->compilationUnits.erase(engine->compilationUnits.find(this));
}
}
- return linkBackendToEngine(engine);
+ QV4::Function *entry = linkBackendToEngine(engine);
+
+ runtimeFunctionsSortedByAddress.resize(runtimeFunctions.size());
+ memcpy(runtimeFunctionsSortedByAddress.data(), runtimeFunctions.data(), runtimeFunctions.size() * sizeof(QV4::Function*));
+ qSort(runtimeFunctionsSortedByAddress.begin(), runtimeFunctionsSortedByAddress.end(), functionSortHelper);
+
+ return entry;
}
void CompilationUnit::markObjects()
runtimeStrings[i]->mark();
for (int i = 0; i < data->regexpTableSize; ++i)
runtimeRegularExpressions[i].mark();
+ for (int i = 0; i < runtimeFunctions.count(); ++i)
+ runtimeFunctions[i]->mark();
}
}
QV4::Lookup *runtimeLookups;
QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
- QList<QV4::Function *> runtimeFunctions;
+ QVector<QV4::Function *> runtimeFunctions;
+ QVector<QV4::Function *> runtimeFunctionsSortedByAddress;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
using namespace QQmlJS::MASM;
using namespace QV4;
+CompilationUnit::~CompilationUnit()
+{
+ UnwindHelper::deregisterFunctions(runtimeFunctions);
+}
+
QV4::Function *CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
{
QV4::Function *rootRuntimeFunction = 0;
(Value (*)(QV4::ExecutionContext *, const uchar *)) codeRefs[i].code().executableAddress(),
codeRefs[i].size());
- UnwindHelper::registerFunction(runtimeFunction);
-
if (compiledFunction == compiledRootFunction) {
assert(!rootRuntimeFunction);
rootRuntimeFunction = runtimeFunction;
}
}
+ UnwindHelper::registerFunctions(runtimeFunctions);
+
return rootRuntimeFunction;
}
struct CompilationUnit : public QV4::CompiledData::CompilationUnit
{
+ virtual ~CompilationUnit();
+
virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine);
virtual QV4::ExecutableAllocator::ChunkOfPages *chunkForFunction(int functionIndex);
void Debugger::applyPendingBreakPoints()
{
- foreach (Function *function, _engine->functions) {
- m_pendingBreakPointsToAdd.applyToFunction(function, /*removeBreakPoints*/false);
- m_pendingBreakPointsToRemove.applyToFunction(function, /*removeBreakPoints*/true);
+ foreach (QV4::CompiledData::CompilationUnit *unit, _engine->compilationUnits) {
+ foreach (Function *function, unit->runtimeFunctions) {
+ m_pendingBreakPointsToAdd.applyToFunction(function, /*removeBreakPoints*/false);
+ m_pendingBreakPointsToRemove.applyToFunction(function, /*removeBreakPoints*/true);
+ }
}
for (BreakPoints::ConstIterator it = m_pendingBreakPointsToAdd.constBegin(),
, debugger(0)
, globalObject(0)
, globalCode(0)
- , functionsNeedSort(false)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
, regExpCache(0)
, m_multiplyWrappedQObjects(0)
delete identifierTable;
delete bumperPointerAllocator;
delete regExpCache;
- UnwindHelper::deregisterFunctions(functions);
delete regExpAllocator;
delete executableAllocator;
}
Function *ExecutionEngine::newFunction(const QString &name)
{
Function *f = new Function(this, newIdentifier(name));
- functions.append(f);
- functionsNeedSort = true;
return f;
}
c = c->parent;
}
- for (int i = 0; i < functions.size(); ++i)
- functions.at(i)->mark();
-
id_length->mark();
id_prototype->mark();
id_constructor->mark();
}
namespace {
- bool functionSortHelper(Function *lhs, Function *rhs)
- {
- return reinterpret_cast<quintptr>(lhs->code) < reinterpret_cast<quintptr>(rhs->code);
- }
-
struct FindHelper
{
bool operator()(Function *function, quintptr pc)
Function *ExecutionEngine::functionForProgramCounter(quintptr pc) const
{
- if (functionsNeedSort) {
- qSort(functions.begin(), functions.end(), functionSortHelper);
- functionsNeedSort = false;
+ for (QSet<QV4::CompiledData::CompilationUnit*>::ConstIterator unitIt = compilationUnits.constBegin(), unitEnd = compilationUnits.constEnd();
+ unitIt != unitEnd; ++unitIt) {
+ const QVector<Function*> &functions = (*unitIt)->runtimeFunctionsSortedByAddress;
+ QVector<Function*>::ConstIterator it = qBinaryFind(functions.constBegin(),
+ functions.constEnd(),
+ pc, FindHelper());
+ if (it != functions.constEnd())
+ return *it;
}
-
- QVector<Function*>::ConstIterator it = qBinaryFind(functions.constBegin(), functions.constEnd(),
- pc, FindHelper());
- if (it != functions.constEnd())
- return *it;
return 0;
}
String *id_uintMax;
String *id_name;
- mutable QVector<Function *> functions;
- mutable bool functionsNeedSort;
-
QSet<CompiledData::CompilationUnit*> compilationUnits;
quint32 m_engineId;
Function::~Function()
{
- engine->functions.remove(engine->functions.indexOf(this));
- UnwindHelper::deregisterFunction(this); // ### move to masm compilation unit
}
void Function::init(CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Value (*codePtr)(ExecutionContext *, const uchar *),