aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h3
-rw-r--r--src/qml/qml/v4/qv4engine.cpp2
-rw-r--r--src/qml/qml/v4/qv4engine_p.h1
-rw-r--r--src/qml/qml/v4/qv4executableallocator.cpp12
-rw-r--r--src/qml/qml/v4/qv4executableallocator_p.h19
-rw-r--r--src/qml/qml/v4/qv4function_p.h1
-rw-r--r--src/qml/qml/v4/qv4regexp.cpp2
-rw-r--r--src/qml/qml/v4/qv4unwindhelper.cpp4
-rw-r--r--src/qml/qml/v4/qv4unwindhelper_p-arm.h4
-rw-r--r--src/qml/qml/v4/qv4unwindhelper_p-dw2.h90
-rw-r--r--src/qml/qml/v4/qv4unwindhelper_p.h4
11 files changed, 78 insertions, 64 deletions
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index 351851c68d..cd8d3e06f4 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -79,6 +79,9 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
void* start() { return m_allocation->start(); }
int sizeInBytes() { return m_size; }
+ QV4::ExecutableAllocator::ChunkOfPages *chunk() const
+ { return m_allocator->chunkForAllocation(m_allocation); }
+
QV4::ExecutableAllocator *m_allocator;
QV4::ExecutableAllocator::Allocation *m_allocation;
int m_size;
diff --git a/src/qml/qml/v4/qv4engine.cpp b/src/qml/qml/v4/qv4engine.cpp
index 9262436fd1..5adb6dac88 100644
--- a/src/qml/qml/v4/qv4engine.cpp
+++ b/src/qml/qml/v4/qv4engine.cpp
@@ -73,6 +73,7 @@ using namespace QV4;
ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
: memoryManager(new QV4::MemoryManager)
, executableAllocator(new QV4::ExecutableAllocator)
+ , regExpAllocator(new QV4::ExecutableAllocator)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, debugger(0)
, globalObject(0)
@@ -258,6 +259,7 @@ ExecutionEngine::~ExecutionEngine()
UnwindHelper::deregisterFunctions(functions);
qDeleteAll(functions);
delete memoryManager;
+ delete regExpAllocator;
delete executableAllocator;
}
diff --git a/src/qml/qml/v4/qv4engine_p.h b/src/qml/qml/v4/qv4engine_p.h
index 5c556c9d2d..7be77711cc 100644
--- a/src/qml/qml/v4/qv4engine_p.h
+++ b/src/qml/qml/v4/qv4engine_p.h
@@ -111,6 +111,7 @@ struct Q_QML_EXPORT ExecutionEngine
{
MemoryManager *memoryManager;
ExecutableAllocator *executableAllocator;
+ ExecutableAllocator *regExpAllocator;
QScopedPointer<QQmlJS::EvalISelFactory> iselFactory;
ExecutionContext *current;
diff --git a/src/qml/qml/v4/qv4executableallocator.cpp b/src/qml/qml/v4/qv4executableallocator.cpp
index e710eba21b..4c5d238c99 100644
--- a/src/qml/qml/v4/qv4executableallocator.cpp
+++ b/src/qml/qml/v4/qv4executableallocator.cpp
@@ -113,6 +113,7 @@ bool ExecutableAllocator::Allocation::mergePrevious(ExecutableAllocator *allocat
ExecutableAllocator::ChunkOfPages::~ChunkOfPages()
{
+ delete unwindInfo;
Allocation *alloc = firstAllocation;
while (alloc) {
Allocation *next = alloc->next;
@@ -206,3 +207,14 @@ void ExecutableAllocator::free(Allocation *allocation)
return;
}
}
+
+ExecutableAllocator::ChunkOfPages *ExecutableAllocator::chunkForAllocation(Allocation *allocation) const
+{
+ QMap<quintptr, ChunkOfPages*>::ConstIterator it = chunks.lowerBound(allocation->addr);
+ if (it != chunks.begin())
+ --it;
+ if (it == chunks.end())
+ return 0;
+ return *it;
+}
+
diff --git a/src/qml/qml/v4/qv4executableallocator_p.h b/src/qml/qml/v4/qv4executableallocator_p.h
index 0defd984a3..475445cc35 100644
--- a/src/qml/qml/v4/qv4executableallocator_p.h
+++ b/src/qml/qml/v4/qv4executableallocator_p.h
@@ -47,6 +47,7 @@
#include <QMultiMap>
#include <QHash>
#include <QVector>
+#include <QByteArray>
namespace WTF {
class PageAllocation;
@@ -58,8 +59,8 @@ namespace QV4 {
class Q_AUTOTEST_EXPORT ExecutableAllocator
{
- struct ChunkOfPages;
public:
+ struct ChunkOfPages;
struct Allocation;
~ExecutableAllocator();
@@ -97,17 +98,31 @@ public:
int freeAllocationCount() const { return freeAllocations.count(); }
int chunkCount() const { return chunks.count(); }
-private:
+ // Used to store CIE+FDE on x86/x86-64.
+ struct PlatformUnwindInfo
+ {
+ virtual ~PlatformUnwindInfo() {}
+ };
+
struct ChunkOfPages
{
+ ChunkOfPages()
+ : pages(0)
+ , firstAllocation(0)
+ , unwindInfo(0)
+ {}
~ChunkOfPages();
WTF::PageAllocation *pages;
Allocation *firstAllocation;
+ PlatformUnwindInfo *unwindInfo;
bool contains(Allocation *alloc) const;
};
+ ChunkOfPages *chunkForAllocation(Allocation *allocation) const;
+
+private:
QMultiMap<size_t, Allocation*> freeAllocations;
QMap<quintptr, ChunkOfPages*> chunks;
};
diff --git a/src/qml/qml/v4/qv4function_p.h b/src/qml/qml/v4/qv4function_p.h
index c7ae954879..d73dc8d28f 100644
--- a/src/qml/qml/v4/qv4function_p.h
+++ b/src/qml/qml/v4/qv4function_p.h
@@ -86,7 +86,6 @@ struct Function {
const uchar *codeData;
JSC::MacroAssemblerCodeRef codeRef;
quint32 codeSize;
- QByteArray unwindInfo; // CIE+FDE on x86/x86-64. Stored directly in code on ARM.
QVector<String *> formals;
QVector<String *> locals;
diff --git a/src/qml/qml/v4/qv4regexp.cpp b/src/qml/qml/v4/qv4regexp.cpp
index 053a32d6a1..e7e2187a50 100644
--- a/src/qml/qml/v4/qv4regexp.cpp
+++ b/src/qml/qml/v4/qv4regexp.cpp
@@ -112,7 +112,7 @@ RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase,
m_byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator);
#if ENABLE(YARR_JIT)
if (!yarrPattern.m_containsBackreferences && engine->iselFactory->jitCompileRegexps()) {
- JSC::JSGlobalData dummy(engine->executableAllocator);
+ JSC::JSGlobalData dummy(engine->regExpAllocator);
JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, m_jitCode);
}
#endif
diff --git a/src/qml/qml/v4/qv4unwindhelper.cpp b/src/qml/qml/v4/qv4unwindhelper.cpp
index 90750e9fe3..3d54ea277a 100644
--- a/src/qml/qml/v4/qv4unwindhelper.cpp
+++ b/src/qml/qml/v4/qv4unwindhelper.cpp
@@ -31,8 +31,8 @@
using namespace QV4;
void UnwindHelper::ensureUnwindInfo(Function *function) {Q_UNUSED(function);}
void UnwindHelper::registerFunction(Function *function) {Q_UNUSED(function);}
-void UnwindHelper::registerFunctions(QVector<Function *> functions) {Q_UNUSED(functions);}
+void UnwindHelper::registerFunctions(const QVector<Function *> &functions) {Q_UNUSED(functions);}
void UnwindHelper::deregisterFunction(Function *function) {Q_UNUSED(function);}
-void UnwindHelper::deregisterFunctions(QVector<Function *> functions) {Q_UNUSED(functions);}
+void UnwindHelper::deregisterFunctions(const QVector<Function *> &functions) {Q_UNUSED(functions);}
#endif // USE_NULL_HELPER
diff --git a/src/qml/qml/v4/qv4unwindhelper_p-arm.h b/src/qml/qml/v4/qv4unwindhelper_p-arm.h
index 92e38f7c80..7055c3a152 100644
--- a/src/qml/qml/v4/qv4unwindhelper_p-arm.h
+++ b/src/qml/qml/v4/qv4unwindhelper_p-arm.h
@@ -96,7 +96,7 @@ void UnwindHelper::deregisterFunction(Function *function)
allFunctions.remove(reinterpret_cast<quintptr>(function->code));
}
-void UnwindHelper::deregisterFunctions(QVector<Function *> functions)
+void UnwindHelper::deregisterFunctions(const QVector<Function *> &functions)
{
QMutexLocker locker(&functionProtector);
foreach (Function *f, functions)
@@ -109,7 +109,7 @@ void UnwindHelper::registerFunction(Function *function)
allFunctions.insert(reinterpret_cast<quintptr>(function->code), function);
}
-void UnwindHelper::registerFunctions(QVector<Function *> functions)
+void UnwindHelper::registerFunctions(const QVector<Function *> &functions)
{
QMutexLocker locker(&functionProtector);
foreach (Function *f, functions)
diff --git a/src/qml/qml/v4/qv4unwindhelper_p-dw2.h b/src/qml/qml/v4/qv4unwindhelper_p-dw2.h
index 841636d912..0e4296769c 100644
--- a/src/qml/qml/v4/qv4unwindhelper_p-dw2.h
+++ b/src/qml/qml/v4/qv4unwindhelper_p-dw2.h
@@ -5,6 +5,8 @@
#include "qv4functionobject_p.h"
#include "qv4function_p.h"
#include <wtf/Platform.h>
+#include <wtf/PageAllocation.h>
+#include <ExecutableAllocator.h>
#include <QMap>
#include <QMutex>
@@ -45,27 +47,7 @@ static const int fde_offset = 20;
static const int initial_location_offset = 28;
static const int address_range_offset = 32;
#endif
-} // anonymous namespace
-
-static QMutex functionProtector;
-static QMap<quintptr, Function*> allFunctions;
-static Function *lookupFunction(void *pc)
-{
- quintptr key = reinterpret_cast<quintptr>(pc);
- QMap<quintptr, Function*>::ConstIterator it = allFunctions.lowerBound(key);
- if (it != allFunctions.begin() && allFunctions.count() > 0)
- --it;
- if (it == allFunctions.end())
- return 0;
-
- quintptr codeStart = reinterpret_cast<quintptr>((*it)->code);
- if (key < codeStart || key >= codeStart + (*it)->codeSize)
- return 0;
- return *it;
-}
-
-namespace {
void writeIntPtrValue(unsigned char *addr, intptr_t val)
{
addr[0] = (val >> 0) & 0xff;
@@ -84,66 +66,66 @@ void writeIntPtrValue(unsigned char *addr, intptr_t val)
extern "C" void __register_frame(void *fde);
extern "C" void __deregister_frame(void *fde);
+struct UnwindInfo : public ExecutableAllocator::PlatformUnwindInfo
+{
+ UnwindInfo(const QByteArray &cieFde);
+ virtual ~UnwindInfo();
+ QByteArray data;
+};
+
+UnwindInfo::UnwindInfo(const QByteArray &cieFde)
+ : data(cieFde)
+{
+ __register_frame(data.data() + fde_offset);
+}
+
+UnwindInfo::~UnwindInfo()
+{
+ __deregister_frame(data.data() + fde_offset);
+}
+
void UnwindHelper::ensureUnwindInfo(Function *f)
{
if (!f->codeRef)
return; // Not a JIT generated function
- if (!f->unwindInfo.isEmpty())
+
+ JSC::ExecutableMemoryHandle *handle = f->codeRef.executableMemory();
+ if (!handle)
return;
+ ExecutableAllocator::ChunkOfPages *chunk = handle->chunk();
+
+ // Already registered?
+ if (chunk->unwindInfo)
+ return;
+
QByteArray info;
info.resize(sizeof(cie_fde_data));
unsigned char *cie_and_fde = reinterpret_cast<unsigned char *>(info.data());
memcpy(cie_and_fde, cie_fde_data, sizeof(cie_fde_data));
- intptr_t ptr = static_cast<char *>(f->codeRef.code().executableAddress()) - static_cast<char *>(0);
+ intptr_t ptr = static_cast<char *>(chunk->pages->base()) - static_cast<char *>(0);
writeIntPtrValue(cie_and_fde + initial_location_offset, ptr);
- writeIntPtrValue(cie_and_fde + address_range_offset, f->codeSize);
+ writeIntPtrValue(cie_and_fde + address_range_offset, chunk->pages->size());
- f->unwindInfo = info;
- __register_frame(f->unwindInfo.data() + fde_offset);
-}
-
-static void registerFunctionUnlocked(Function *f)
-{
- quintptr addr = reinterpret_cast<quintptr>(f->code);
- if (allFunctions.contains(addr))
- return;
- allFunctions.insert(addr, f);
-}
-
-static void deregisterFunctionUnlocked(Function *f)
-{
- allFunctions.remove(reinterpret_cast<quintptr>(f->code));
- if (!f->unwindInfo.isEmpty())
- __deregister_frame(f->unwindInfo.data() + fde_offset);
+ chunk->unwindInfo = new UnwindInfo(info);
}
-void UnwindHelper::registerFunction(Function *function)
+void UnwindHelper::registerFunction(Function *)
{
- QMutexLocker locker(&functionProtector);
- registerFunctionUnlocked(function);
}
-void UnwindHelper::registerFunctions(QVector<Function *> functions)
+void UnwindHelper::registerFunctions(const QVector<Function *>&)
{
- QMutexLocker locker(&functionProtector);
- foreach (Function *f, functions)
- registerFunctionUnlocked(f);
}
-void UnwindHelper::deregisterFunction(Function *function)
+void UnwindHelper::deregisterFunction(Function *)
{
- QMutexLocker locker(&functionProtector);
- deregisterFunctionUnlocked(function);
}
-void UnwindHelper::deregisterFunctions(QVector<Function *> functions)
+void UnwindHelper::deregisterFunctions(const QVector<Function *> &)
{
- QMutexLocker locker(&functionProtector);
- foreach (Function *f, functions)
- deregisterFunctionUnlocked(f);
}
}
diff --git a/src/qml/qml/v4/qv4unwindhelper_p.h b/src/qml/qml/v4/qv4unwindhelper_p.h
index 72bf56c531..7949278aad 100644
--- a/src/qml/qml/v4/qv4unwindhelper_p.h
+++ b/src/qml/qml/v4/qv4unwindhelper_p.h
@@ -12,9 +12,9 @@ class UnwindHelper
public:
static void ensureUnwindInfo(Function *function);
static void registerFunction(Function *function);
- static void registerFunctions(QVector<Function *> functions);
+ static void registerFunctions(const QVector<Function *> &functions);
static void deregisterFunction(Function *function);
- static void deregisterFunctions(QVector<Function *> functions);
+ static void deregisterFunctions(const QVector<Function *> &functions);
#ifdef Q_PROCESSOR_ARM
static int unwindInfoSize();
static void writeARMUnwindInfo(void *codeAddr, int codeSize);