From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18375 invoked by alias); 18 Dec 2018 16:03:53 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 18044 invoked by uid 89); 18 Dec 2018 16:03:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_PASS autolearn=no version=3.3.2 spammy=highlights, resolver X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 18 Dec 2018 16:03:47 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9709728123; Tue, 18 Dec 2018 16:03:45 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-24.rdu2.redhat.com [10.10.112.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id 69754600CC; Tue, 18 Dec 2018 16:03:42 +0000 (UTC) Subject: Re: [PATCH v4][C][ADA] use function descriptors instead of trampolines in C To: Jakub Jelinek , Paul Koning Cc: Szabolcs Nagy , "Uecker, Martin" , "msebor@gmail.com" , "joseph@codesourcery.com" , nd , "gcc-patches@gcc.gnu.org" , "ebotcazou@adacore.com" , Wilco Dijkstra References: <1544781926.10326.8.camel@med.uni-goettingen.de> <17025085-3d47-0b16-c9d3-fec8d1ae9f39@redhat.com> <56b1e591-4d32-672f-6a30-11a9a0b167b7@gmail.com> <1544967934.14155.1.camel@med.uni-goettingen.de> <1545000327.30232.11.camel@med.uni-goettingen.de> <05b12e7e-b6dd-fa8d-94cb-35ec9c512950@arm.com> <1545070952.3328.5.camel@med.uni-goettingen.de> <5896AE4C-D296-4FAF-A809-7BACA532BBF5@comcast.net> <20181218153209.GP23305@tucnak> From: Jeff Law Openpgp: preference=signencrypt Message-ID: <81804969-da3b-80b8-98d2-beb31cd19541@redhat.com> Date: Tue, 18 Dec 2018 16:03:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 In-Reply-To: <20181218153209.GP23305@tucnak> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2018-12/txt/msg01320.txt.bz2 On 12/18/18 8:32 AM, Jakub Jelinek wrote: > On Tue, Dec 18, 2018 at 10:23:46AM -0500, Paul Koning wrote: >> >> >>> On Dec 17, 2018, at 2:23 PM, Szabolcs Nagy wrote: >>> >>> On 17/12/2018 18:22, Uecker, Martin wrote: >>>>> >>>>> ... >>>> >>>> So a thread_local static variable for storing the static >>>> chain? >>> >>> something like that, but the more i think about it the >>> harder it seems: the call site of the nested function >>> may not be under control of the nested function writer, >>> in particular the nested function may be called on a >>> different thread, and extern library apis are unlikely >>> to provide guarantees about this, so in general if a >>> nested function escapes into an extern library then >>> this cannot be relied on, which limits my original >>> idea again to cases where there is no escape (which i >>> think is not that useful). >> >> I'm not sure I understand "escape" of a nested function pointer. >> >> Your description makes it sound like you're talking about a function being called by someone who has been given the pointer, from outside the scope of the function. That sounds like an illegal operation, exactly as it would be if you attempted to reference an automatic variable via a pointer from outside the scope of that variable. >> >> Did I misunderstand? > > The most common case is when you pass a call to a nested function > to some function that has a function pointer argument, e.g. qsort. > This is well defined with GNU nested functions, but the function that calls > the callback (qsort in this case) doesn't know it is a call to a nested > function. Right. This is the classic example and highlights the ABI concerns. If we use the low bit to distinguish between a normal function pointer and a pointer to a descriptor and qsort doesn't know about it, then we lose. One way around this is to make *all* function pointers be some kind of descriptor and route all indirect calls through a resolver. THen you need either linker hackery or special code to compare function pointers to preserve ISO C behavior. Note that if you have a nested function and take its address, then go out of scope of the containing function, then that function pointer is no longer valid -- which makes perfect sense if you think about it. THe trampoline was on the stack and if you go out of scope of the containing function, then that stack frame is invalid and you also don't have a suitable frame chain to pass to the nested function either. Jeff