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 14 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.

#if defined(TARGET_AMD64)
pRD->pCurrentContext->Rbp;
#elif defined(TARGET_ARM)
// FIXME: CONTEXTGetFp says R7 but cgencpu.h says R11
Copy link
Member

@filipnavara filipnavara Apr 12, 2025

Choose a reason for hiding this comment

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

R11 is correct. I'll look into the CONTEXTGetFp implementation, it dates back 9 years and it always had the wrong register.

Copy link
Member

Choose a reason for hiding this comment

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

The distinction boils down to the Thumb instruction set where only limited number of registers was accessible and R7 was indeed used as the frame pointer since PUSH instruction could only access R0-R7. I'll need to go recheck my assumptions about what is actually used. We do use Thumb code for both JIT and the native runtime. If clang/gcc use R7 for frame pointer, then CONTEXTGetFp would be correct for native code. JIT does use R11, as described both in clr-abi.md and REG_FPBASE in targetarm.h.

@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.

kg added 9 commits April 25, 2025 17:53
…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
Fix linux build

Fix linux build more
kg added 3 commits April 25, 2025 17:53
…t might contain refs or interior pointers

Use globalVarsStackTop to reduce how much stack we zero on method entry
@kg kg force-pushed the interp-gcinfo-3 branch from 9152269 to 26a4882 Compare April 26, 2025 01:05
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.

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.

5 participants