From patchwork Mon May 2 10:34:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 617458 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qz0zv0W0pz9sdm for ; Mon, 2 May 2016 20:34:49 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ZmEwqWwN; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=evNt/IlaI+T+6j6jcefuNQ971wWi+Ak6dkl+DfYSmZjBpdPgp0 ou5UekkUYKd9atiOtJ4TWoDRkjxI9jrsMJXxefXrOvMl86uFsSjtKPH/MEFlvF/d rnxAv4s+Al4WSkZIo7Gke87Rl1bAm4Sw4swomEdsjb2PgIa8dFr4d0zok= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=m3cOjzTC7UNSuovCXldZbfXRjh4=; b=ZmEwqWwNy35lvMrVMEgL jtASBLPpRl7CyUNuRN+vvKHzK1HR3j/JKuA7ne9EEhZVT/8oD2JV91TGQDxduCUc TWZbfLDjUDQ/GHUhxGAoYKEMeKX59sJxLg/fWHYp6TipzlrvKigNiGLnjFc8l62t kD2Xe1DeCMWMRGd8byQOIk4= Received: (qmail 2484 invoked by alias); 2 May 2016 10:34:38 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 2464 invoked by uid 89); 2 May 2016 10:34:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.6 required=5.0 tests=BAYES_50, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.2 spammy=elsif, redistribute, allocate, duffadacorecom X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 02 May 2016 10:34:31 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1CE9F116B3D; Mon, 2 May 2016 06:34:30 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 1ge--C8NcUqe; Mon, 2 May 2016 06:34:30 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id 0C687116B30; Mon, 2 May 2016 06:34:30 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4192) id 0B5F830C; Mon, 2 May 2016 06:34:30 -0400 (EDT) Date: Mon, 2 May 2016 06:34:30 -0400 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Bob Duff Subject: [Ada] Speed up memory management Message-ID: <20160502103430.GA137107@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This patch speeds up "new" and Unchecked_Deallocation in simple cases. No change in behavior; no test available. Tested on x86_64-pc-linux-gnu, committed on trunk 2016-05-02 Bob Duff * s-memory.adb (Alloc, Realloc): Move checks for Size = 0 or size_t'Last into the Result = System.Null_Address path for efficiency. Improve comments (based on actual C language requirements for malloc). * exp_util.adb (Build_Allocate_Deallocate_Proc): Optimize the case where we are using the default Global_Pool_Object, and we don't need the heavy finalization machinery. Index: exp_util.adb =================================================================== --- exp_util.adb (revision 235744) +++ exp_util.adb (working copy) @@ -584,6 +584,14 @@ elsif Is_RTE (Pool_Id, RE_SS_Pool) then return; + -- Optimize the case where we are using the default Global_Pool_Object, + -- and we don't need the heavy finalization machinery. + + elsif Pool_Id = RTE (RE_Global_Pool_Object) + and then not Needs_Finalization (Desig_Typ) + then + return; + -- Do not replicate the machinery if the allocator / free has already -- been expanded and has a custom Allocate / Deallocate. Index: s-memory.adb =================================================================== --- s-memory.adb (revision 235706) +++ s-memory.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2001-2016, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -43,14 +43,12 @@ pragma Compiler_Unit_Warning; -with Ada.Exceptions; +with System.CRTL; +with System.Parameters; with System.Soft_Links; -with System.Parameters; -with System.CRTL; package body System.Memory is - use Ada.Exceptions; use System.Soft_Links; function c_malloc (Size : System.CRTL.size_t) return System.Address @@ -68,33 +66,41 @@ ----------- function Alloc (Size : size_t) return System.Address is - Result : System.Address; - Actual_Size : size_t := Size; - + Result : System.Address; begin - if Size = size_t'Last then - Raise_Exception (Storage_Error'Identity, "object too large"); - end if; - - -- Change size from zero to non-zero. We still want a proper pointer - -- for the zero case because pointers to zero length objects have to - -- be distinct, but we can't just go ahead and allocate zero bytes, - -- since some malloc's return zero for a zero argument. - - if Size = 0 then - Actual_Size := 1; - end if; - if Parameters.No_Abort then - Result := c_malloc (System.CRTL.size_t (Actual_Size)); + Result := c_malloc (System.CRTL.size_t (Size)); else Abort_Defer.all; - Result := c_malloc (System.CRTL.size_t (Actual_Size)); + Result := c_malloc (System.CRTL.size_t (Size)); Abort_Undefer.all; end if; if Result = System.Null_Address then - Raise_Exception (Storage_Error'Identity, "heap exhausted"); + -- If Size = 0, we can't allocate 0 bytes, because then two different + -- allocators, one of which has Size = 0, could return pointers that + -- compare equal, which is wrong. (Nonnull pointers compare equal if + -- and only if they designate the same object, and two different + -- allocators allocate two different objects). + + -- malloc(0) is defined to allocate a non-zero-sized object (in which + -- case we won't get here, and all is well) or NULL, in which case we + -- get here. We also get here in case of error. So check for the + -- zero-size case, and allocate 1 byte. Otherwise, raise + -- Storage_Error. + + -- We check for zero size here, rather than at the start, for + -- efficiency. + + if Size = 0 then + return Alloc (1); + end if; + + if Size = size_t'Last then + raise Storage_Error with "object too large"; + end if; + + raise Storage_Error with "heap exhausted"; end if; return Result; @@ -125,23 +131,21 @@ return System.Address is Result : System.Address; - Actual_Size : constant size_t := Size; - begin - if Size = size_t'Last then - Raise_Exception (Storage_Error'Identity, "object too large"); - end if; - if Parameters.No_Abort then - Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size)); + Result := c_realloc (Ptr, System.CRTL.size_t (Size)); else Abort_Defer.all; - Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size)); + Result := c_realloc (Ptr, System.CRTL.size_t (Size)); Abort_Undefer.all; end if; if Result = System.Null_Address then - Raise_Exception (Storage_Error'Identity, "heap exhausted"); + if Size = size_t'Last then + raise Storage_Error with "object too large"; + end if; + + raise Storage_Error with "heap exhausted"; end if; return Result;