From 59d5d8cdb95479231e675a03e5baec955b7095c2 Mon Sep 17 00:00:00 2001 From: Vadim Godunko Date: Wed, 10 Mar 2021 14:27:20 +0300 Subject: [PATCH] [Ada] Fix operations on Unbounded_String... gcc/ada/ * libgnat/a-strunb__shared.ads (Allocate): Additional parameter to provide additional amount of space to be allocated. * libgnat/a-strunb__shared.adb (Aligned_Max_Length): Limit length to Natural'Last when requested length is larger than it. (Allocate): Merge two slightly different implementations into one. --- gcc/ada/libgnat/a-strunb__shared.adb | 58 +++++++++++++++--------------------- gcc/ada/libgnat/a-strunb__shared.ads | 10 ++++--- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/gcc/ada/libgnat/a-strunb__shared.adb b/gcc/ada/libgnat/a-strunb__shared.adb index 00327de..d2907f6 100644 --- a/gcc/ada/libgnat/a-strunb__shared.adb +++ b/gcc/ada/libgnat/a-strunb__shared.adb @@ -50,11 +50,13 @@ package body Ada.Strings.Unbounded is -- align the returned memory on the maximum alignment as malloc does not -- know the target alignment. - function Aligned_Max_Length (Max_Length : Natural) return Natural; + function Aligned_Max_Length + (Required_Length : Natural; + Reserved_Length : Natural) return Natural; -- Returns recommended length of the shared string which is greater or - -- equal to specified length. Calculation take in sense alignment of the - -- allocated memory segments to use memory effectively by Append/Insert/etc - -- operations. + -- equal to specified required length and desired reserved length. + -- Calculation takes into account alignment of the allocated memory + -- segments to use memory effectively by Append/Insert/etc operations. function Sum (Left : Natural; Right : Integer) return Natural with Inline; -- Returns summary of Left and Right, raise Constraint_Error on overflow @@ -63,11 +65,6 @@ package body Ada.Strings.Unbounded is -- Returns multiplication of Left and Right, raise Constraint_Error on -- overflow - function Allocate - (Length, Growth : Natural) return not null Shared_String_Access; - -- Allocates new Shared_String with at least specified Length plus optional - -- Growth. - --------- -- "&" -- --------- @@ -490,17 +487,24 @@ package body Ada.Strings.Unbounded is -- Aligned_Max_Length -- ------------------------ - function Aligned_Max_Length (Max_Length : Natural) return Natural is + function Aligned_Max_Length + (Required_Length : Natural; + Reserved_Length : Natural) return Natural + is Static_Size : constant Natural := Empty_Shared_String'Size / Standard'Storage_Unit; -- Total size of all Shared_String static components begin - if Max_Length > Natural'Last - Static_Size then + if Required_Length > Natural'Last - Static_Size - Reserved_Length then + -- Total requested length is larger than maximum possible length. + -- Use of Static_Size needed to avoid overflows in expression to + -- compute aligned length. return Natural'Last; + else return - ((Static_Size + Max_Length - 1) / Min_Mul_Alloc + 2) * Min_Mul_Alloc - - Static_Size; + ((Static_Size + Required_Length + Reserved_Length - 1) + / Min_Mul_Alloc + 2) * Min_Mul_Alloc - Static_Size; end if; end Aligned_Max_Length; @@ -509,35 +513,21 @@ package body Ada.Strings.Unbounded is -------------- function Allocate - (Max_Length : Natural) return not null Shared_String_Access + (Required_Length : Natural; + Reserved_Length : Natural := 0) return not null Shared_String_Access is begin -- Empty string requested, return shared empty string - if Max_Length = 0 then + if Required_Length = 0 then return Empty_Shared_String'Access; -- Otherwise, allocate requested space (and probably some more room) else - return new Shared_String (Aligned_Max_Length (Max_Length)); - end if; - end Allocate; - - -------------- - -- Allocate -- - -------------- - - function Allocate - (Length, Growth : Natural) return not null Shared_String_Access is - begin - if Natural'Last - Growth < Length then - -- Then Length + Growth would be more than Natural'Last - - return new Shared_String (Integer'Last); - - else - return Allocate (Length + Growth); + return + new Shared_String + (Aligned_Max_Length (Required_Length, Reserved_Length)); end if; end Allocate; @@ -657,7 +647,7 @@ package body Ada.Strings.Unbounded is System.Atomic_Counters.Is_One (Item.Counter) and then Item.Max_Length >= Length and then Item.Max_Length <= - Aligned_Max_Length (Length + Length / Growth_Factor); + Aligned_Max_Length (Length, Length / Growth_Factor); end Can_Be_Reused; ----------- diff --git a/gcc/ada/libgnat/a-strunb__shared.ads b/gcc/ada/libgnat/a-strunb__shared.ads index ee446a6..094bf7e 100644 --- a/gcc/ada/libgnat/a-strunb__shared.ads +++ b/gcc/ada/libgnat/a-strunb__shared.ads @@ -725,10 +725,12 @@ private -- store string with specified length effectively. function Allocate - (Max_Length : Natural) return not null Shared_String_Access; - -- Allocates new Shared_String with at least specified maximum length. - -- Actual maximum length of the allocated Shared_String can be slightly - -- greater. Returns reference to Empty_Shared_String when requested length + (Required_Length : Natural; + Reserved_Length : Natural := 0) return not null Shared_String_Access; + -- Allocates new Shared_String. Actual maximum length of allocated object + -- is at least the specified required length. Additional storage is + -- allocated to allow to store up to the specified reserved length when + -- possible. Returns reference to Empty_Shared_String when requested length -- is zero. Empty_Shared_String : aliased Shared_String (0); -- 2.7.4