aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-05-12 12:07:15 +0200
committerLars Knoll <lars.knoll@digia.com>2013-05-15 23:34:11 +0200
commit52012a548c030a5d299e0132a01657d848f4289f (patch)
treed0620c787fc0396562d54129ba44a1ca215c95d0 /src/3rdparty
parent69c6209e1c337af1cc55f48c78937083dd2eba7e (diff)
Fix exception handling not working reliably on x86/x86-64 Linux (Part 2)
The registration of the unwind tables is done through the interposition of the _Unwind_Find_FDE symbol from libgcc. Unfortunately that interposition breaks when libgcc happens to come first in the linker scope. As it turns out, the order is not for us to control, therefore the interposition may not always work and our JIT generated functions may not get their unwind information found at exception throwing time. That results in the program aborting with an uncaught exception. The proposed solution of replacing the interposition approach is two-fold: (1) Go back to calling __register_frame explicitly, but only for functions that exception _may_ pass through. In addition the performance of scalability of the objects registered with __register_frame is a known issue upstream, as the LLVM JIT also triggers the issue. It is being tracked at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56460 (2) Instead of registering one FDE per function, we can theoretically register one FDE for _all_ JIT generate functions, because they all use the same stack layout that has exactly the same unwinding requirements from any function call site. Since we can't guarantee the presence of all JIT generated code within the same contiguous memory area, we can at least do it per executable memory allocation chunk (page size). One chunk can contain many functions. This patch implements part (2) by moving the per-function unwind info straight to into the executable memory chunk and registering the entire chunk (page) with libgcc. This also separates the regexp JIT executable memory from regular functions, because only for the memory of the latter we need to register unwind info. Change-Id: Ic4d1978686463c6d319436c9083e4d7cf0409829 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h3
1 files changed, 3 insertions, 0 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;