
2009/4/20 Peter Hercek
Simon Marlow wrote:
Peter Hercek wrote:
The proposed meaning for :next
Lets mark dynamic stack size at a breakpoint (at which we issue :next) as breakStackSize and its selected expression as breakSpan. Then :next would single step till any of these is true: 1) current dynamic stack size is smaller than breakStackSize 2) current dynamic stack size is equal to breakStackSize and the current selected expression is not a subset of breakSpan
So what happens if the stack shrinks and then grows again between two breakpoints? Presumably :next wouldn't notice.
Yes, if there is no breakpoint in between I would not notice. I did not expect this can happen though. I thought that to add a frame on the stack this must be done within an expression (which is going to be forced) and the expression should be a breakpoint location. If it is so negligible that it does not have a breakpoint location associated then even the things it is calling should be negligible. Where is an error in this?
You can't assume that there are breakpoints everywhere. Compiled code doesn't have breakpoints, for example. Even in interpreted code, there is compiler-generated code that doesn't have breakpoints in it, and after transformations breakpoints may have moved around.
I think you'd be better off implementing this with a special stack frame, so that you can guarantee to notice when the current "context" has been exited.
This would be robust but I do not have knowledge to do it yet. If I understand you correctly this means that before executing a BCO which we are going to break at, we must prepare for a possible :next. So regardless whether :next is going to be issued by the user or not we would add a frame which represents a return to a function which: a) if user issued :next it enables all breakpoints so that we stop at the next breakpoint b) if user did not issue a break it would not do anything (just return)
Yes, exactly. Although we have to worry about stack growth: we don't want the addition of a new stack frame to change constant stack-usage into linear stack-usage, so perhaps we would have to avoid pushing these frames directly on top of each other.
We could decide not to insert the frame when we are only tracing. But if I would want to track a simulated dynamic stack I would need to insert this stack frame at the start of each breakpoint (when dynamic stack tracing would be on). Does not sound that good.
I hope the above would make good sense but I do not really know since maybe rts does some funny things with stack sometimes. If you think the proposed behavior is garbage let me know why so that I do not waste more time with this :)
Yes the RTS does do "funny thing" with the stack sometimes. The stack can shrink as a result of adjacent update frames being coalesced ("stack squeezing").
OK, so it looks like either switching off the squeezing (if shrinking and growing stack between breakpoints/ticks is not such an issue), or inserting a stack frame. Does the "stack squeezing" happen during garbage collection?
It can happen any time, so yes. Cheers, Simon