Add an UNSPEC_PROLOGUE_USE to prevent the link register from being considered dead.
[official-gcc.git] / gcc / ada / g-debpoo.adb
blobf7bec400f66e7799fc3d4dc5efd5907e7b4396d8
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T . D E B U G _ P O O L S --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
29 -- --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 -- --
33 ------------------------------------------------------------------------------
35 with Unchecked_Conversion;
36 with GNAT.HTable;
37 with System.Memory;
39 pragma Elaborate_All (GNAT.HTable);
41 package body GNAT.Debug_Pools is
42 use System;
43 use System.Memory;
44 use System.Storage_Elements;
46 -- Definition of a H-table storing the status of each storage chunck
47 -- used by this pool
49 type State is (Not_Allocated, Deallocated, Allocated);
51 type Header is range 1 .. 1023;
52 function H (F : Address) return Header;
54 package Table is new GNAT.HTable.Simple_HTable (
55 Header_Num => Header,
56 Element => State,
57 No_Element => Not_Allocated,
58 Key => Address,
59 Hash => H,
60 Equal => "=");
62 --------------
63 -- Allocate --
64 --------------
66 procedure Allocate
67 (Pool : in out Debug_Pool;
68 Storage_Address : out Address;
69 Size_In_Storage_Elements : Storage_Count;
70 Alignment : Storage_Count)
72 pragma Warnings (Off, Alignment);
74 begin
75 Storage_Address := Alloc (size_t (Size_In_Storage_Elements));
77 if Storage_Address = Null_Address then
78 raise Storage_Error;
79 else
80 Table.Set (Storage_Address, Allocated);
81 Pool.Allocated := Pool.Allocated + Size_In_Storage_Elements;
83 if Pool.Allocated - Pool.Deallocated > Pool.High_Water then
84 Pool.High_Water := Pool.Allocated - Pool.Deallocated;
85 end if;
86 end if;
87 end Allocate;
89 ----------------
90 -- Deallocate --
91 ----------------
93 procedure Deallocate
94 (Pool : in out Debug_Pool;
95 Storage_Address : Address;
96 Size_In_Storage_Elements : Storage_Count;
97 Alignment : Storage_Count)
99 pragma Warnings (Off, Alignment);
101 procedure Free (Address : System.Address; Siz : Storage_Count);
102 -- Fake free, that resets all the deallocated storage to "DEADBEEF"
104 procedure Free (Address : System.Address; Siz : Storage_Count) is
105 DB1 : constant Integer := 16#DEAD#;
106 DB2 : constant Integer := 16#BEEF#;
108 type Dead_Memory is array (1 .. Siz / 4) of Integer;
109 type Mem_Ptr is access all Dead_Memory;
111 function From_Ptr is
112 new Unchecked_Conversion (System.Address, Mem_Ptr);
114 J : Storage_Offset;
116 begin
117 J := Dead_Memory'First;
118 while J < Dead_Memory'Last loop
119 From_Ptr (Address) (J) := DB1;
120 From_Ptr (Address) (J + 1) := DB2;
121 J := J + 2;
122 end loop;
124 if J = Dead_Memory'Last then
125 From_Ptr (Address) (J) := DB1;
126 end if;
127 end Free;
129 S : State := Table.Get (Storage_Address);
131 -- Start of processing for Deallocate
133 begin
134 case S is
135 when Not_Allocated =>
136 raise Freeing_Not_Allocated_Storage;
138 when Deallocated =>
139 raise Freeing_Deallocated_Storage;
141 when Allocated =>
142 Free (Storage_Address, Size_In_Storage_Elements);
143 Table.Set (Storage_Address, Deallocated);
144 Pool.Deallocated := Pool.Deallocated + Size_In_Storage_Elements;
145 end case;
146 end Deallocate;
148 -----------------
149 -- Dereference --
150 -----------------
152 procedure Dereference
153 (Pool : in out Debug_Pool;
154 Storage_Address : Address;
155 Size_In_Storage_Elements : Storage_Count;
156 Alignment : Storage_Count)
158 pragma Warnings (Off, Pool);
159 pragma Warnings (Off, Size_In_Storage_Elements);
160 pragma Warnings (Off, Alignment);
162 S : State := Table.Get (Storage_Address);
163 Max_Dim : constant := 3;
164 Dim : Integer := 1;
166 begin
168 -- If this is not a known address, maybe it is because is is an
169 -- unconstained array. In which case, the bounds have used the
170 -- 2 first words (per dimension) of the allocated spot.
172 while S = Not_Allocated and then Dim <= Max_Dim loop
173 S := Table.Get (Storage_Address - Storage_Offset (Dim * 2 * 4));
174 Dim := Dim + 1;
175 end loop;
177 case S is
178 when Not_Allocated =>
179 raise Accessing_Not_Allocated_Storage;
181 when Deallocated =>
182 raise Accessing_Deallocated_Storage;
184 when Allocated =>
185 null;
186 end case;
187 end Dereference;
189 -------
190 -- H --
191 -------
193 function H (F : Address) return Header is
194 begin
195 return
196 Header (1 + (To_Integer (F) mod Integer_Address (Header'Last)));
197 end H;
199 ----------------
200 -- Print_Info --
201 ----------------
203 procedure Print_Info (Pool : Debug_Pool) is
204 use System.Storage_Elements;
206 begin
207 Put_Line ("Debug Pool info:");
208 Put_Line (" Total allocated bytes : "
209 & Storage_Offset'Image (Pool.Allocated));
211 Put_Line (" Total deallocated bytes : "
212 & Storage_Offset'Image (Pool.Deallocated));
214 Put_Line (" Current Water Mark: "
215 & Storage_Offset'Image (Pool.Allocated - Pool.Deallocated));
217 Put_Line (" High Water Mark: "
218 & Storage_Offset'Image (Pool.High_Water));
219 Put_Line ("");
220 end Print_Info;
222 ------------------
223 -- Storage_Size --
224 ------------------
226 function Storage_Size (Pool : Debug_Pool) return Storage_Count is
227 pragma Warnings (Off, Pool);
229 begin
230 return Storage_Count'Last;
231 end Storage_Size;
233 end GNAT.Debug_Pools;