* gimplify.c (find_single_pointer_decl_1): New static function.
[official-gcc.git] / gcc / ada / s-stausa.ads
blob0c0d8eb17b2fc8edfdcdd35b8f4b575bdd482ff9
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- S Y S T E M - S T A C K _ U S A G E --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2004-2005, Free Software Foundation, Inc. --
10 -- --
11 -- GNARL is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNARL; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNARL was developed by the GNARL team at Florida State University. --
30 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 with System;
35 with System.Storage_Elements;
36 with System.Address_To_Access_Conversions;
38 package System.Stack_Usage is
40 package SSE renames System.Storage_Elements;
42 Byte_Size : constant := 8;
43 Word_32_Size : constant := 4 * Byte_Size;
45 type Word_32 is mod 2 ** Word_32_Size;
46 for Word_32'Alignment use 4;
48 subtype Stack_Address is SSE.Integer_Address;
49 -- Address on the stack.
51 -- NOTE:
52 -- *****
54 -- in this package, when comparing two addresses on the
55 -- stack, the comments use the terms "outer", "inner", "outermost"
56 -- and "innermost" instead of the ambigous "higher", "lower",
57 -- "highest" and "lowest". "inner" means "closer to the bottom of
58 -- stack" and is the contrary of "outer". "innermost" means "closest
59 -- address to the bottom of stack". The stack is growing from the
60 -- innermost addresses to the outermost addresses.
62 function To_Stack_Address (Value : Address) return Stack_Address
63 renames System.Storage_Elements.To_Integer;
65 type Stack_Analyzer is private;
66 -- Type of the stack analyzer tool. It is used to fill a portion of
67 -- the stack with Pattern, and to compute the stack used after some
68 -- execution.
70 -- USAGE:
71 -- ******
73 -- -- A typical use of the package is something like:
75 -- A : Stack_Analyzer;
77 -- task T is
78 -- pragma Storage_Size (A_Storage_Size);
79 -- end T;
81 -- [...]
83 -- Bottom_Of_Stack : aliased Integer;
84 -- -- Bottom_Of_Stack'Address will be used as an approximation of
85 -- -- the bottom of stack. A good practise is to avoid allocating
86 -- -- other local variables on this stack, as it would degrade
87 -- -- the quality of this approximation.
89 -- begin
90 -- Initialize_Analyzer (A,
91 -- "Task t",
92 -- A_Storage_Size - A_Guard,
93 -- To_Stack_Address (Bottom_Of_Stack'Address));
94 -- Fill_Stack (A);
95 -- Some_User_Code;
96 -- Compute_Result (A);
97 -- Report_Result (A);
98 -- end T;
101 -- Errors:
102 -- *******
104 -- We are instrumenting the code to measure the stack used by the user
105 -- code. This method has a number of systematic errors, but several
106 -- methods can be used to evaluate or reduce those errors. Here are
107 -- those errors and the strategy that we use to deal with them:
109 -- * Bottom offset:
110 -- - Description: The procedure used to fill the stack with a given
111 -- pattern will itself have a stack frame. The value of the stack pointer
112 -- in this procedure is, therefore, different from the value before the
113 -- call to the instrumentation procedure.
114 -- - Strategy: The user of this package shall measure the bottom of stack
115 -- before the call to Fill_Stack and pass it in parameter.
117 -- * Instrumentation threshold at writing:
118 -- - Description: The procedure used to fill the stack with a given
119 -- pattern will itself have a stack frame. Therefore, it will
120 -- fill the stack after this stack frame. This part of the stack will
121 -- appear as used in the final measure.
122 -- - Strategy: As the user pass the value of the bottom of stack to
123 -- the instrumentation to deal with the bottom offset error, and as
124 -- as the instrumentation procedure knows where the pattern filling
125 -- start on the stack, the difference between the two values is the
126 -- minimum stack usage that the method can measure. If, when the results
127 -- are computed, the pattern zone has been left untouched, we conclude
128 -- that the stack usage is inferior to this minimum stack usage.
130 -- * Instrumentation threshold at reading:
131 -- - Description: The procedure used to read the stack at the end of the
132 -- execution clobbers the stack by allocating its stack frame. If this
133 -- stack frame is bigger than the total stack used by the user code at
134 -- this point, it will increase the measured stack size.
135 -- - Strategy: We could augment this stack frame and see if it changes the
136 -- measure. However, this error should be negligeable.
138 -- * Pattern zone overflow:
139 -- - Description: The stack grows outer than the outermost bound of the
140 -- pattern zone. In that case, the outermost region modified in the
141 -- pattern is not the maximum value of the stack pointer during the
142 -- execution.
143 -- - Strategy: At the end of the execution, the difference between the
144 -- outermost memory region modified in the pattern zone and the
145 -- outermost bound of the pattern zone can be understood as the
146 -- biggest allocation that the method could have detect, provided
147 -- that there is no "Untouched allocated zone" error and no "Pattern
148 -- usage in user code" error. If no object in the user code is likely
149 -- to have this size, this is not likely to happen.
151 -- * Pattern usage in user code:
152 -- - Description: The pattern can be found in the object of the user
153 -- code. Therefore, the address space where this object has been
154 -- allocated will appear as untouched.
155 -- - Strategy: Choose a pattern that is uncommon. 16#0000_0000# is the
156 -- worst choice; 16#DEAD_BEEF# can be a good one. A good choice is an
157 -- address which is not a multiple of 2, and which is not in the
158 -- target address space. You can also change the pattern to see if
159 -- it changes the measure. Note that this error *very* rarely influence
160 -- the measure of the total stack usage: to have some influence, the
161 -- pattern has to be used in the object that has been allocated on the
162 -- outermost address of the used stack.
164 -- * Stack overflow:
165 -- - Description: The pattern zone does not fit on the stack.
166 -- This may lead to an erroneous execution.
167 -- - Strategy: Specify a storage size that is bigger than the
168 -- size of the pattern. 2 times bigger should be enough.
170 -- * Augmentation of the user stack frames:
171 -- - Description: The use of instrumentation object or procedure may
172 -- augment the stack frame of the caller.
173 -- - Strategy: Do *not* inline the instrumentation procedures. Do *not*
174 -- allocate the Stack_Analyzer object on the stack.
176 -- * Untouched allocated zone:
177 -- - Description: The user code may allocate objects that it will never
178 -- touch. In that case, the pattern will not be changed.
179 -- - Strategy: There are no way to detect this error. Fortunately, this
180 -- error is really rare, and it is most probably a bug in the user code,
181 -- e.g. some uninitialized variable. It is (most of the time) harmless:
182 -- it influences the measure only if the untouched allocated zone
183 -- happens to be located at the outermost value of the stack pointer
184 -- for the whole execution.
186 procedure Fill_Stack (Analyzer : in out Stack_Analyzer);
187 -- Fill an area of the stack with the pattern Analyzer.Pattern. The size
188 -- of this area is Analyzer.Size. After the call to this procedure,
189 -- the memory will look like that:
191 -- Stack growing
192 -- ----------------------------------------------------------------------->
193 -- |<---------------------->|<----------------------------------->|
194 -- | Stack frame | Memory filled with Analyzer.Pattern |
195 -- | of Fill_Stack | |
196 -- | (deallocated at | |
197 -- | the end of the call) | |
198 -- ^ | |
199 -- Analyzer.Bottom_Of_Stack ^ |
200 -- Analyzer.Inner_Pattern_Mark ^
201 -- Analyzer.Outer_Pattern_Mark
203 procedure Compute_Result (Analyzer : in out Stack_Analyzer);
204 -- Read the patern zone and deduce the stack usage. It should
205 -- be called from the same frame as Fill_Stack. If Analyzer.Probe is not
206 -- null, an array of Word_32 with Analyzer.Probe elements is allocated on
207 -- Compute_Result's stack frame. Probe can be used to detect an
208 -- "instrumentation threshold at reading" error; See above.
209 -- After the call to this procedure, the memory will look like:
211 -- Stack growing
212 -- ----------------------------------------------------------------------->
213 -- |<---------------------->|<-------------->|<--------->|<--------->|
214 -- | Stack frame | Array of | used | Memory |
215 -- | of Compute_Result | Analyzer.Probe | during | filled |
216 -- | (deallocated at | elements | the | with |
217 -- | the end of the call) | | execution | pattern |
218 -- | ^ | | |
219 -- | Inner_Pattern_Mark | | |
220 -- | | |
221 -- |<----------------------------------------------------> |
222 -- Stack used ^
223 -- Outer_Pattern_Mark
225 procedure Report_Result (Analyzer : Stack_Analyzer);
226 -- Store the results of the computation in memory, at the address
227 -- corresponding to the symbol __gnat_stack_usage_results.
229 type Parameterless_Procedure is access procedure;
231 procedure Initialize_Analyzer
232 (Analyzer : in out Stack_Analyzer;
233 Task_Name : String;
234 Size : Natural;
235 Bottom : Stack_Address;
236 Pattern : Word_32 := 16#DEAD_BEEF#);
237 -- Should be called before any use of a Stack_Analyzer, to initialize it.
238 -- Size is the size of the pattern zone.
239 -- Bottom should be a close approximation of the caller base
240 -- frame address.
242 procedure Output_Results;
243 -- Print the results computed so far on the standard output. Should be
244 -- called when all tasks are dead.
246 private
248 package Word_32_Addr is
249 new System.Address_To_Access_Conversions (Word_32);
251 type Result_Array_Id is range 0 .. 1_023;
253 type Stack_Analyzer
254 is record
255 Size : Natural;
256 -- Size of the pattern zone.
258 Pattern : Word_32 := 16#DEAD_BEEF#;
259 -- Pattern used to recognize untouched memory.
261 Inner_Pattern_Mark : Stack_Address;
262 -- Innermost bound of the pattern area on the stack.
264 Outer_Pattern_Mark : Stack_Address;
265 -- Outermost bound of the pattern area on the stack.
267 Outermost_Touched_Mark : Stack_Address;
268 -- Outermost address of the pattern area whose value it is pointing
269 -- at has been modified during execution. If the systematic error are
270 -- compensated, it is the outermost value of the stack pointer during
271 -- the execution.
273 Bottom_Of_Stack : Stack_Address;
274 -- Address of the bottom of the stack, as given by the caller of
275 -- Initialize_Analyzer.
277 Array_Address : Address;
278 -- Address of the array of Word_32 that represents the pattern zone.
280 First_Is_Outermost : Boolean;
281 -- Set to true if the first element of the array of Word_32 that
282 -- represents the pattern zone is at the outermost address of the
283 -- pattern zone; false if it is the innermost address.
285 Result_Id : Result_Array_Id;
286 -- Location in the result array of the result for the current task.
287 end record;
289 end System.Stack_Usage;