-
Notifications
You must be signed in to change notification settings - Fork 5k
[clr-interp] Implement CEE_LOCALLOC
and frame data allocator for dynamic stack allocations
#114860
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
[clr-interp] Implement CEE_LOCALLOC
and frame data allocator for dynamic stack allocations
#114860
Conversation
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 implements dynamic stack allocation capabilities in the interpreter by introducing a frame data allocator and adding support for the CEE_LOCALLOC opcode.
- Added comprehensive tests for localloc operations in Interpreter.cs
- Implemented frame data allocator infrastructure and dynamic memory allocation functions in interpexec.{h,cpp}
- Updated the interpreter compiler to generate code for CEE_LOCALLOC and overflow-check multiplication opcodes
Reviewed Changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
src/tests/JIT/interpreter/Interpreter.cs | Added tests for dynamic stack allocation via TestLocalloc() |
src/coreclr/vm/interpexec.h | Added definitions for FrameDataFragment, FrameDataInfo, and FrameDataAllocator structures |
src/coreclr/vm/interpexec.cpp | Implemented functions for managing dynamic stack memory and added INTOP_LOCALLOC opcode handling |
src/coreclr/interpreter/compiler.cpp | Updated code generation to support CEE_LOCALLOC and checked overflow multiplication opcodes |
Files not reviewed (1)
- src/coreclr/interpreter/intops.def: Language not supported
Comments suppressed due to low confidence (2)
src/coreclr/vm/interpexec.cpp:1266
- Ensure that the ALIGN_UP macro and related allocation logic correctly enforce the required alignment for dynamic stack allocations to avoid subtle memory issues.
mem = frame_data_alloc(&pThreadContext->frameDataAllocator, (InterpreterFrame*)pFrame, ALIGN_UP(len, INTERP_STACK_ALIGNMENT));
src/coreclr/interpreter/compiler.cpp:3145
- The handling of the CEE_LOCALLOC opcode involves pointer arithmetic and stack pointer adjustments; please verify that these operations maintain the stack invariants under all conditions to prevent runtime errors.
case CEE_LOCALLOC:
Tagging subscribers to this area: @BrzVlad, @janvorli, @kg |
… FrameDataAllocator code to interpframeallocator.cpp/h. Add TODO comments.
src/coreclr/vm/interpexec.cpp
Outdated
@@ -1129,6 +1204,8 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr | |||
goto MAIN_LOOP; | |||
} | |||
|
|||
// Interpreter-TODO: FrameDataAllocator is owned by the current thread, free it when the thread exits instead of here | |||
delete pThreadContext->pFrameDataAllocator; |
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 am not sure how can we delete the allocator here. If I understand it correctly, we allocate it in the InterpGetThreadContext
, but only if the t_pThreadContext
was not set yet. And we delete it here when we exit from a block of interpreted frames that can happen many times. E.g. with the EH, a catch funclet exits here and then we resume in the parent function after the catch. That means that after resuming from catch, the pFrameDataAllocator
would be invalid.
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.
That workaround was only temporary, but you are right. I’ve now implemented a destructor for InterpThreadContext. Please let me know if there is a deterministic place to destroy the thread context.
If this approach is reasonable, I would move the initialization into the constructor instead.
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 would prefer moving the InterpThreadContext
instance to the coreclr Thread
class instead and performing the cleanup in the Thread::~Thread
or Thread::OnThreadTerminate
. Having a thread local object with a destructor is a recipe for possible problems due to the fact that the order of their destruction is arbitrary.
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.
Implemented the InterpThreadContext constructor and destructor, and moved its instance into the CoreCLR Thread class. It is now created lazily on first pThread->GetInterpThreadContext()
in prestub.cpp. This ensures that all allocated memory is properly released when the Thread destructor runs.
… destructor. Inline FrameDataAllocator into InterpThreadContext and ensure allocated memory is released
src/coreclr/vm/interpexec.cpp
Outdated
|
||
if (len > 0) | ||
{ | ||
pMemory = pThreadContext->frameDataAllocator.Alloc(pFrame, &len); |
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.
pMemory = pThreadContext->frameDataAllocator.Alloc(pFrame, &len); | |
pMemory = pThreadContext->frameDataAllocator.Alloc(pFrame, len); |
It is not necessary to use the aligned length for memset. We just need to clear the memory that the user code asked for. We do not need to clear the extra padding.
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.
LGTM, thank you!
Description
This PR adds support for the
CEE_LOCALLOC
and frame data allocator to the interpreter for handling dynamic stack allocations.Changes
CEE_LOCALLOC
with a frame data allocator for dynamic stack memorystackalloc
argumentsFrameDataAllocator
based on the existing allocatorruntime/src/mono/mono/mini/interp/interp-internals.h
Lines 219 to 225 in d9c4c3e
Validation
Tests in
Interpreter.cs
covering frame data allocator scenarios.