-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
JIT: CSE of an address computation can result in a write barrier change #97534
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsIf we CSE an address computation for a GC store, then Seems like we could find a way not to lose track of this, info for example marking the store as For example:
We may also want to propagate this info during assertion prop or similar so if there is a manual CSE we still are able to see through it.
|
When varying CSEs we can sometimes alter the write barrier that is needed. In particular if we CSE a heap address computation we may lose track of the fact that an indir is writing to the heap, and so change which write barrier needs to be used. See dotnet#97534. Even if that's fixed it seems like we still might change our minds for various reasons, so when running under SPMI, just collect all the possible write barrier helper addresses.
When varying CSEs we can sometimes alter the write barrier that is needed. In particular if we CSE a heap address computation we may lose track of the fact that an indir is writing to the heap, and so change which write barrier needs to be used. See #97534. Even if that's fixed it seems like we still might change our minds for various reasons, so when running under SPMI, just collect all the possible write barrier helper addresses.
Minimal repro: void Test(ref string s1, ref string s2)
{
s1 = "Hello";
s2 = "Hello";
} Codegen: ; Method Program:Test(byref,byref):this (FullOpts)
push rsi
push rbx
mov rcx, rdx
mov rbx, r8
mov rsi, 0x22080106290
mov rdx, rsi
call CORINFO_HELP_CHECKED_ASSIGN_REF
mov rcx, rbx
mov rdx, rsi
call CORINFO_HELP_CHECKED_ASSIGN_REF
nop
pop rbx
pop rsi
ret
; Total bytes of code: 41 Now similar code but different string literals: void Test(ref string s1, ref string s2)
{
s1 = "Hello";
s2 = "World";
} Codegen: ; Method Program:Test(byref,byref):this (FullOpts)
mov rax, 0x24F00106290
mov gword ptr [rdx], rax
mov rax, 0x24F001062B0
mov gword ptr [r8], rax
ret
; Total bytes of code: 27 (frozen objects need no write barrier, but CSE might mess it up) |
@EgorBo that's actually a slightly different (but related) problem. Write barrier form depends both on what is being written (your example) and where it is being written to (my example). CSE can mess with either or both. Interestingly somebody (haven't looked at blame yet to see who) added code to use VN to examine what is being written. Seems a bit iffy to look at VNs so late, but if it is viable, one could imagine doing something comparable for where it's being written (I suspect addr mode formation will get in the way, and we'll have to walk the IR like we do now, and fall down if we hit a cse). I'd rather start depending on the |
It wasn't me, but I filed #97943 to remove it 🙂 |
If we CSE an address computation for a GC store, then
gcIsWriteBarrierCandidate
may no longer be able to tell that the address being stored to is a heap address, and so will switch to using a checked write barrier.Seems like we could find a way not to lose track of this, info for example marking the store as
GTF_IND_TGT_HEAP
(orGTF_IND_TGT_NOT_HEAP
) if we do a CSE.For example:
We may also want to propagate this info during assertion prop or similar so if there is a manual CSE we still are able to see through it.
The text was updated successfully, but these errors were encountered: