RFR(L): 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9

Roland Westrelin roland.westrelin at oracle.com
Wed Apr 9 17:18:52 UTC 2014


Hi Vladimir,

> I tried to tell about this during review ;) I thought using (<=StackShadowPages) from 8026775 changes should touch it.

Sorry Vladimir. I didn’t realize there could be a problem even before the end of the stack is reached. I should have read 8026775 more carefully.

> Can you spend sometime and write down in bug report about all places where we do stack bang and how much pages we bang so we can see whole picture?
> 
> I think we should bang all sequential pages and do the same in all places. Banging StackShadowPages or StackShadowPages+1 is secondary if we do the same in all places.

Ready for some headaches?

The interpreter: allocates the current frame and then stack bangs all pages at sp+1*page … sp+StackShadowPages*page included
The compiler bangs (before my change): sp + StackShadowPages*page and the next frame_size/page_size pages
In the deopt blob we bang: sp (once the compiled frame is popped) +1 page … sp+(StackShadowPages+1)*page and the next frame_size/page_size pages

I talked with Mikael and the reason we bang up to (StackShadowPages+1)*page in the deopt blob is because in the interpreter, banging happens once the frame is set up. So banging up to StackShadowPages*page in the deopt blob with no frame pushed doesn’t bang as far as the interpreter would.

Let’s take an example with my change (no banging in the deopt blob) and if the compiler bangs at sp+StackShadowPages*page. I think something like this is possible:
Let’s say StackShadowPages=2

1) SP points in page P. We enter an interpreted frame. The frame is allocated. SP is still in P. The interpreter bangs P+1 and P+2.
2) The interpreter calls a compiled method. The compiled method is entered with SP still in P but right before the boundary with the next page. The compiler bangs P+2.
3) We deoptimize. We pop the frame. SP is in P right before the page boundary. The method has a lot of locals and the interpreter frame size is just below 1 page. After deoptimization SP is in P+1 right before the boundary.
4) We’re at a call, push some arguments and SP moves to P+2 and we call a compiled method. The compiled method bang P+4. P+3 was never touched.

Had the compiler banged at P+3 (StackShadowPages+1) in 2), there would be no problem in that example. But then another example with my change and if the compiler bangs at sp+(StackShadowPages+1)*page. Let’s say StackShadowPages=2.

1) SP points in page P. We enter an interpreted frame. The frame is allocated. SP is still in P but right before the page boundary. The interpreter bangs P+1 and P+2.
2) The interpreter pushes some arguments and we are now in P+1 and calls a compiled method. The compiler bangs P+4. P+3 was never touched.

So that doesn’t work either.

Wishing we had a whiteboard again? ;-)

Maybe the solution is for the compiler to bang at sp + StackShadowPages*page + (interpreter_frame_size % page) and the next interpreter_frame_size/page_size pages. That would mimic what the interpreter does and would work in both examples, above I think. interpreter_frame_size would have to not include what’s on the expression stack of the top frame to be as close as possible to the interpreter behavior.

Roland.


> 
> Thanks,
> Vladimir
> 
> On 4/2/14 1:46 AM, Roland Westrelin wrote:
>>> The question is why you got EXCEPTION_ACCESS_VIOLATION for normal stack bang?  May be it is 8026775 again when one page is skipped during banging. Windows requires sequential pages touche.
>> 
>> I wasn’t aware of this requirement on windows. Thanks, Vladimir.
>> The interpreter bangs up to and including sp + StackShadowPages while the compiled code, with this change, bangs at sp + StackShadowPages + 1. So a page can be skipped and the requirement that all pages be touched sequentially cannot be guaranteed. So we either have to go back to banging at sp + StackShadowPages for the compiled code or enable the code that I pointed to in the signal on 32 bit. What do you think?
>> 
>> Roland.
>> 
>>> 
>>> Thanks,
>>> Vladimir
>>> 
>>> On 4/1/14 8:00 AM, Roland Westrelin wrote:
>>>> I tried to push that change and couldn’t because of a crash on windows 32 bit. The VM crashes at a stack banging instruction in compiled code but the sp looks to be perfectly valid (not in the yellow zone or red zone, within the stack bounds). I noticed this code in the windows signal handler:
>>>> 
>>>> #ifdef _WIN64
>>>>           //
>>>>           // If it's a legal stack address map the entire region in
>>>>           //
>>>>           PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
>>>>           address addr = (address) exceptionRecord->ExceptionInformation[1];
>>>>           if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
>>>>                   addr = (address)((uintptr_t)addr &
>>>>                          (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
>>>>                   os::commit_memory((char *)addr, thread->stack_base() - addr,
>>>>                                     !ExecMem);
>>>>                   return EXCEPTION_CONTINUE_EXECUTION;
>>>>           }
>>>>           else
>>>> #endif
>>>> 
>>>> If I enable it on 32 bit, the jprt tests pass. Does anybody know why this is needed? Why this is WIN64 only?
>>>> 
>>>> Roland.
>>>> 
>> 



More information about the hotspot-compiler-dev mailing list