From patchwork Fri Dec 9 17:34:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Neumann X-Patchwork-Id: 31898 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp903956wrr; Fri, 9 Dec 2022 09:35:18 -0800 (PST) X-Google-Smtp-Source: AA0mqf7CVAGthJvfiV9apN8AusO1J35WuaursMpHvaM5oBg5mYpZlqWkjtux9Px7CpFR86CaJOcl X-Received: by 2002:a17:906:1dd6:b0:7c0:aa8e:af5b with SMTP id v22-20020a1709061dd600b007c0aa8eaf5bmr5350031ejh.60.1670607318479; Fri, 09 Dec 2022 09:35:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670607318; cv=none; d=google.com; s=arc-20160816; b=MH3OcEw42aRYvhyhblJ2PzB4ZV5Rv8J6NxoHYjonnjTl3PKL/2o7fDNUmo04AHpimO yhl3NW1dwXgPJvXTHvU2b30prgNuSGcP0q5k8TmnbGspiLWjqPjQcLxWBp9S0v15zaO9 Stb8L/QQJSvqYgPDGoM90ADRqlbFQ4oCswOtl2/lGqgop2hfdoYbzNTdPFu+O0A0mkj3 E5XTk1L3gTAaHa3BHzNpIBcSZmlYux4QvFRZ5H85fDEoWDIBsL7muAeiXq4LSYRK5pcf kIPfAq0jJrMalfVT4kkOFsCyfEFas0yvwXOgIhfv2+HM7bjuf3WfaxyH6749q6sg+06D iZNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:user-agent:mime-version:date:message-id:dmarc-filter :delivered-to:dkim-signature:dkim-filter; bh=NIEpJSfVW1R8nWJjuKGsGZoCDnf9Z+JH1WxhoMZ3xng=; b=R4ZDfwzcd4QmZtyNUZ+UrGfjM+mkSExy8kTBq9A1HG0AStFVT+HRL0/XS8S8cQQLDX FnSSL1krFV0QgvVKvIbSMHvZ+PnOYoBC8irBBC3Scg6e/7F48WYajlv9j3HIrQMkAEmD d+4JrTkIB5gnCHX5lM75X5XRIM6x5IQ64+0U3pHU83LchMI8t34wNIOvA3iAYvnuQCPn ZHBpnh3ORei6egrcPVKuRz7ECpxaU/XUiADDxKKZD9pQvMgk/m09wjpjOEePIC1yzETk r0SwmoeboTravu1n7edBCEax+ULXwKiaCUD3CLAZsDxAR4LLf/+Ih23MRE8MC7TDojGa ip8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=RwJ39sB3; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id sb19-20020a1709076d9300b007c0d4287960si272932ejc.213.2022.12.09.09.35.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Dec 2022 09:35:18 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=RwJ39sB3; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DFAA33884F97 for ; Fri, 9 Dec 2022 17:35:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DFAA33884F97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670607309; bh=NIEpJSfVW1R8nWJjuKGsGZoCDnf9Z+JH1WxhoMZ3xng=; h=Date:Subject:To:Cc:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=RwJ39sB3luNN+auNnqENj+bGGbW3i9quVaZqGSiul62wgz9oop4ci3F9wgx1Ybm+j B5O49l7jyLbKPKmvNEWUGsiuKfTzFE79uoHA3I2pncPUezWdU61DPRuBx+wrf70ChV 6aFhnDgmoSK+oeSWbC3Y926Kh9F/ifrGariZVcu8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailout3.rbg.tum.de (mailout3.rbg.tum.de [131.159.0.8]) by sourceware.org (Postfix) with ESMTPS id 8A719384D3D5 for ; Fri, 9 Dec 2022 17:34:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8A719384D3D5 Received: from mailrelay1.rbg.tum.de (mailrelay1.in.tum.de [131.159.254.14]) by mailout3.rbg.tum.de (Postfix) with ESMTPS id 1BA7F100110; Fri, 9 Dec 2022 18:34:20 +0100 (CET) Received: by mailrelay1.rbg.tum.de (Postfix, from userid 112) id 166CD1A8; Fri, 9 Dec 2022 18:34:20 +0100 (CET) Received: from mailrelay1.rbg.tum.de (localhost [127.0.0.1]) by mailrelay1.rbg.tum.de (Postfix) with ESMTP id A84041A5; Fri, 9 Dec 2022 18:34:19 +0100 (CET) Received: from mail.in.tum.de (mailproxy.in.tum.de [IPv6:2a09:80c0::78]) by mailrelay1.rbg.tum.de (Postfix) with ESMTPS id A08E41A1; Fri, 9 Dec 2022 18:34:19 +0100 (CET) Received: by mail.in.tum.de (Postfix, from userid 112) id 976304A01A8; Fri, 9 Dec 2022 18:34:19 +0100 (CET) Received: (Authenticated sender: neumann) by mail.in.tum.de (Postfix) with ESMTPSA id C457D4A0023; Fri, 9 Dec 2022 18:34:18 +0100 (CET) (Extended-Queue-bit xtech_uw@fff.in.tum.de) Message-ID: <7d18f085-ae46-138d-4f04-df5857b7b014@in.tum.de> Date: Fri, 9 Dec 2022 18:34:18 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.1 Subject: [PATCH] initialize fde objects lazily To: "gcc-patches@gcc.gnu.org" Cc: "H.J. Lu" , Jakub Jelinek , Tamar Christina , Jason Merrill , Jonathan Wakely , Florian Weimer References: <2a4776b9-9271-bb3c-a626-d5ec22dae6f3@in.tum.de> <91045a34-a534-4436-bb06-cac32d797a36@in.tum.de> <87sfibqu1s.fsf@oldenburg.str.redhat.com> Content-Language: en-US In-Reply-To: <87sfibqu1s.fsf@oldenburg.str.redhat.com> X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thomas Neumann via Gcc-patches From: Thomas Neumann Reply-To: Thomas Neumann Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751758739570237661?= X-GMAIL-MSGID: =?utf-8?q?1751758739570237661?= When registering an unwind frame with __register_frame_info_bases we currently initialize that fde object eagerly. This has the advantage that it is immutable afterwards and we can safely access it from multiple threads, but it has the disadvantage that we pay the initialization cost even if the application never throws an exception. This commit changes the logic to initialize the objects lazily. The objects themselves are inserted into the b-tree when registering the frame, but the sorted fde_vector is not constructed yet. Only on the first time that an exception tries to pass through the registered code the object is initialized. We notice that with a double checking, first doing a relaxed load of the sorted bit and then re-checking under a mutex when the object was not initialized yet. Note that the check must implicitly be safe concering a concurrent frame deregistration, as trying the deregister a frame that is on the unwinding path of a concurrent exception is inherently racy. libgcc/ChangeLog: * unwind-dw2-fde.c: Initialize fde object lazily when the first exception tries to pass through. --- libgcc/unwind-dw2-fde.c | 52 ++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c index 3c0cc654ec0..6f69c20ff4b 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -63,8 +63,6 @@ release_registered_frames (void) static void get_pc_range (const struct object *ob, uintptr_type *range); -static void -init_object (struct object *ob); #else /* Without fast path frame deregistration must always succeed. */ @@ -76,6 +74,7 @@ static const int in_shutdown = 0; by decreasing value of pc_begin. */ static struct object *unseen_objects; static struct object *seen_objects; +#endif #ifdef __GTHREAD_MUTEX_INIT static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; @@ -103,7 +102,6 @@ init_object_mutex_once (void) static __gthread_mutex_t object_mutex; #endif #endif -#endif /* Called from crtbegin.o to register the unwind info for an object. */ @@ -126,10 +124,7 @@ __register_frame_info_bases (const void *begin, struct object *ob, #endif #ifdef ATOMIC_FDE_FAST_PATH - // Initialize eagerly to avoid locking later - init_object (ob); - - // And register the frame + // Register the frame in the b-tree uintptr_type range[2]; get_pc_range (ob, range); btree_insert (®istered_frames, range[0], range[1] - range[0], ob); @@ -180,10 +175,7 @@ __register_frame_info_table_bases (void *begin, struct object *ob, ob->s.b.encoding = DW_EH_PE_omit; #ifdef ATOMIC_FDE_FAST_PATH - // Initialize eagerly to avoid locking later - init_object (ob); - - // And register the frame + // Register the frame in the b-tree uintptr_type range[2]; get_pc_range (ob, range); btree_insert (®istered_frames, range[0], range[1] - range[0], ob); @@ -892,7 +884,15 @@ init_object (struct object* ob) accu.linear->orig_data = ob->u.single; ob->u.sort = accu.linear; +#ifdef ATOMIC_FDE_FAST_PATH + // We must update the sorted bit with an atomic operation + struct object tmp; + tmp.s.b = ob->s.b; + tmp.s.b.sorted = 1; + __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_SEQ_CST); +#else ob->s.b.sorted = 1; +#endif } #ifdef ATOMIC_FDE_FAST_PATH @@ -1130,6 +1130,21 @@ search_object (struct object* ob, void *pc) } } +#ifdef ATOMIC_FDE_FAST_PATH + +// Check if the object was already initialized +static inline bool +is_object_initialized (struct object *ob) +{ + // We have to use relaxed atomics for the read, which + // is a bit involved as we read from a bitfield + struct object tmp; + __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELAXED); + return tmp.s.b.sorted; +} + +#endif + const fde * _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) { @@ -1141,6 +1156,21 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) if (!ob) return NULL; + // Initialize the object lazily + if (!is_object_initialized (ob)) + { + // Check again under mutex + init_object_mutex_once (); + __gthread_mutex_lock (&object_mutex); + + if (!ob->s.b.sorted) + { + init_object (ob); + } + + __gthread_mutex_unlock (&object_mutex); + } + f = search_object (ob, pc); #else