[x86/Linux] Initial patch to restore EBP for funclet#9300
Conversation
| getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, REG_FPBASE, REG_FPBASE, -8); | ||
| // mov eax, [esp + 12] ; exception object to eax: funclet needs eax having the exception object | ||
| getEmitter()->emitIns_R_AR(INS_mov, EA_PTRSIZE, REG_EAX, REG_SPBASE, 12); | ||
|
|
There was a problem hiding this comment.
It would be better to use REG_EXCEPTION_OBJECT instead of REG_EAX (although they are same).
|
|
||
| // Save callee-saved registers | ||
| genPushCalleeSavedRegisters(); | ||
| } |
There was a problem hiding this comment.
It would be better to invoke genPushCalleeSavedRegisters in the middle of unwindBegProlog and unwindEndProlog
There was a problem hiding this comment.
Problem is that it will change the ESP, now knowing the amount, so EBP restore offset and also for EAX should have calculated offset not fixed 8 and 12. If genPushCalleeSavedRegisters must be in between, I need to find another way to restore EBP and EAX.
There was a problem hiding this comment.
Or, we may skip callee-saved registers save/restore (as discussed in #9245).
| * |-----------------------| | ||
| * | Outgoing arg space | // this only exists if the function makes a call | ||
| * |-----------------------| | ||
| * | | | |
There was a problem hiding this comment.
There may be no outgoing arg space as FEATURE_FIXED_OUT_ARGS is not set for x86.
There was a problem hiding this comment.
It's for spaces when calling other methods, if any, inside funclets with "push" instruction.
There was a problem hiding this comment.
I think this block can be removed as you noted.
This is a initial patch to restore EBP and Exception object for funclets With this patch it fixes lots of try-catch fails like PinObj-neg.exe Further changes are needed for nested try-catch.
| * | ||
| * Funclets have the following incoming arguments: | ||
| * | ||
| * catch/filter-handler: ebp+8 = CallerSP, ebp+12 = the exception object that was caught (see GT_CATCH_ARG) |
There was a problem hiding this comment.
This calling convention for funclets looks odd. Was it inspired by something?
I think the natural calling convention for funclets would be:
ecx = establisher frame
edx = exception object
ebp, esi, edi, ebx = restored to what they were when the control flow left the method last time
There was a problem hiding this comment.
It seems that the following code in exceptionhandling.cpp invokes funclets:
//
// Invoke the funclet.
//
dwResumePC = pfnHandler(sf.SP, OBJECTREFToObject(throwable));
pfnHandler is of type HandlerFn *:
src/ $ grep -Rn 'pfnHandler'
vm/exceptionhandling.cpp:3241: HandlerFn* pfnHandler = (HandlerFn*)uHandlerStartPC;
src/ $ grep -Rn 'HandlerFn'
...
vm/exceptionhandling.h:35:typedef DWORD_PTR (HandlerFn)(UINT_PTR uStackFrame, Object* pExceptionObj);
There is no calling convention annotation on HandlerFn which means that CDECL.
There was a problem hiding this comment.
Should we introduce CallEHFunclet and CallEHFilterFunclet for x86 as in ARM/ARM64?
This is a initial patch to restore EBP and Exception object for funclets
With this patch it fixes lots of try-catch fails like PinObj-neg.exe
Further changes maybe needed for nested try-catch.