_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.