-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Move funclets invocation to code managers #114180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move funclets invocation to code managers #114180
Conversation
This change moves exception handling funclets invocation to the ICodeManager so that it can be done differently for JITted/crossgened code and interpreted code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR moves funclet invocation for exception handling into ICodeManager‑derived classes so that different implementations can be provided for JITted/crossgened versus interpreted code.
- Removed direct usage of GetEstablisherFrame and handler function calls in catch, finally, and filter funclet blocks in exceptionhandling.cpp.
- Updated EECodeManager in eetwain.cpp and its corresponding interface in eetwain.h to include a CallFunclet virtual method for funclet invocation.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
src/coreclr/vm/exceptionhandling.cpp | Replaced direct funclet calls with CodeManager::CallFunclet invocations. |
src/coreclr/vm/eetwain.cpp | Added alternative implementation for CallFunclet and GetEstablisherFrame. |
src/coreclr/inc/eetwain.h | Updated the virtual method declarations for CallFunclet. |
CastHandlerFn(pfnHandler), | ||
GetFirstNonVolatileRegisterAddress(pvRegDisplay->pCurrentContext), | ||
pFuncletCallerSP); | ||
dwResumePC = exInfo->m_frameIter.m_crawl.GetCodeManager()->CallFunclet(throwable, pHandlerIP, pvRegDisplay, exInfo, false /* isFilterFunclet */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that the new CallFunclet invocation in the catch funclet correctly replicates the behavior (especially the resume address) of the previous direct handler call. It may be beneficial to document any behavioral differences introduced by delegating to the CodeManager.
Copilot uses AI. Check for mistakes.
DWORD_PTR dwResumePC = pfnHandler(establisherFrame, NULL); | ||
#endif | ||
|
||
exInfo->m_frameIter.m_crawl.GetCodeManager()->CallFunclet(NULL, pHandlerIP, pvRegDisplay, exInfo, false /* isFilterFunclet */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirm that discarding the return value from CallFunclet in the finally funclet case is intentional and that no downstream logic depends on it; consider adding a clarifying comment if necessary.
Copilot uses AI. Check for mistakes.
cc: @filipnavara |
dwResumePC = exInfo->m_frameIter.m_crawl.GetCodeManager()->CallFunclet(throwable, pHandlerIP, pvRegDisplay, exInfo, false /* isFilterFunclet */); | ||
|
||
#ifdef USE_FUNCLET_CALL_HELPER | ||
FixContext(pvRegDisplay->pCurrentContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make sense to move the FixContext
logic inside EECodeManager::CallFunclet
. Afterall I don't expect it to be relevant for interpreter (ignoring the fact that we don't support interpreter on x86) and it only calls back into the code manager anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've actually had it there, but moved it back. It is used for catch funclet only, so I would have to add another flag to the signature to distinguish catch. The context fixing is only relevant to the resuming after catch and that happens here, not in the code manager. I would actually prefer replacing the fixcontext here by its body and ifdef it on x86, since the function does nothing for all other architectures.
There is some Linux problem, I am investigating. |
I've missed the fact that the macro is defined in the exceptionhandling.cpp only, so the move to eetwain.cpp disabled this feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unix test failures look real
@jkotas Yes, I've been looking into that whole day and finally found the culprit. The C++ compiler optimized the call to the actual funclet from the CallFunclet as a tail call, so the m_csfEHClause wasn't the caller SP. The StackFrameIterator depends on that. I have fixed that by disabling optimizations for the CallFunclet on Windows / disabling tail calling on Unix. I am running the tests now and will update the PR soon. |
src/coreclr/vm/eetwain.cpp
Outdated
#else | ||
HandlerFn* pfnHandler = (HandlerFn*)pHandler; | ||
|
||
pExInfo->m_csfEHClause = CallerStackFrame((UINT_PTR)GetCurrentSP()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this line be in the #else
of #ifdef USE_FUNCLET_CALL_HELPER
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(It would be nice to update x64 to use the asm helper too at some point, so we should keep all workarounds related to that under the !asm helper ifdef.
Switching x64 to asm helper should improve code size of the EH codegen and remove unnecessary differences between architectures.
src/coreclr/vm/eetwain.cpp
Outdated
|
||
pExInfo->m_csfEHClause = CallerStackFrame((UINT_PTR)GetCurrentSP()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pExInfo->m_csfEHClause = CallerStackFrame((UINT_PTR)GetCurrentSP()); |
This change moves exception handling funclets invocation to the
ICodeManager
derived classes so that it can be done differently for JITted/crossgened code and interpreted code.