alloca attribute?

Perry Smith pedz@easesoftware.com
Wed Nov 29 14:17:00 GMT 2006


On Nov 29, 2006, at 4:19 AM, Andrew Haley wrote:

> Perry Smith writes:
>> I wrote a class that switches the stack to a new area.  This is for
>> the power PC.
>>
>> In the text below, I'll use main, testit, and newStack.  main is the
>> main program, testit is a function that main calls, and newStack is
>> the method that switches the stack to the new space.  main calls
>> testit which calls s.newStack.  (s is an instance of the class that
>> switches the stack).
>>
>> The purpose of separating main and testit is so I can verify that
>> returning from testit works properly.
>>
>> newStack gets the current value of r1 (the stack pointer) and copies
>> the last two stack frames (which would be the stack frame for testit
>> and newStack) to the top of some allocated memory.  It alters r1(0)
>> (the previous stack value for newStack) in the new memory to point to
>> the address of testit's new stack frame.  It sets r1 up to the base
>> of this new area and returns.
>
> OK, before we go any further.  Did you write and test DWARF unwinder
> information for newStack?

No, I did not.  I thought it would be too big a task and I'm willing  
to put a try/catch
after the stack has been changed so the unwind does not need to go  
through
this.  This may be naive.  (See more below).

>> With g++ and no optimization, this works.  When newStack returns,
>> it consumes its stack frame in the new memory leaving only testit's
>> new stack frame and r1 pointing to the base of the new stack from
>> for testit.  When testit returns, it loads r1 with r1(0) and
>> returns.  This properly puts r1 back to main's stack frame.
>>
>> If I put -O3, then at the return of testit, instead of loading r1
>> with r1(0), just adds in the size of the stack frame (and assumes
>> that r1 has not been munged with).  I presume this is faster.  I
>> know that xlc does the same thing.  As a result, when we return
>> back to main, the stack pointer is off in the weeds somewhere.
>
> I get the feeling I'm not understanding something here.  As long as
> newStack is correct and handles all registers according to the ABI,
> there shouldn't be any trouble.

I'm sure you understand this better than I do.  Can you point me to  
the info
needed for the DWARF unwinder you mention above?  That may educate me
more.

It still seems I am going to have problems so I will try and repeat  
the symptom:

The code generated to return from a function can have two forms.   
Logically, it is
a three step process.  Pick up the return address which is located at  
r1(8) (assuming
  a 32 bit system) into a register (like r0),  replace r1 with r1(0)  
which moves r1 to
point to the previous stack frame, and then branch to what was at r1(8).

But in optimized code, the compiler does not load r1 with r1(0).  It  
assumes that r1
has not changed, and it knows the size of the stack frame, it just  
adds the size of the
stack frame to r1.  This will be the same address if r1 has not been  
changed.

It seems like (but I may be wrong), even with the DWARF unwinder  
information, the
compiler will still produce the code that adds the size of the stack  
from to r1 to get
r1 to point to the previous stack frame instead of loading r1 with r1 
(0).

Am I making sense?

Perry Smith ( pedz@easesoftware.com )
Ease Software, Inc. ( http://www.easesoftware.com )

Low cost SATA Disk Systems for IBMs p5, pSeries, and RS/6000 AIX systems




More information about the Gcc-help mailing list