Skip to content

Interpreter GC info stage 3: Report locals to the GC #114469

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

kg
Copy link
Member

@kg kg commented Apr 10, 2025

This updates the interpreter compiler to use GcInfoEncoder to allocate slot IDs for interp vars and then report their liveness ranges (unless they're globals).
I template-specialized the implementation of TGcInfoDecoder<InterpreterGcInfoEncoding>::GetStackSlot so that it knows how to find the interpreter stack and look up slots in it, since the default implementation isn't compatible with the way we store the interpreter SP.

I've verified that when a GC happens inside TestFields, the object reference(s) on the interpreter stack are reported to the GC, and the GC is able to successfully move them and update the stack.

I had to modify the way we do INITLOCALS to ensure that any global vars containing pointers are zeroed at method entry, because we don't have accurate liveness information for them to report, otherwise the GC might see garbage data where it expects a managed pointer.

This PR also adds some basic test coverage for structs containing object references.

Copy link
Contributor

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

@kg kg force-pushed the interp-gcinfo-3 branch from c216bab to 74bb2b3 Compare April 18, 2025 18:08
@kg
Copy link
Member Author

kg commented Apr 18, 2025

Rebased and updated to report byrefs. Tweaked the test to explicitly use a ref local.

@kg kg force-pushed the interp-gcinfo-3 branch from 1bac9a0 to ae624f3 Compare April 21, 2025 19:15
@kg
Copy link
Member Author

kg commented Apr 21, 2025

Initial pass at handling structs containing refs. Will need to refactor it to not rely on lambdas.

eeinterp.cpp)
eeinterp.cpp
stackmap.cpp
../../native/containers/dn-simdhash.c
Copy link
Member

Choose a reason for hiding this comment

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

As discussed in offline conversation, it would be better to start reusing code from the regular JIT. There appears to be a quite a bit of code that can be shared between regular JIT and the interpreter JIT.

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 create a 'jitshared' and move JitHashTable into it and use that, then.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moving JitHashTable is looking very time intensive, could I do it in a follow-up PR?

@kg
Copy link
Member Author

kg commented May 2, 2025 via email

@kg kg force-pushed the interp-gcinfo-3 branch 2 times, most recently from 68b0a27 to 4f56fef Compare May 2, 2025 18:32
kg added 6 commits May 5, 2025 20:14
…ss ranges

Use ConvertOffset and live range helpers to record actual byte offsets

Fix globals not being reported

Specialize GetStackSlot for the interpreter because we stash the actual stack location in the frame register

Doing aggressive blocking GC produces earlier, more consistent failures

Calculate stack slot addresses correctly, at least on x64

Disable problematic GC in the test for now

Better debug spew and adjust test

Fix nativeAOT build on CI

Implement additional architectures in GetStackSlot based on CONTEXTGetFp

Maybe fix CI build by using TARGET instead of HOST

Updated guesses at fp register / more architectures

Report and explicitly test byrefs

Refactoring

Maintain separate slot tables for byref and non-byref locals

Handle allocation failure in simdhash

Checkpoint support for byref and ref fields inside VT interpreter locals

Add test coverage for structs containing refs

Match getClassGClayout's size calculation

Remove use of lambdas

Fix release build

Fix linux build

Fix linux build more

Use GetFP to get the frame pointer in interpreter's GcInfoDecoder

Formatting cleanup

Patch initlocals once we have allocated offsets so that we zero our vars in addition to IL vars (GC safety)

Preserve effect of not initializing IL locals even when we expand the initlocals

Introduce globalVarsStackTop, the high water mark for global vars that might contain refs or interior pointers
Use globalVarsStackTop to reduce how much stack we zero on method entry

Formatting cleanups

Repair damage to simdhash files
@kg kg force-pushed the interp-gcinfo-3 branch from 2755150 to feda13a Compare May 6, 2025 03:15
{
int32_t endOfVar = pVar->offset + pVar->size;
if (endOfVar > globalVarsStackTop)
globalVarsStackTop = endOfVar;
Copy link
Member

Choose a reason for hiding this comment

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

This name is a bit misleading, since it is the top of the global vars that might contain refs, and not the end of all global vars. Maybe a more explicit name, like globalVarsWithRefsStackTop or some other name that you think is good.

pVar->global && (
(pVar->interpType == InterpTypeO) ||
(pVar->interpType == InterpTypeByRef) ||
(pVar->interpType == InterpTypeVT)
Copy link
Member

Choose a reason for hiding this comment

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

If you want you could improve the check here for valuetypes with m_compHnd->getClassAttribs(pVar->clsHnd) & CORINFO_FLG_CONTAINS_GC_PTR

{
// We may have global vars containing managed pointers or interior pointers, so we need
// to zero the region of the stack containing global vars, not just IL locals.
// data[0] is either the start of IL locals or the end of IL locals depending on whether local
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 is outdated now

@BrzVlad
Copy link
Member

BrzVlad commented May 6, 2025

@kg Note that after #115198 and this PR I think we should be able to enable the TestSpecialFields test. Also any reason why this pr doesn't enable also TestVirtual ?

@kg
Copy link
Member Author

kg commented May 6, 2025

@kg Note that after #115198 and this PR I think we should be able to enable the TestSpecialFields test. Also any reason why this pr doesn't enable also TestVirtual ?

TestVirtual was added after I created it. I can enable both TestSpecialFields and TestVirtual and make sure they pass.

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.

6 participants