# Making unwinding through JIT-ed code scalable - Replacing the gcc hooks

DevFeed: [Making unwinding through JIT-ed code scalable - Replacing the gcc hooks](<https://devfeed.tech/articles/making-unwinding-through-jit-ed-code-scalable-replacing-the-gcc-hooks-25080.md>)

Original publisher: [Read original article](<https://databasearchitects.blogspot.com/2022/06/replacinggcchooks.html>)

Author: Thomas Neumann (noreply@blogger.com)

Published: 2022-06-26T08:48:00Z

Content type: article

Language: en

Sources: [Database Architects](<https://devfeed.tech/sources/database-architects.md>)

Topics: [gcc](<https://devfeed.tech/topics/gcc.md>), [patches](<https://devfeed.tech/topics/patches.md>), [JIT](<https://devfeed.tech/topics/jit.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [jit](<https://devfeed.tech/tags/jit.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [mutex](<https://devfeed.tech/tags/mutex.md>), [patches](<https://devfeed.tech/tags/patches.md>)

## AI overview

This article explains patches to GCC that replace a globally locked list of unwinding frames with a read-optimized B-tree. The change enables concurrent registration, deregistration, and lock-free lookups, while keeping frames immutable during unwinding on platforms that support atomics.

## Source excerpt

This article is part of the series about scalable unwinding that starts here. As discussed in the previous article, the gcc mechanism does not scale because it uses a global lock to protect its list of unwinding frames. To solve that problem, we replace that list with a read-optimized b-tree that allows for concurrent reads and writes. In this article we just discuss the patches to gcc necessary to enable that mechanism, the b-tree itself is discussed in subsequent articles. We start by replacing the old fast path mechanism with a b-tree root: index 8ee55be5675..d546b9e4c43 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -42,15 +42,34 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif #endif +#ifdef ATOMIC_FDE_FAST_PATH +#include "unwind-dw2-btree.h" + +static struct btree registered_frames; + +static void +release_registered_frames (void) __attribute__ ((destructor (110))); +static void +release_registered_frames (void) +{ + /* Release the b-tree and all frames. Frame releases that happen later are + * silently ignored */ + btree_destroy (&registered_frames); +} + +static void +get_pc_range (const struct object *ob, uintptr_t *range); +static void +init_object (struct object *ob); + +#else + /* The unseen_objects list contains objects that have been registered but not yet categorized in any way. The seen_objects list has had its pc_begin and count fields initialized at minimum, and is sorted by decreasing value of pc_begin. */ static struct object *unseen_objects; static struct object *seen_objects; -#ifdef ATOMIC_FDE_FAST_PATH -static int any_objects_registered; -#endif #ifdef __GTHREAD_MUTEX_INIT static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; @@ -78,6 +97,7 @@ init_object_mutex_once (void) static __gthread_mutex_t object_mutex; #endif #endif +#endif When the platform supports atomics (ATOMIC_FDE_FAST_PATH), we replace the whole mechanism with one b-tree, whose root is registered_frames. Neither the