Home | History | Annotate | Line # | Download | only in libgcc
unwind-dw2-btree.h revision 1.1
      1 /* Lock-free btree for manually registered unwind frames.  */
      2 /* Copyright (C) 2022-2024 Free Software Foundation, Inc.
      3    Contributed by Thomas Neumann
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU General Public License as published by the Free
      9 Software Foundation; either version 3, or (at your option) any later
     10 version.
     11 
     12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 for more details.
     16 
     17 Under Section 7 of GPL version 3, you are granted additional
     18 permissions described in the GCC Runtime Library Exception, version
     19 3.1, as published by the Free Software Foundation.
     20 
     21 You should have received a copy of the GNU General Public License and
     22 a copy of the GCC Runtime Library Exception along with this program;
     23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 <http://www.gnu.org/licenses/>.  */
     25 
     26 #ifndef GCC_UNWIND_DW2_BTREE_H
     27 #define GCC_UNWIND_DW2_BTREE_H
     28 
     29 #include <stdbool.h>
     30 
     31 // Common logic for version locks.
     32 struct version_lock
     33 {
     34   // The lock itself. The lowest bit indicates an exclusive lock,
     35   // the second bit indicates waiting threads. All other bits are
     36   // used as counter to recognize changes.
     37   // Overflows are okay here, we must only prevent overflow to the
     38   // same value within one lock_optimistic/validate
     39   // range. Even on 32 bit platforms that would require 1 billion
     40   // frame registrations within the time span of a few assembler
     41   // instructions.
     42   uintptr_type version_lock;
     43 };
     44 
     45 #ifdef __GTHREAD_HAS_COND
     46 // We should never get contention within the tree as it rarely changes.
     47 // But if we ever do get contention we use these for waiting.
     48 static __gthread_mutex_t version_lock_mutex = __GTHREAD_MUTEX_INIT;
     49 static __gthread_cond_t version_lock_cond = __GTHREAD_COND_INIT;
     50 #endif
     51 
     52 // Initialize in locked state.
     53 static inline void
     54 version_lock_initialize_locked_exclusive (struct version_lock *vl)
     55 {
     56   vl->version_lock = 1;
     57 }
     58 
     59 // Try to lock the node exclusive.
     60 static inline bool
     61 version_lock_try_lock_exclusive (struct version_lock *vl)
     62 {
     63   uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
     64   if (state & 1)
     65     return false;
     66   return __atomic_compare_exchange_n (&(vl->version_lock), &state, state | 1,
     67 				      false, __ATOMIC_SEQ_CST,
     68 				      __ATOMIC_SEQ_CST);
     69 }
     70 
     71 // Lock the node exclusive, blocking as needed.
     72 static void
     73 version_lock_lock_exclusive (struct version_lock *vl)
     74 {
     75 #ifndef __GTHREAD_HAS_COND
     76 restart:
     77 #endif
     78 
     79   // We should virtually never get contention here, as frame
     80   // changes are rare.
     81   uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
     82   if (!(state & 1))
     83     {
     84       if (__atomic_compare_exchange_n (&(vl->version_lock), &state, state | 1,
     85 				       false, __ATOMIC_SEQ_CST,
     86 				       __ATOMIC_SEQ_CST))
     87 	return;
     88     }
     89 
     90     // We did get contention, wait properly.
     91 #ifdef __GTHREAD_HAS_COND
     92   __gthread_mutex_lock (&version_lock_mutex);
     93   state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
     94   while (true)
     95     {
     96       // Check if the lock is still held.
     97       if (!(state & 1))
     98 	{
     99 	  if (__atomic_compare_exchange_n (&(vl->version_lock), &state,
    100 					   state | 1, false, __ATOMIC_SEQ_CST,
    101 					   __ATOMIC_SEQ_CST))
    102 	    {
    103 	      __gthread_mutex_unlock (&version_lock_mutex);
    104 	      return;
    105 	    }
    106 	  else
    107 	    {
    108 	      continue;
    109 	    }
    110 	}
    111 
    112       // Register waiting thread.
    113       if (!(state & 2))
    114 	{
    115 	  if (!__atomic_compare_exchange_n (&(vl->version_lock), &state,
    116 					    state | 2, false, __ATOMIC_SEQ_CST,
    117 					    __ATOMIC_SEQ_CST))
    118 	    continue;
    119 	}
    120 
    121       // And sleep.
    122       __gthread_cond_wait (&version_lock_cond, &version_lock_mutex);
    123       state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
    124     }
    125 #else
    126   // Spin if we do not have condition variables available.
    127   // We expect no contention here, spinning should be okay.
    128   goto restart;
    129 #endif
    130 }
    131 
    132 // Release a locked node and increase the version lock.
    133 static void
    134 version_lock_unlock_exclusive (struct version_lock *vl)
    135 {
    136   // increase version, reset exclusive lock bits
    137   uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
    138   uintptr_type ns = (state + 4) & (~((uintptr_type) 3));
    139   state = __atomic_exchange_n (&(vl->version_lock), ns, __ATOMIC_SEQ_CST);
    140 
    141 #ifdef __GTHREAD_HAS_COND
    142   if (state & 2)
    143     {
    144       // Wake up waiting threads. This should be extremely rare.
    145       __gthread_mutex_lock (&version_lock_mutex);
    146       __gthread_cond_broadcast (&version_lock_cond);
    147       __gthread_mutex_unlock (&version_lock_mutex);
    148     }
    149 #endif
    150 }
    151 
    152 // Acquire an optimistic "lock". Note that this does not lock at all, it
    153 // only allows for validation later.
    154 static inline bool
    155 version_lock_lock_optimistic (const struct version_lock *vl, uintptr_type *lock)
    156 {
    157   uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
    158   *lock = state;
    159 
    160   // Acquiring the lock fails when there is currently an exclusive lock.
    161   return !(state & 1);
    162 }
    163 
    164 // Validate a previously acquired "lock".
    165 static inline bool
    166 version_lock_validate (const struct version_lock *vl, uintptr_type lock)
    167 {
    168   // Prevent the reordering of non-atomic loads behind the atomic load.
    169   // Hans Boehm, Can Seqlocks Get Along with Programming Language Memory
    170   // Models?, Section 4.
    171   __atomic_thread_fence (__ATOMIC_ACQUIRE);
    172 
    173   // Check that the node is still in the same state.
    174   uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
    175   return (state == lock);
    176 }
    177 
    178 // The largest possible separator value.
    179 static const uintptr_type max_separator = ~((uintptr_type) (0));
    180 
    181 struct btree_node;
    182 
    183 // Inner entry. The child tree contains all entries <= separator.
    184 struct inner_entry
    185 {
    186   uintptr_type separator;
    187   struct btree_node *child;
    188 };
    189 
    190 // Leaf entry. Stores an object entry.
    191 struct leaf_entry
    192 {
    193   uintptr_type base, size;
    194   struct object *ob;
    195 };
    196 
    197 // Node types.
    198 enum node_type
    199 {
    200   btree_node_inner,
    201   btree_node_leaf,
    202   btree_node_free
    203 };
    204 
    205 // Node sizes. Chosen such that the result size is roughly 256 bytes.
    206 #define max_fanout_inner 15
    207 #define max_fanout_leaf 10
    208 
    209 // A btree node.
    210 struct btree_node
    211 {
    212   // The version lock used for optimistic lock coupling.
    213   struct version_lock version_lock;
    214   // The number of entries.
    215   unsigned entry_count;
    216   // The type.
    217   enum node_type type;
    218   // The payload.
    219   union
    220   {
    221     // The inner nodes have fence keys, i.e., the right-most entry includes a
    222     // separator.
    223     struct inner_entry children[max_fanout_inner];
    224     struct leaf_entry entries[max_fanout_leaf];
    225   } content;
    226 };
    227 
    228 // Is an inner node?
    229 static inline bool
    230 btree_node_is_inner (const struct btree_node *n)
    231 {
    232   return n->type == btree_node_inner;
    233 }
    234 
    235 // Is a leaf node?
    236 static inline bool
    237 btree_node_is_leaf (const struct btree_node *n)
    238 {
    239   return n->type == btree_node_leaf;
    240 }
    241 
    242 // Should the node be merged?
    243 static inline bool
    244 btree_node_needs_merge (const struct btree_node *n)
    245 {
    246   return n->entry_count < (btree_node_is_inner (n) ? (max_fanout_inner / 2)
    247 						   : (max_fanout_leaf / 2));
    248 }
    249 
    250 // Get the fence key for inner nodes.
    251 static inline uintptr_type
    252 btree_node_get_fence_key (const struct btree_node *n)
    253 {
    254   // For inner nodes we just return our right-most entry.
    255   return n->content.children[n->entry_count - 1].separator;
    256 }
    257 
    258 // Find the position for a slot in an inner node.
    259 static unsigned
    260 btree_node_find_inner_slot (const struct btree_node *n, uintptr_type value)
    261 {
    262   for (unsigned index = 0, ec = n->entry_count; index != ec; ++index)
    263     if (n->content.children[index].separator >= value)
    264       return index;
    265   return n->entry_count;
    266 }
    267 
    268 // Find the position for a slot in a leaf node.
    269 static unsigned
    270 btree_node_find_leaf_slot (const struct btree_node *n, uintptr_type value)
    271 {
    272   for (unsigned index = 0, ec = n->entry_count; index != ec; ++index)
    273     if (n->content.entries[index].base + n->content.entries[index].size > value)
    274       return index;
    275   return n->entry_count;
    276 }
    277 
    278 // Try to lock the node exclusive.
    279 static inline bool
    280 btree_node_try_lock_exclusive (struct btree_node *n)
    281 {
    282   return version_lock_try_lock_exclusive (&(n->version_lock));
    283 }
    284 
    285 // Lock the node exclusive, blocking as needed.
    286 static inline void
    287 btree_node_lock_exclusive (struct btree_node *n)
    288 {
    289   version_lock_lock_exclusive (&(n->version_lock));
    290 }
    291 
    292 // Release a locked node and increase the version lock.
    293 static inline void
    294 btree_node_unlock_exclusive (struct btree_node *n)
    295 {
    296   version_lock_unlock_exclusive (&(n->version_lock));
    297 }
    298 
    299 // Acquire an optimistic "lock". Note that this does not lock at all, it
    300 // only allows for validation later.
    301 static inline bool
    302 btree_node_lock_optimistic (const struct btree_node *n, uintptr_type *lock)
    303 {
    304   return version_lock_lock_optimistic (&(n->version_lock), lock);
    305 }
    306 
    307 // Validate a previously acquire lock.
    308 static inline bool
    309 btree_node_validate (const struct btree_node *n, uintptr_type lock)
    310 {
    311   return version_lock_validate (&(n->version_lock), lock);
    312 }
    313 
    314 // Insert a new separator after splitting.
    315 static void
    316 btree_node_update_separator_after_split (struct btree_node *n,
    317 					 uintptr_type old_separator,
    318 					 uintptr_type new_separator,
    319 					 struct btree_node *new_right)
    320 {
    321   unsigned slot = btree_node_find_inner_slot (n, old_separator);
    322   for (unsigned index = n->entry_count; index > slot; --index)
    323     n->content.children[index] = n->content.children[index - 1];
    324   n->content.children[slot].separator = new_separator;
    325   n->content.children[slot + 1].child = new_right;
    326   n->entry_count++;
    327 }
    328 
    329 // A btree. Suitable for static initialization, all members are zero at the
    330 // beginning.
    331 struct btree
    332 {
    333   // The root of the btree.
    334   struct btree_node *root;
    335   // The free list of released node.
    336   struct btree_node *free_list;
    337   // The version lock used to protect the root.
    338   struct version_lock root_lock;
    339 };
    340 
    341 // Initialize a btree. Not actually used, just for exposition.
    342 static inline void
    343 btree_init (struct btree *t)
    344 {
    345   t->root = NULL;
    346   t->free_list = NULL;
    347   t->root_lock.version_lock = 0;
    348 };
    349 
    350 static void
    351 btree_release_tree_recursively (struct btree *t, struct btree_node *n);
    352 
    353 // Destroy a tree and release all nodes.
    354 static void
    355 btree_destroy (struct btree *t)
    356 {
    357   // Disable the mechanism before cleaning up.
    358   struct btree_node *old_root
    359     = __atomic_exchange_n (&(t->root), NULL, __ATOMIC_SEQ_CST);
    360   if (old_root)
    361     btree_release_tree_recursively (t, old_root);
    362 
    363   // Release all free nodes.
    364   while (t->free_list)
    365     {
    366       struct btree_node *next = t->free_list->content.children[0].child;
    367       free (t->free_list);
    368       t->free_list = next;
    369     }
    370 }
    371 
    372 // Allocate a node. This node will be returned in locked exclusive state.
    373 static struct btree_node *
    374 btree_allocate_node (struct btree *t, bool inner)
    375 {
    376   while (true)
    377     {
    378       // Try the free list first.
    379       struct btree_node *next_free
    380 	= __atomic_load_n (&(t->free_list), __ATOMIC_SEQ_CST);
    381       if (next_free)
    382 	{
    383 	  if (!btree_node_try_lock_exclusive (next_free))
    384 	    continue;
    385 	  // The node might no longer be free, check that again after acquiring
    386 	  // the exclusive lock.
    387 	  if (next_free->type == btree_node_free)
    388 	    {
    389 	      struct btree_node *ex = next_free;
    390 	      if (__atomic_compare_exchange_n (
    391 		    &(t->free_list), &ex, next_free->content.children[0].child,
    392 		    false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
    393 		{
    394 		  next_free->entry_count = 0;
    395 		  next_free->type = inner ? btree_node_inner : btree_node_leaf;
    396 		  return next_free;
    397 		}
    398 	    }
    399 	  btree_node_unlock_exclusive (next_free);
    400 	  continue;
    401 	}
    402 
    403       // No free node available, allocate a new one.
    404       struct btree_node *new_node
    405 	= (struct btree_node *) (malloc (sizeof (struct btree_node)));
    406       version_lock_initialize_locked_exclusive (
    407 	&(new_node->version_lock)); // initialize the node in locked state.
    408       new_node->entry_count = 0;
    409       new_node->type = inner ? btree_node_inner : btree_node_leaf;
    410       return new_node;
    411     }
    412 }
    413 
    414 // Release a node. This node must be currently locked exclusively and will
    415 // be placed in the free list.
    416 static void
    417 btree_release_node (struct btree *t, struct btree_node *node)
    418 {
    419   // We cannot release the memory immediately because there might still be
    420   // concurrent readers on that node. Put it in the free list instead.
    421   node->type = btree_node_free;
    422   struct btree_node *next_free
    423     = __atomic_load_n (&(t->free_list), __ATOMIC_SEQ_CST);
    424   do
    425     {
    426       node->content.children[0].child = next_free;
    427   } while (!__atomic_compare_exchange_n (&(t->free_list), &next_free, node,
    428 					 false, __ATOMIC_SEQ_CST,
    429 					 __ATOMIC_SEQ_CST));
    430   btree_node_unlock_exclusive (node);
    431 }
    432 
    433 // Recursively release a tree. The btree is by design very shallow, thus
    434 // we can risk recursion here.
    435 static void
    436 btree_release_tree_recursively (struct btree *t, struct btree_node *node)
    437 {
    438   btree_node_lock_exclusive (node);
    439   if (btree_node_is_inner (node))
    440     {
    441       for (unsigned index = 0; index < node->entry_count; ++index)
    442 	btree_release_tree_recursively (t, node->content.children[index].child);
    443     }
    444   btree_release_node (t, node);
    445 }
    446 
    447 // Check if we are splitting the root.
    448 static void
    449 btree_handle_root_split (struct btree *t, struct btree_node **node,
    450 			 struct btree_node **parent)
    451 {
    452   // We want to keep the root pointer stable to allow for contention
    453   // free reads. Thus, we split the root by first moving the content
    454   // of the root node to a new node, and then split that new node.
    455   if (!*parent)
    456     {
    457       // Allocate a new node, this guarantees us that we will have a parent
    458       // afterwards.
    459       struct btree_node *new_node
    460 	= btree_allocate_node (t, btree_node_is_inner (*node));
    461       struct btree_node *old_node = *node;
    462       new_node->entry_count = old_node->entry_count;
    463       new_node->content = old_node->content;
    464       old_node->content.children[0].separator = max_separator;
    465       old_node->content.children[0].child = new_node;
    466       old_node->entry_count = 1;
    467       old_node->type = btree_node_inner;
    468 
    469       *parent = old_node;
    470       *node = new_node;
    471     }
    472 }
    473 
    474 // Split an inner node.
    475 static void
    476 btree_split_inner (struct btree *t, struct btree_node **inner,
    477 		   struct btree_node **parent, uintptr_type target,
    478 		   uintptr_type size)
    479 {
    480   // Check for the root.
    481   btree_handle_root_split (t, inner, parent);
    482 
    483   // Create two inner node.
    484   uintptr_type right_fence = btree_node_get_fence_key (*inner);
    485   struct btree_node *left_inner = *inner;
    486   struct btree_node *right_inner = btree_allocate_node (t, true);
    487   unsigned split = left_inner->entry_count / 2;
    488   right_inner->entry_count = left_inner->entry_count - split;
    489   for (unsigned index = 0; index < right_inner->entry_count; ++index)
    490     right_inner->content.children[index]
    491       = left_inner->content.children[split + index];
    492   left_inner->entry_count = split;
    493   uintptr_type left_fence = btree_node_get_fence_key (left_inner);
    494   if (left_fence >= target && left_fence < target + size - 1)
    495     // See the PR119151 comment in btree_insert.
    496     left_fence = target + size - 1;
    497   btree_node_update_separator_after_split (*parent, right_fence, left_fence,
    498 					   right_inner);
    499   if (target <= left_fence)
    500     {
    501       *inner = left_inner;
    502       btree_node_unlock_exclusive (right_inner);
    503     }
    504   else
    505     {
    506       *inner = right_inner;
    507       btree_node_unlock_exclusive (left_inner);
    508     }
    509 }
    510 
    511 // Split a leaf node.
    512 static void
    513 btree_split_leaf (struct btree *t, struct btree_node **leaf,
    514 		  struct btree_node **parent, uintptr_type fence,
    515 		  uintptr_type target)
    516 {
    517   // Check for the root.
    518   btree_handle_root_split (t, leaf, parent);
    519 
    520   // Create two leaf nodes.
    521   uintptr_type right_fence = fence;
    522   struct btree_node *left_leaf = *leaf;
    523   struct btree_node *right_leaf = btree_allocate_node (t, false);
    524   unsigned split = left_leaf->entry_count / 2;
    525   right_leaf->entry_count = left_leaf->entry_count - split;
    526   for (unsigned index = 0; index != right_leaf->entry_count; ++index)
    527     right_leaf->content.entries[index]
    528       = left_leaf->content.entries[split + index];
    529   left_leaf->entry_count = split;
    530   uintptr_type left_fence = right_leaf->content.entries[0].base - 1;
    531   btree_node_update_separator_after_split (*parent, right_fence, left_fence,
    532 					   right_leaf);
    533   if (target <= left_fence)
    534     {
    535       *leaf = left_leaf;
    536       btree_node_unlock_exclusive (right_leaf);
    537     }
    538   else
    539     {
    540       *leaf = right_leaf;
    541       btree_node_unlock_exclusive (left_leaf);
    542     }
    543 }
    544 
    545 // Merge (or balance) child nodes.
    546 static struct btree_node *
    547 btree_merge_node (struct btree *t, unsigned child_slot,
    548 		  struct btree_node *parent, uintptr_type target)
    549 {
    550   // Choose the emptiest neighbor and lock both. The target child is already
    551   // locked.
    552   unsigned left_slot;
    553   struct btree_node *left_node, *right_node;
    554   if ((child_slot == 0)
    555       || (((child_slot + 1) < parent->entry_count)
    556 	  && (parent->content.children[child_slot + 1].child->entry_count
    557 	      < parent->content.children[child_slot - 1].child->entry_count)))
    558     {
    559       left_slot = child_slot;
    560       left_node = parent->content.children[left_slot].child;
    561       right_node = parent->content.children[left_slot + 1].child;
    562       btree_node_lock_exclusive (right_node);
    563     }
    564   else
    565     {
    566       left_slot = child_slot - 1;
    567       left_node = parent->content.children[left_slot].child;
    568       right_node = parent->content.children[left_slot + 1].child;
    569       btree_node_lock_exclusive (left_node);
    570     }
    571 
    572   // Can we merge both nodes into one node?
    573   unsigned total_count = left_node->entry_count + right_node->entry_count;
    574   unsigned max_count
    575     = btree_node_is_inner (left_node) ? max_fanout_inner : max_fanout_leaf;
    576   if (total_count <= max_count)
    577     {
    578       // Merge into the parent?
    579       if (parent->entry_count == 2)
    580 	{
    581 	  // Merge children into parent. This can only happen at the root.
    582 	  if (btree_node_is_inner (left_node))
    583 	    {
    584 	      for (unsigned index = 0; index != left_node->entry_count; ++index)
    585 		parent->content.children[index]
    586 		  = left_node->content.children[index];
    587 	      for (unsigned index = 0; index != right_node->entry_count;
    588 		   ++index)
    589 		parent->content.children[index + left_node->entry_count]
    590 		  = right_node->content.children[index];
    591 	    }
    592 	  else
    593 	    {
    594 	      parent->type = btree_node_leaf;
    595 	      for (unsigned index = 0; index != left_node->entry_count; ++index)
    596 		parent->content.entries[index]
    597 		  = left_node->content.entries[index];
    598 	      for (unsigned index = 0; index != right_node->entry_count;
    599 		   ++index)
    600 		parent->content.entries[index + left_node->entry_count]
    601 		  = right_node->content.entries[index];
    602 	    }
    603 	  parent->entry_count = total_count;
    604 	  btree_release_node (t, left_node);
    605 	  btree_release_node (t, right_node);
    606 	  return parent;
    607 	}
    608       else
    609 	{
    610 	  // Regular merge.
    611 	  if (btree_node_is_inner (left_node))
    612 	    {
    613 	      for (unsigned index = 0; index != right_node->entry_count;
    614 		   ++index)
    615 		left_node->content.children[left_node->entry_count++]
    616 		  = right_node->content.children[index];
    617 	    }
    618 	  else
    619 	    {
    620 	      for (unsigned index = 0; index != right_node->entry_count;
    621 		   ++index)
    622 		left_node->content.entries[left_node->entry_count++]
    623 		  = right_node->content.entries[index];
    624 	    }
    625 	  parent->content.children[left_slot].separator
    626 	    = parent->content.children[left_slot + 1].separator;
    627 	  for (unsigned index = left_slot + 1; index + 1 < parent->entry_count;
    628 	       ++index)
    629 	    parent->content.children[index]
    630 	      = parent->content.children[index + 1];
    631 	  parent->entry_count--;
    632 	  btree_release_node (t, right_node);
    633 	  btree_node_unlock_exclusive (parent);
    634 	  return left_node;
    635 	}
    636     }
    637 
    638   // No merge possible, rebalance instead.
    639   if (left_node->entry_count > right_node->entry_count)
    640     {
    641       // Shift from left to right.
    642       unsigned to_shift
    643 	= (left_node->entry_count - right_node->entry_count) / 2;
    644       if (btree_node_is_inner (left_node))
    645 	{
    646 	  for (unsigned index = 0; index != right_node->entry_count; ++index)
    647 	    {
    648 	      unsigned pos = right_node->entry_count - 1 - index;
    649 	      right_node->content.children[pos + to_shift]
    650 		= right_node->content.children[pos];
    651 	    }
    652 	  for (unsigned index = 0; index != to_shift; ++index)
    653 	    right_node->content.children[index]
    654 	      = left_node->content
    655 		  .children[left_node->entry_count - to_shift + index];
    656 	}
    657       else
    658 	{
    659 	  for (unsigned index = 0; index != right_node->entry_count; ++index)
    660 	    {
    661 	      unsigned pos = right_node->entry_count - 1 - index;
    662 	      right_node->content.entries[pos + to_shift]
    663 		= right_node->content.entries[pos];
    664 	    }
    665 	  for (unsigned index = 0; index != to_shift; ++index)
    666 	    right_node->content.entries[index]
    667 	      = left_node->content
    668 		  .entries[left_node->entry_count - to_shift + index];
    669 	}
    670       left_node->entry_count -= to_shift;
    671       right_node->entry_count += to_shift;
    672     }
    673   else
    674     {
    675       // Shift from right to left.
    676       unsigned to_shift
    677 	= (right_node->entry_count - left_node->entry_count) / 2;
    678       if (btree_node_is_inner (left_node))
    679 	{
    680 	  for (unsigned index = 0; index != to_shift; ++index)
    681 	    left_node->content.children[left_node->entry_count + index]
    682 	      = right_node->content.children[index];
    683 	  for (unsigned index = 0; index != right_node->entry_count - to_shift;
    684 	       ++index)
    685 	    right_node->content.children[index]
    686 	      = right_node->content.children[index + to_shift];
    687 	}
    688       else
    689 	{
    690 	  for (unsigned index = 0; index != to_shift; ++index)
    691 	    left_node->content.entries[left_node->entry_count + index]
    692 	      = right_node->content.entries[index];
    693 	  for (unsigned index = 0; index != right_node->entry_count - to_shift;
    694 	       ++index)
    695 	    right_node->content.entries[index]
    696 	      = right_node->content.entries[index + to_shift];
    697 	}
    698       left_node->entry_count += to_shift;
    699       right_node->entry_count -= to_shift;
    700     }
    701   uintptr_type left_fence;
    702   if (btree_node_is_leaf (left_node))
    703     {
    704       left_fence = right_node->content.entries[0].base - 1;
    705     }
    706   else
    707     {
    708       left_fence = btree_node_get_fence_key (left_node);
    709     }
    710   parent->content.children[left_slot].separator = left_fence;
    711   btree_node_unlock_exclusive (parent);
    712   if (target <= left_fence)
    713     {
    714       btree_node_unlock_exclusive (right_node);
    715       return left_node;
    716     }
    717   else
    718     {
    719       btree_node_unlock_exclusive (left_node);
    720       return right_node;
    721     }
    722 }
    723 
    724 // Insert an entry.
    725 static bool
    726 btree_insert (struct btree *t, uintptr_type base, uintptr_type size,
    727 	      struct object *ob)
    728 {
    729   // Sanity check.
    730   if (!size)
    731     return false;
    732 
    733   // Access the root.
    734   struct btree_node *iter, *parent = NULL;
    735   {
    736     version_lock_lock_exclusive (&(t->root_lock));
    737     iter = t->root;
    738     if (iter)
    739       {
    740 	btree_node_lock_exclusive (iter);
    741       }
    742     else
    743       {
    744 	t->root = iter = btree_allocate_node (t, false);
    745       }
    746     version_lock_unlock_exclusive (&(t->root_lock));
    747   }
    748 
    749   // Walk down the btree with classic lock coupling and eager splits.
    750   // Strictly speaking this is not performance optimal, we could use
    751   // optimistic lock coupling until we hit a node that has to be modified.
    752   // But that is more difficult to implement and frame registration is
    753   // rare anyway, we use simple locking for now.
    754 
    755   uintptr_type fence = max_separator;
    756   while (btree_node_is_inner (iter))
    757     {
    758       // Use eager splits to avoid lock coupling up.
    759       if (iter->entry_count == max_fanout_inner)
    760 	btree_split_inner (t, &iter, &parent, base, size);
    761 
    762       unsigned slot = btree_node_find_inner_slot (iter, base);
    763       if (parent)
    764 	btree_node_unlock_exclusive (parent);
    765       parent = iter;
    766       fence = iter->content.children[slot].separator;
    767       if (fence < base + size - 1)
    768 	// The separator was set to the base - 1 of the leftmost leaf child
    769 	// at some point but such an entry could have been removed afterwards.
    770 	// As both insertion and removal are just walking down the tree with
    771 	// only a few current nodes locked at a time, updating the separator
    772 	// on removal is not possible, especially because btree_remove does
    773 	// not know the size until it reaches leaf node.  We must ensure that
    774 	// the separator is not in a middle of some entry though, as
    775 	// btree_lookup can look up any address in the entry's range and if
    776 	// the separator is in the middle, addresses below it or equal to it
    777 	// would be found while addresses above it would result in failed
    778 	// lookup.  Update the separator now.  Assumption that users
    779 	// ensure no overlapping registered ranges, there should be no
    780 	// current entry for any address in the range.  See PR119151.
    781 	fence = iter->content.children[slot].separator = base + size - 1;
    782       iter = iter->content.children[slot].child;
    783       btree_node_lock_exclusive (iter);
    784     }
    785 
    786   // Make sure we have space.
    787   if (iter->entry_count == max_fanout_leaf)
    788     btree_split_leaf (t, &iter, &parent, fence, base);
    789   if (parent)
    790     btree_node_unlock_exclusive (parent);
    791 
    792   // Insert in node.
    793   unsigned slot = btree_node_find_leaf_slot (iter, base);
    794   if ((slot < iter->entry_count) && (iter->content.entries[slot].base == base))
    795     {
    796       // Duplicate entry, this should never happen.
    797       btree_node_unlock_exclusive (iter);
    798       return false;
    799     }
    800   for (unsigned index = iter->entry_count; index > slot; --index)
    801     iter->content.entries[index] = iter->content.entries[index - 1];
    802   struct leaf_entry *e = &(iter->content.entries[slot]);
    803   e->base = base;
    804   e->size = size;
    805   e->ob = ob;
    806   iter->entry_count++;
    807   btree_node_unlock_exclusive (iter);
    808   return true;
    809 }
    810 
    811 // Remove an entry.
    812 static struct object *
    813 btree_remove (struct btree *t, uintptr_type base)
    814 {
    815   // Access the root.
    816   version_lock_lock_exclusive (&(t->root_lock));
    817   struct btree_node *iter = t->root;
    818   if (iter)
    819     btree_node_lock_exclusive (iter);
    820   version_lock_unlock_exclusive (&(t->root_lock));
    821   if (!iter)
    822     return NULL;
    823 
    824   // Same strategy as with insert, walk down with lock coupling and
    825   // merge eagerly.
    826   while (btree_node_is_inner (iter))
    827     {
    828       unsigned slot = btree_node_find_inner_slot (iter, base);
    829       struct btree_node *next = iter->content.children[slot].child;
    830       btree_node_lock_exclusive (next);
    831       if (btree_node_needs_merge (next))
    832 	{
    833 	  // Use eager merges to avoid lock coupling up.
    834 	  iter = btree_merge_node (t, slot, iter, base);
    835 	}
    836       else
    837 	{
    838 	  btree_node_unlock_exclusive (iter);
    839 	  iter = next;
    840 	}
    841     }
    842 
    843   // Remove existing entry.
    844   unsigned slot = btree_node_find_leaf_slot (iter, base);
    845   if ((slot >= iter->entry_count) || (iter->content.entries[slot].base != base))
    846     {
    847       // Not found, this should never happen.
    848       btree_node_unlock_exclusive (iter);
    849       return NULL;
    850     }
    851   struct object *ob = iter->content.entries[slot].ob;
    852   for (unsigned index = slot; index + 1 < iter->entry_count; ++index)
    853     iter->content.entries[index] = iter->content.entries[index + 1];
    854   iter->entry_count--;
    855   btree_node_unlock_exclusive (iter);
    856   return ob;
    857 }
    858 
    859 // Find the corresponding entry for the given address.
    860 static struct object *
    861 btree_lookup (const struct btree *t, uintptr_type target_addr)
    862 {
    863   // Within this function many loads are relaxed atomic loads.
    864   // Use a macro to keep the code reasonable.
    865 #define RLOAD(x) __atomic_load_n (&(x), __ATOMIC_RELAXED)
    866 
    867   // For targets where unwind info is usually not registered through these
    868   // APIs anymore, avoid any sequential consistent atomics.
    869   // Use relaxed MO here, it is up to the app to ensure that the library
    870   // loading/initialization happens-before using that library in other
    871   // threads (in particular unwinding with that library's functions
    872   // appearing in the backtraces).  Calling that library's functions
    873   // without waiting for the library to initialize would be racy.
    874   if (__builtin_expect (!RLOAD (t->root), 1))
    875     return NULL;
    876 
    877   // The unwinding tables are mostly static, they only change when
    878   // frames are added or removed. This makes it extremely unlikely that they
    879   // change during a given unwinding sequence. Thus, we optimize for the
    880   // contention free case and use optimistic lock coupling. This does not
    881   // require any writes to shared state, instead we validate every read. It is
    882   // important that we do not trust any value that we have read until we call
    883   // validate again. Data can change at arbitrary points in time, thus we always
    884   // copy something into a local variable and validate again before acting on
    885   // the read. In the unlikely event that we encounter a concurrent change we
    886   // simply restart and try again.
    887 
    888 restart:
    889   struct btree_node *iter;
    890   uintptr_type lock;
    891   {
    892     // Accessing the root node requires defending against concurrent pointer
    893     // changes Thus we couple rootLock -> lock on root node -> validate rootLock
    894     if (!version_lock_lock_optimistic (&(t->root_lock), &lock))
    895       goto restart;
    896     iter = RLOAD (t->root);
    897     if (!version_lock_validate (&(t->root_lock), lock))
    898       goto restart;
    899     if (!iter)
    900       return NULL;
    901     uintptr_type child_lock;
    902     if ((!btree_node_lock_optimistic (iter, &child_lock))
    903 	|| (!version_lock_validate (&(t->root_lock), lock)))
    904       goto restart;
    905     lock = child_lock;
    906   }
    907 
    908   // Now we can walk down towards the right leaf node.
    909   while (true)
    910     {
    911       enum node_type type = RLOAD (iter->type);
    912       unsigned entry_count = RLOAD (iter->entry_count);
    913       if (!btree_node_validate (iter, lock))
    914 	goto restart;
    915       if (!entry_count)
    916 	return NULL;
    917 
    918       if (type == btree_node_inner)
    919 	{
    920 	  // We cannot call find_inner_slot here because we need (relaxed)
    921 	  // atomic reads here.
    922 	  unsigned slot = 0;
    923 	  while (
    924 	    ((slot + 1) < entry_count)
    925 	    && (RLOAD (iter->content.children[slot].separator) < target_addr))
    926 	    ++slot;
    927 	  struct btree_node *child = RLOAD (iter->content.children[slot].child);
    928 	  if (!btree_node_validate (iter, lock))
    929 	    goto restart;
    930 
    931 	  // The node content can change at any point in time, thus we must
    932 	  // interleave parent and child checks.
    933 	  uintptr_type child_lock;
    934 	  if (!btree_node_lock_optimistic (child, &child_lock))
    935 	    goto restart;
    936 	  if (!btree_node_validate (iter, lock))
    937 	    goto restart; // make sure we still point to the correct node after
    938 			  // acquiring the optimistic lock.
    939 
    940 	  // Go down
    941 	  iter = child;
    942 	  lock = child_lock;
    943 	}
    944       else
    945 	{
    946 	  // We cannot call find_leaf_slot here because we need (relaxed)
    947 	  // atomic reads here.
    948 	  unsigned slot = 0;
    949 	  while (((slot + 1) < entry_count)
    950 		 && (RLOAD (iter->content.entries[slot].base)
    951 		       + RLOAD (iter->content.entries[slot].size)
    952 		     <= target_addr))
    953 	    ++slot;
    954 	  struct leaf_entry entry;
    955 	  entry.base = RLOAD (iter->content.entries[slot].base);
    956 	  entry.size = RLOAD (iter->content.entries[slot].size);
    957 	  entry.ob = RLOAD (iter->content.entries[slot].ob);
    958 	  if (!btree_node_validate (iter, lock))
    959 	    goto restart;
    960 
    961 	  // Check if we have a hit.
    962 	  if ((entry.base <= target_addr)
    963 	      && (target_addr < entry.base + entry.size))
    964 	    {
    965 	      return entry.ob;
    966 	    }
    967 	  return NULL;
    968 	}
    969     }
    970 #undef RLOAD
    971 }
    972 
    973 #endif /* unwind-dw2-btree.h */
    974