diff options
author | Bob Duff <duff@adacore.com> | 2007-08-31 12:23:37 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2007-08-31 12:23:37 +0200 |
commit | b54ddf5adfaa5be8c910c862d62b3726670df773 (patch) | |
tree | 198081394ea01406fbc6cf4d9510dc38574a8add /gcc/ada/stringt.adb | |
parent | b90cfacd5f804816323d230bd3d7fc4d62569d5b (diff) | |
download | gcc-b54ddf5adfaa5be8c910c862d62b3726670df773.zip gcc-b54ddf5adfaa5be8c910c862d62b3726670df773.tar.gz gcc-b54ddf5adfaa5be8c910c862d62b3726670df773.tar.bz2 |
par-ch4.adb (P_Simple_Expression): Fold long sequences of concatenations of string literals into a single literal...
2007-08-31 Bob Duff <duff@adacore.com>
* par-ch4.adb (P_Simple_Expression): Fold long sequences of
concatenations of string literals into a single literal, in order to
avoid very deep recursion in the front end, which was causing stack
overflow.
* sem_eval.adb (Eval_Concatenation): If the left operand is the empty
string, and the right operand is a string literal (the case of "" &
"..."), optimize by avoiding copying the right operand -- just use the
value of the right operand directly.
* stringt.adb (Store_String_Chars): Optimize by growing the
String_Chars table all at once, rather than appending characters one by
one.
(Write_String_Table_Entry): If the string to be printed is very long,
just print the first few characters, followed by the length. Otherwise,
doing "pn(n)" in the debugger can take an extremely long time.
* sem_prag.adb (Process_Interface_Name): Replace loop doing
Store_String_Char with Store_String_Chars.
From-SVN: r127977
Diffstat (limited to 'gcc/ada/stringt.adb')
-rw-r--r-- | gcc/ada/stringt.adb | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/gcc/ada/stringt.adb b/gcc/ada/stringt.adb index e272009..88b72e05 100644 --- a/gcc/ada/stringt.adb +++ b/gcc/ada/stringt.adb @@ -202,10 +202,27 @@ package body Stringt is end Store_String_Chars; procedure Store_String_Chars (S : String_Id) is + + -- We are essentially doing this: + + -- for J in 1 .. String_Length (S) loop + -- Store_String_Char (Get_String_Char (S, J)); + -- end loop; + + -- but when the string is long it's more efficient to grow the + -- String_Chars table all at once. + + S_First : constant Int := Strings.Table (S).String_Index; + S_Len : constant Int := String_Length (S); + Old_Last : constant Int := String_Chars.Last; + New_Last : constant Int := Old_Last + S_Len; + begin - for J in 1 .. String_Length (S) loop - Store_String_Char (Get_String_Char (S, J)); - end loop; + String_Chars.Set_Last (New_Last); + String_Chars.Table (Old_Last + 1 .. New_Last) := + String_Chars.Table (S_First .. S_First + S_Len - 1); + Strings.Table (Strings.Last).Length := + Strings.Table (Strings.Last).Length + S_Len; end Store_String_Chars; ---------------------- @@ -417,6 +434,15 @@ package body Stringt is else Write_Char_Code (C); end if; + + -- If string is very long, quit + + if J >= 1000 then -- arbitrary limit + Write_Str ("""...etc (length = "); + Write_Int (String_Length (Id)); + Write_Str (")"); + return; + end if; end loop; Write_Char ('"'); |