Skip to content
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

Split up loader heap implementations #114246

Merged

Conversation

davidwrighton
Copy link
Member

@davidwrighton davidwrighton commented Apr 3, 2025

We have long had 3 rather different heaps embedded in one structure called a LoaderHeap. They have shared ... some infrastructure, but there is a mess of confusing flags and code paths which only work for one or the other type of heap.

This PR changes that to supporting the 3 different types of heaps with separate codebases, and keeps as much of the shared infrastructure as I could manage. Its, not what I would call a pretty separation, as there is a bit of a mess around the way the DAC apis can access the heaps, but I think this is an improvement. Notably, in a followon PR I'm intending to provide a new mechanism for the interleaved heap to work off of contents of a file instead of creating unique pages per stub block. (This should slighly improve the cache locality of .NET programs, and is a prerequisite for running on some heavily locked down platforms.) This PR prepares for that by making the Interleaved heap its own thing, so adding new behavior variants is a reviewable piece of work.

The only functional change that happens with this PR is the newly added capability of the interleaved heaps to support freeing memory. (It was always possible to free, but for some reason the re-allocation behavior was not actually supported.)

Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

@davidwrighton davidwrighton changed the title [DRAFT] Split up loader heap implementations Split up loader heap implementations Apr 8, 2025
@davidwrighton davidwrighton marked this pull request as ready for review April 8, 2025 21:57
@Copilot Copilot bot review requested due to automatic review settings April 8, 2025 21:57
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • src/coreclr/utilcode/CMakeLists.txt: Language not supported

Comment on lines 316 to 318
"\nset the following registry DWORD value:"
"\n"
"\n HKLM\\Software\\Microsoft\\.NETFramework\\LoaderHeapCallTracing = 1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"\nset the following registry DWORD value:"
"\n"
"\n HKLM\\Software\\Microsoft\\.NETFramework\\LoaderHeapCallTracing = 1"
"\nset the following environment variable:"
"\n"
"\n DOTNET_LoaderHeapCallTracing=1"

@davidwrighton
Copy link
Member Author

/ba-g the failing test is unrelated to this change and was fixed by Michal earlier today.

@davidwrighton davidwrighton requested a review from jkotas April 10, 2025 00:02
@am11
Copy link
Member

am11 commented Apr 10, 2025

Copilot spotted a typo #114246 (comment).

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Member

@janvorli janvorli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

// and notify the user to provide more reserved mem.
_ASSERTE((dwSizeToCommit <= dwSizeToReserve) && "Loaderheap tried to commit more memory than reserved by user");

if (!fReleaseMemory)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fReleaseMemory is always set to TRUE at this point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix that. Thanks.


INDEBUG(m_dwDebugWastedBytes += unusedRemainder;)

// For interleaved heaps, further allocations will start from the newly committed page as they cannot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - maybe remove the "For interleaved heap, " from multiple comments here, that was only usefull originally when the code for interleaved heaps stuff was intertwined with the other code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to revisit these comments with the page remapping logic in my next PR. I'll address this then.

//
// Caller is responsible for synchronization. ExplicitControlLoaderHeap is
// not multithread safe.
// The LoaderHeap is the black-box heap and has a Backout() method but none
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment does not match InterleavedLoaderHeap


protected:
void *UnlockedAllocMemForCode_NoThrow(size_t dwHeaderSize, size_t dwCodeSize, DWORD dwCodeAlignment, size_t dwReserveForJumpStubs);
// This frees memory allocated by UnlockAllocMem. It's given this horrible name to emphasize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// This frees memory allocated by UnlockAllocMem. It's given this horrible name to emphasize
// This frees memory allocated by UnlockedAllocStub. It's given this horrible name to emphasize

void SetReservedRegion(BYTE* dwReservedRegionAddress, SIZE_T dwReservedRegionSize, BOOL fReleaseMemory)

public:
// This frees memory allocated by AllocMem. It's given this horrible name to emphasize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// This frees memory allocated by AllocMem. It's given this horrible name to emphasize
// This frees memory allocated by AllocStub. It's given this horrible name to emphasize

#define DONOT_DEFINE_ETW_CALLBACK
#include "eventtracebase.h"

#ifndef DACCESS_COMPILE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the file to (non-DAC) UTILCODE_SOURCES in CMakeLists.txt instead of end-to-end ifdef

m_codePageGenerator = codePageGenerator;
}

// ~LoaderHeap is not synchronised (obviously)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// ~LoaderHeap is not synchronised (obviously)


// Interleaved heap cannot ad any extra to the requested size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Interleaved heap cannot ad any extra to the requested size

@davidwrighton davidwrighton merged commit e6f38d7 into dotnet:main Apr 12, 2025
98 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants