aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-18 21:13:03 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-20 14:27:24 +0200
commitc392069685c9b6c6dec11cc8f1179a2c4e15be13 (patch)
treeb1b232649bcc566d80cef86577d892edf09ff5f7
parent8c3f133bc34e2c72d4decc0c9af59965d964bbed (diff)
Allow delayed deallocation in the executable memory allocator
Allow for allocations to outlive the allocator itself. When the allocator dies, it invalidates any remaining non-free allocations, making them safe to delete later. Change-Id: I6c71cddbbd5dcaff1ad50f3991a3c710d4f96737 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h2
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp17
-rw-r--r--src/qml/jsruntime/qv4executableallocator_p.h5
3 files changed, 22 insertions, 2 deletions
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index 4e3be7ca4a..a8f54df39f 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -67,7 +67,7 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
}
~ExecutableMemoryHandle()
{
- m_allocator->free(m_allocation);
+ m_allocation->deallocate(m_allocator);
}
inline void shrink(size_t) {
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index 2e80f3a611..e539d62d54 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -52,6 +52,14 @@ void *ExecutableAllocator::Allocation::start() const
return reinterpret_cast<void*>(addr);
}
+void ExecutableAllocator::Allocation::deallocate(ExecutableAllocator *allocator)
+{
+ if (isValid())
+ allocator->free(this);
+ else
+ delete this;
+}
+
ExecutableAllocator::Allocation *ExecutableAllocator::Allocation::split(size_t dividingSize)
{
Allocation *remainder = new Allocation;
@@ -117,7 +125,8 @@ ExecutableAllocator::ChunkOfPages::~ChunkOfPages()
Allocation *alloc = firstAllocation;
while (alloc) {
Allocation *next = alloc->next;
- delete alloc;
+ if (alloc->isValid())
+ delete alloc;
alloc = next;
}
pages->deallocate();
@@ -142,6 +151,12 @@ ExecutableAllocator::ExecutableAllocator()
ExecutableAllocator::~ExecutableAllocator()
{
+ foreach (ChunkOfPages *chunk, chunks) {
+ for (Allocation *allocation = chunk->firstAllocation; allocation; allocation = allocation->next)
+ if (!allocation->free)
+ allocation->invalidate();
+ }
+
qDeleteAll(chunks);
}
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index feba5d7e3d..b4fb2fb0e5 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -81,8 +81,13 @@ public:
{}
void *start() const;
+ void invalidate() { addr = 0; }
+ bool isValid() const { return addr != 0; }
+ void deallocate(ExecutableAllocator *allocator);
private:
+ ~Allocation() {}
+
friend class ExecutableAllocator;
Allocation *split(size_t dividingSize);