_Unwind_Find_FDE calls _Unwind_Find_registered_FDE and it takes lock even
when there is no registered objects. As far as I see only statically
linked applications call __register_frame_info* functions, so for
dynamically linked executables taking the lock to check unseen_objects
and seen_objects is a pessimization. Since the function is called on
each thrown exception this is a lot of unneeded locking. This patch
checks unseen_objects and seen_objects outside of the lock and returns
earlier if both are NULL.
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 5b16a1f..41de746 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -1001,6 +1001,13 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
struct object *ob;
const fde *f = NULL;
+ /* __atomic_write is not used to modify unseen_objects and seen_objects
+ since they are modified in locked sections only and unlock provides
+ release semantics. */
+ if (!__atomic_load_n(&unseen_objects, __ATOMIC_ACQUIRE)
+ && !__atomic_load_n(&seen_objects, __ATOMIC_ACQUIRE))
+ return NULL;
+
init_object_mutex_once ();
__gthread_mutex_lock (&object_mutex);
@@ -1020,8 +1027,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
while ((ob = unseen_objects))
{
struct object **p;
+ struct object *next = ob->next;
- unseen_objects = ob->next;
f = search_object (ob, pc);
/* Insert the object into the classified list. */
@@ -1031,6 +1038,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
ob->next = *p;
*p = ob;
+ unseen_objects = next;
+
if (f)
goto fini;
}
--
Gleb.