aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-12 08:44:09 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-12 23:00:48 +0200
commit8c2201e2e51e9a6c09b4f91c4b4fc09b2c82f4af (patch)
tree6c42cf0bb73da85c1d303cf7e53672c292ae7172 /src/qml/jsruntime
parent53d005693eaba49b90fb636dd420d8993b698b66 (diff)
Implement plain simple locking in the executable memory allocator
Memory allocations may now also happen to come from a separate thread, the QML loader thread where we also compile the JavaScript code and (likely) use the JIT. Commonly that will be the only place where the allocator will be used. The main thread uses the allocator only when an exception is thrown (to look up platform unwind info) or when the garbage collector runs and decides to delete objects that also hold the last reference to executable memory. Change-Id: I8bb710184164cd8d32168449f48d09f7ee828e6e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp10
-rw-r--r--src/qml/jsruntime/qv4executableallocator_p.h3
2 files changed, 13 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index a754663556..2e80f3a611 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -135,6 +135,11 @@ bool ExecutableAllocator::ChunkOfPages::contains(Allocation *alloc) const
return false;
}
+ExecutableAllocator::ExecutableAllocator()
+ : mutex(QMutex::NonRecursive)
+{
+}
+
ExecutableAllocator::~ExecutableAllocator()
{
qDeleteAll(chunks);
@@ -142,6 +147,7 @@ ExecutableAllocator::~ExecutableAllocator()
ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size)
{
+ QMutexLocker locker(&mutex);
Allocation *allocation = 0;
// Code is best aligned to 16-byte boundaries.
@@ -182,6 +188,8 @@ ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size)
void ExecutableAllocator::free(Allocation *allocation)
{
+ QMutexLocker locker(&mutex);
+
assert(allocation);
allocation->free = true;
@@ -210,6 +218,8 @@ void ExecutableAllocator::free(Allocation *allocation)
ExecutableAllocator::ChunkOfPages *ExecutableAllocator::chunkForAllocation(Allocation *allocation) const
{
+ QMutexLocker locker(&mutex);
+
QMap<quintptr, ChunkOfPages*>::ConstIterator it = chunks.lowerBound(allocation->addr);
if (it != chunks.begin())
--it;
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index 2a304baf9c..feba5d7e3d 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -48,6 +48,7 @@
#include <QHash>
#include <QVector>
#include <QByteArray>
+#include <QMutex>
namespace WTF {
class PageAllocation;
@@ -63,6 +64,7 @@ public:
struct ChunkOfPages;
struct Allocation;
+ ExecutableAllocator();
~ExecutableAllocator();
Allocation *allocate(size_t size);
@@ -125,6 +127,7 @@ public:
private:
QMultiMap<size_t, Allocation*> freeAllocations;
QMap<quintptr, ChunkOfPages*> chunks;
+ mutable QMutex mutex;
};
}