Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Fix callKillSet for CORINFO_HELP_ASSIGN_BYREF on x64. #19780

Merged
merged 2 commits into from
Aug 31, 2018

Conversation

sandreenko
Copy link

@sandreenko sandreenko commented Aug 31, 2018

Our emitter doesn't check liveness information consistency, so when we generate a LIR node that expands to a several machine instructions there is no way to check that nobody corrupts the data.

In this case STORE_OBJ generated

IN0006:        mov      rdi, r15
IN0007:        mov      rsi, r12
							Byref regs: 00009000 {r12 r15} => 00009040 {rsi r12 r15}
							Byref regs: 00009040 {rsi r12 r15} => 000090C0 {rsi rdi r12 r15}
							Call: GCvars=0000000000000000 {}, gcrefRegs=00000000 {}, byrefRegs=00009000 {r12 r15}
IN0008:        call     CORINFO_HELP_ASSIGN_BYREF
IN0009:        mov      ecx, 7
IN000a:        rep movsq 

where byrefRegs after call did not include rsi, rdi, because we trashed RBM_CALLEE_TRASH_NOGC that on Linux x64 incudes rsi, rdi.

coreclr/src/jit/emitxarch.cpp

Lines 6880 to 6884 in 1c47703

/* Trim out any callee-trashed registers from the live set */
gcrefRegs &= savedSet;
byrefRegs &= savedSet;

Fixes #19361.

@sandreenko
Copy link
Author

PTAL @dotnet/jit-contrib

I am trying to modify the repro from @jkotas to expose this issue in ci, if I success I will add it later.

Copy link

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

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

LGTM except comment suggestions

// This helper only trashes ECX.
return RBM_ECX;
#elif defined(_TARGET_AMD64_)
// This uses and defs rdi and rci.

Choose a reason for hiding this comment

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

Typo: rci -> rsi
Also, you may want to just be quite explicit that "This uses and defines rdi and rsi, so they remain as live GC refs or byrefs, and are not killed." or something like that.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you, fixed.

// the CORINFO_HELP_ASSIGN_BYREF helper (i.e. JIT_ByRefWriteBarrier).
// The precise set is defined by RBM_CALLEE_TRASH.
// the CORINFO_HELP_ASSIGN_BYREF helper (i.e. JIT_ByRefWriteBarrier)
// except RDI and RCI that are incoming and outgoing registers.

Choose a reason for hiding this comment

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

Same typo (RCI -> RSI)

@sandreenko
Copy link
Author

Hm, win_x64 corefx test failed, lets try to rerun. Doesn't look like infra.
@dotnet-bot test
Windows_NT x64 Checked CoreFX Tests

@AndyAyersMS
Copy link
Member

Any idea why gc stress didn't catch this?

@sandreenko
Copy link
Author

Have not succeed in adding a repro. I will merge the fix only for now.

Any idea why gc stress didn't catch this?

The issue only marks struct fields as dead and we usually have other parts of the class alive (like this or temp variables that saves &field etc.). So I think it is pretty rare case when the gc can collect the whole class right after the large struct assignment.

Thank for your help with repro.

@sandreenko sandreenko merged commit d71ed81 into dotnet:master Aug 31, 2018
sandreenko pushed a commit to sandreenko/coreclr that referenced this pull request Aug 31, 2018
* Fix callKillSet for CORINFO_HELP_ASSIGN_BYREF.

on x64.

* Fix typos.
sandreenko pushed a commit that referenced this pull request Sep 11, 2018
* Fix callKillSet for CORINFO_HELP_ASSIGN_BYREF.

on x64.
@sandreenko sandreenko deleted the GitHub_19361 branch October 30, 2018 23:47
sandreenko pushed a commit to sandreenko/coreclr that referenced this pull request Nov 6, 2018
…otnet#19803)

* Fix callKillSet for CORINFO_HELP_ASSIGN_BYREF.

on x64.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants