|
|
| Author |
Message |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 24 January 2006, 1:17 AM Post subject: Stack Use Analysis |
|
|
An experimental version of the compiler has been created that performs a stack use analysis on a program. The stack use information is shown in the .map file alongside other information about each procedure. Also, if the compiler option --calls-list is given the stack space used by each called procedure is shown in the list.
A new section has been added to the .map file that shows the stack space required for each task. Additionally, the compiler will compare the calculated stack space against the available stack space and will generated a warning if the calculated size plus a safety margin exeeds the available space. By default, the safety margin is 10 bytes but it may be set for each module using the syntax:
| Code: | | Option TaskStackMargin <value> |
where <value> is a decimal integer value.
This version of the compiler also contains a correction for the reversed opcodes generated for Shr() and Shl() for Integer and UnsignedInteger operands. Although this correction has not yet been completely tested it is highly likely that it will pass the regression tests due to the very narrow scope of the change required for the correction.
Because this version of the compiler is experimental, it is not posted on the Downloads page. Rather, you may download it directly using the link:
http://www.zbasic.net/download/ZBasic/ZBasic_1-1-5.zip |
|
| Back to top |
|
 |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 24 January 2006, 7:00 AM Post subject: |
|
|
Nice idea
The stack checking is really helpful and looks like it found a problem in some recent code I wrote (AN208). I have several comments:
1. In the task stack table it would be nice to relate the required stack size to the declared stack size e.g.
| Code: | --- Task Stack Information
Stack Min. Actual Task
Size Margin Size Size Module.Procedure
----- ------ ----- ------ ------------------------
31 0 31 30 SRF.doRanging
39 5 44 60 RemoteControl.GetIRCodeTask
125 5 130 655 Robot.Main |
2. The compiler message is not very clear. It just says "too small" rather than giving the size needed. It would be also nice to point to the stack declaration line rather than the CallTask statement but that might be harder to do.
3. The --calls-list option doesn't seem to work for me. If I use --called-by-list then I get both lists, using --calls-list results in no lists.
4. Many of the stack operations in ZBasic (and BasicX) are completely deterministic about the stack usage and even conditional paths have the correct result. The problem came about with strings and some particularly strange BasicX stack pointer manipulation that made it impossible to calculate the correct stack usage through static analysis. If you don't have this problem with ZBasic then the requirement for stack margin goes away because "static stack usage" is the same as "dynamic stack usage".
5. I cannot check the actual results because I don't have any documentation about the stack usage for each ZBasic instruction. However the results do look reasonable. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 24 January 2006, 16:57 PM Post subject: |
|
|
| Quote: | | In the task stack table it would be nice to relate the required stack size to the declared stack size e.g. |
That is a good idea. However, since it is possible for a task to be invoked multiple times with different stacks it will be necessary to replace the task list with a task invocation list.
| Quote: | | The compiler message is not very clear. ... It would be also nice to point to the stack declaration line rather than the CallTask statement but that might be harder to do. |
This can be done.
| Quote: | | The --calls-list option doesn't seem to work for me. |
I'll see what's up with that.
| Quote: | | If you don't have this problem with ZBasic then the requirement for stack margin goes away because "static stack usage" is the same as "dynamic stack usage" |
It is true that ZBasic have the same problem with pushing strings on the stack as BasicX does. For some System Library routines, string parameters are pushed as two or four bytes but the analysis assumes the worst case. Of course, you can set the margin to zero but I think that it is useful to have it to allow a programmer-specified safety margin.
Also, dynamic stack usage may be larger than the statically computed value in the presence of recursion. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 24 January 2006, 19:54 PM Post subject: |
|
|
| Quote: | | The --calls-list option doesn't seem to work for me. |
Confirmed and fixed. As you noted, using --called-by-list currently results in both the called-by and the calls lists being generated. |
|
| Back to top |
|
 |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 24 January 2006, 23:14 PM Post subject: |
|
|
| dkinzer wrote: | | However, since it is possible for a task to be invoked multiple times with different stacks it will be necessary to replace the task list with a task invocation list. | This is what bxDism does.
| dkinzer wrote: | It is true that ZBasic have the same problem with pushing strings on the stack as BasicX does. For some System Library routines, string parameters are pushed as two or four bytes but the analysis assumes the worst case. Of course, you can set the margin to zero but I think that it is useful to have it to allow a programmer-specified safety margin.
| You should be able to tell if the string is a 2 or 4 byte value on the stack. In the case of 4 bytes then the stack size is determinate because the string data is on the heap. Where possible the use of the 2 byte form should be discouraged but I agree in that case it is very difficult to calculate stack usage througth static analysis. Is there a way to not use 2 byte string usage (at least for system library routines? I have a feeling that we had this discussion during the Beta and the answer was no.
| dkinzer wrote: | | Also, dynamic stack usage may be larger than the statically computed value in the presence of recursion. | It is doubtful that a safety margin will deal with the problem of recursion in any case so I will discount that situation. It's important but nothing can be done about it except to signal possible use of recursion as a compiler warning. |
|
| Back to top |
|
 |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 24 January 2006, 23:34 PM Post subject: Re: Stack Use Analysis |
|
|
| dkinzer wrote: | | An experimental version of the compiler has been created that performs a stack use analysis on a program. |
New problem: Some of the ZBasic keyword highlighting has stopped working. Keywords such as Then and Sub no longer work. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 25 January 2006, 2:06 AM Post subject: |
|
|
| Quote: | | New problem: Some of the ZBasic keyword highlighting has stopped working. |
The compiler plays no part in keyword highlighting. Nevertheless, I'll see what I can find.
Update: There is a missing backslash in the IDE's bas.properties file that causes this problem. It can be easily rectified. See http://www.zbasic.net/forum/about162.html
Last edited by dkinzer on 28 January 2006, 18:59 PM; edited 1 time in total |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 25 January 2006, 2:14 AM Post subject: |
|
|
| Quote: | | You should be able to tell if the string is a 2 or 4 byte value on the stack. ... Where possible the use of the 2 byte form should be discouraged... |
If a string is passed by reference, it always occupies two bytes on the stack. When passed by value, the actual parameter may be the result of an expression evaluation that cannot be determined at compile time. If the actual string parameter is an empty string, it only occupies two bytes on the stack, otherwise four.
In any event, I believe that the current code handles the various cases correctly and also correctly accounts for worst case behavior when the actual behavior cannot be determined at compile time. |
|
| Back to top |
|
 |
Genesis
Joined: 15 Jan 2006
Posts: 28
|
|
Posted: 28 January 2006, 17:59 PM Post subject: |
|
|
This capability is extremely cool.
It caught a potential task stack problem for me already - I like it plenty..... |
|
| Back to top |
|
 |
|