Patchwork [Ada] Avoid memory exhaustion when using gnatmake -m

login
register
mail settings
Submitter Arnaud Charlet
Date June 12, 2012, 11:09 a.m.
Message ID <20120612110937.GA5402@adacore.com>
Download mbox | patch
Permalink /patch/164391/
State New
Headers show

Comments

Arnaud Charlet - June 12, 2012, 11:09 a.m.
In large systems, gnatmake may crash when invoked with -m (minimal
recompilation) when there are many sources that have been modified
but have kept the same checksum.
This patch fixes this.
There is no simple test.

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-06-12  Vincent Celier  <celier@adacore.com>

	* ali-util.adb (Time_Stamp_Mismatch): In minimal recompilation
	mode, use Stringt Mark and Release to avoid growing the Stringt
	internal tables uselessly.
	* stringt.adb (Strings_Last): New global variable
	(String_Chars_Last): New global variable.
	(Mark, Release): New procedures.
	* stringt.ads (Mark, Release) New procedures.

Patch

Index: ali-util.adb
===================================================================
--- ali-util.adb	(revision 188428)
+++ ali-util.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -32,6 +32,7 @@ 
 with Scng;
 with Sinput.C;
 with Snames;  use Snames;
+with Stringt;
 with Styleg;
 
 package body ALI.Util is
@@ -476,6 +477,8 @@ 
             --  ??? It is probably worth updating the ALI file with a new
             --  field to avoid recomputing it each time.
 
+            Stringt.Mark;
+
             if Checksums_Match
                  (Get_File_Checksum (Sdep.Table (D).Sfile),
                   Source.Table (Src).Checksum)
@@ -491,6 +494,8 @@ 
                Sdep.Table (D).Stamp := Source.Table (Src).Stamp;
             end if;
 
+            Stringt.Release;
+
          end if;
 
          if (not Read_Only) or else Source.Table (Src).Source_Found then
Index: stringt.adb
===================================================================
--- stringt.adb	(revision 188428)
+++ stringt.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -70,6 +70,12 @@ 
    --  when Start_String is called with a parameter that is the last string
    --  currently allocated in the table.
 
+   Strings_Last : String_Id := First_String_Id;
+   String_Chars_Last : Int := 0;
+   --  Strings_Last and String_Chars_Last are used by procedure Mark and
+   --  Release to get a snapshot of the tables and to restore them to their
+   --  previous situation.
+
    -------------------------------
    -- Add_String_To_Name_Buffer --
    -------------------------------
@@ -129,6 +135,26 @@ 
       Strings.Release;
    end Lock;
 
+   ----------
+   -- Mark --
+   ----------
+
+   procedure Mark is
+   begin
+      Strings_Last := Strings.Last;
+      String_Chars_Last := String_Chars.Last;
+   end Mark;
+
+   -------------
+   -- Release --
+   -------------
+
+   procedure Release is
+   begin
+      Strings.Set_Last (Strings_Last);
+      String_Chars.Set_Last (String_Chars_Last);
+   end Release;
+
    ------------------
    -- Start_String --
    ------------------
Index: stringt.ads
===================================================================
--- stringt.ads	(revision 188428)
+++ stringt.ads	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
@@ -62,6 +62,14 @@ 
    procedure Unlock;
    --  Unlock internal tables, in case back end needs to modify them
 
+   procedure Mark;
+   --  Take a snapshot of the internal tables
+
+   procedure Release;
+   --  Restore the internal tables to the situation when Mark was last called.
+   --  Mark and Release are used when getting checksums of sources in minimal
+   --  recompilation mode, to reduce memory usage.
+
    procedure Start_String;
    --  Sets up for storing a new string in the table. To store a string, a
    --  call is first made to Start_String, then successive calls are