Lifetime of Parameters and Local Variables
pjv
Posts: 1,903
Hello All;
I've been buried in PASM for much too long, and am now doing some things in Spin, but I do not know much about higher level language concepts, so I'm experimenting.
A question that I am looking to have answered, is: what is the lifetime of the values in parameters passed to a method as well as the lifetime of local variables in the method ?
More precisely, when I invoke MethodA which calls MethodB, are MethodA's parameters and locals valid in MethodB, and are MethodB's values still valid in MethodA after exiting MethodB.
And what about their values after exiting both methods ?
So far most of my work has been software employing a single cog. Does mutiple cogs affect my observations ?
Insight into this would be much appreciated.
Cheers,
Peter (pjv)
I've been buried in PASM for much too long, and am now doing some things in Spin, but I do not know much about higher level language concepts, so I'm experimenting.
A question that I am looking to have answered, is: what is the lifetime of the values in parameters passed to a method as well as the lifetime of local variables in the method ?
More precisely, when I invoke MethodA which calls MethodB, are MethodA's parameters and locals valid in MethodB, and are MethodB's values still valid in MethodA after exiting MethodB.
And what about their values after exiting both methods ?
So far most of my work has been software employing a single cog. Does mutiple cogs affect my observations ?
Insight into this would be much appreciated.
Cheers,
Peter (pjv)
Comments
If method A calls method B, method A's parameters and local variables are still on the stack, but their names are known only within method A, so you can't really access them from method B.
Using multiple cogs doesn't change this. Each cog has its own stack and any methods executing refer to the copy of their variables on their (private) stack.
As they live on the stack there is in theory a possibility to access the variables, but in SPIN there is no stack-pointer available, so there is no easy way to do this. And to make this very clear: It would also be a very bad idea to do this! One function should not assume that it's called from ONE other function! In case both functions need the same variable you have several options:
Make the variable global
Pass a pointer to the function
Use getter and setter functions
When the function returns parameters and local variables are not cleaned up. So the values are still available on the stack until there is the next function call. Writing about that I have an interesting idea. You can for example call
MethodB(par1, par2, par3)
And Method B returns the address of par1. Then the calling function can access all parameters which allows to return more than one value!
But you need to be aware that these have to be rescued before calling the next function!
Multiple COGs work with multiple stacks. So, as long as you do not exceed the limit of the stacks there is no affect. The speciality of the first COG (which starts your code) is that this COG has the whole unused HUB-RAM as stack-space. So, with small amount of beginners code you'll never run into stack-problems.
print_i is able to output the value of start local variable i because it's still on the stack -- behind the return address and the (unused) result variable. But by the time start attempts to retrieve the value of print_i's local variable j, it's already been clobbered by intervening stack manipulations for expression evaluation.
-Phil
Thank you so much for your prompt responses.
So, if I distill down what I interpret from these answers (and my experimentation) is that the values on the stack will not be affected by activity within other cogs, and the value will remain valid while in each respective method. And still valid after exiting each method until some further method is called with some parameters.
In my particular case, speed is everything, and transferring parameters into global variables consumes 36 microseconds, so I would prefer to just pass the address of the parameter list an additional method and saving the transfer time. My methods are very skinny, and I believe I would not mess up the stack between consecutive operations. At least that is what my experimentation indicates.
Thank you again for your comments.
Cheers,
Peter (pjv)
-Phil
Cheers
Peter (pjv)
You can't expect that the pst function-calls don't clobber the stack. So the right test would look like this:
and this prooves that only function calls destroy the stack and not expressions! Makes sense, because I guess that there is a register inside the COG which is used to calculate expressions. And it does not make sense to write back intermediate results. And end results propably don't need to be stored at all. And if so, they will be stored with an assignment directly in the right location and not on the stack.
But thank you phil, now I took the time to also try out the multi value passback and it works: Not sure whether this is usefull, but it works!
-Phil
Out of curiosity I wrote some small tests! It looks like the SPIN language makes heavy usage of the stack! Repeat loops, case statements and EXPRESSIONs use the stack! So, why does the example (post #9) work? It's because the calculation only needs 2 longs regardless of how complex the expression is (when no function call is involved!). This means that the calculation of [@i+16] only overwrites the return-address and the return-value of the previous function call. All parameters and local variables are untouched.
Learning never ends! )