-
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
Allow async interruptions on safepoints #95565
Changes from all commits
800db91
72b015f
b2cf275
8cf3e0c
76b4053
fbaf77e
0a13211
30a8524
df581c6
d08552b
45f74af
f656ba4
5487818
604f864
ee6129c
ee75d35
bb98cd9
a8d9b43
5a332b0
3f6c088
4d1895d
93eede9
8fa6a6f
5ac10c5
43fb760
b17b42e
855dd1f
8fb65ba
cb84de7
d1cb779
7ad04bc
3702386
7b6506d
a816dc0
ef9bd7d
d6b2b9f
06d681e
52e2fd6
0a938e0
dc12379
c8f1ba1
e99529c
53c99d3
40e4526
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -922,7 +922,11 @@ void GcInfoEncoder::FinalizeSlotIds() | |
#endif | ||
} | ||
|
||
bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) | ||
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED | ||
|
||
// tells whether a slot cannot contain an object reference | ||
// at call instruction or right after returning | ||
bool GcInfoEncoder::DoNotTrackInPartiallyInterruptible(GcSlotDesc &slotDesc) | ||
{ | ||
#if defined(TARGET_ARM) | ||
|
||
|
@@ -933,7 +937,31 @@ bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) | |
_ASSERTE(regNum >= 0 && regNum <= 14); | ||
_ASSERTE(regNum != 13); // sp | ||
|
||
return ((regNum <= 3) || (regNum >= 12)); // R12 and R14/LR are both scratch registers | ||
return ((regNum <= 3) || (regNum >= 12)) // R12 is volatile and SP/LR can't contain objects around calls | ||
&& regNum != 0 // R0 can contain return value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that R1 can contain a part of 64bit return value as well, however R1 never returns an object/byref |
||
; | ||
} | ||
else if (!slotDesc.IsUntracked() && (slotDesc.Slot.Stack.Base == GC_SP_REL) && | ||
((UINT32)slotDesc.Slot.Stack.SpOffset < m_SizeOfStackOutgoingAndScratchArea)) | ||
{ | ||
return TRUE; | ||
} | ||
else | ||
return FALSE; | ||
|
||
#elif defined(TARGET_ARM64) | ||
|
||
_ASSERTE(m_SizeOfStackOutgoingAndScratchArea != (UINT32)-1); | ||
if (slotDesc.IsRegister()) | ||
{ | ||
int regNum = (int)slotDesc.Slot.RegisterNumber; | ||
_ASSERTE(regNum >= 0 && regNum <= 30); | ||
_ASSERTE(regNum != 18); | ||
|
||
return (regNum <= 17 || regNum >= 29) // X0 through X17 are scratch, FP/LR can't be used for objects around calls | ||
&& regNum != 0 // X0 can contain return value | ||
&& regNum != 1 // X1 can contain return value | ||
; | ||
} | ||
else if (!slotDesc.IsUntracked() && (slotDesc.Slot.Stack.Base == GC_SP_REL) && | ||
((UINT32)slotDesc.Slot.Stack.SpOffset < m_SizeOfStackOutgoingAndScratchArea)) | ||
|
@@ -953,7 +981,7 @@ bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) | |
_ASSERTE(regNum != 4); // rsp | ||
|
||
UINT16 PreservedRegMask = | ||
(1 << 3) // rbx | ||
(1 << 3) // rbx | ||
| (1 << 5) // rbp | ||
#ifndef UNIX_AMD64_ABI | ||
| (1 << 6) // rsi | ||
|
@@ -962,7 +990,12 @@ bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) | |
| (1 << 12) // r12 | ||
| (1 << 13) // r13 | ||
| (1 << 14) // r14 | ||
| (1 << 15); // r15 | ||
| (1 << 15) // r15 | ||
| (1 << 0) // rax - may contain return value | ||
#ifdef UNIX_AMD64_ABI | ||
| (1 << 2) // rdx - may contain return value | ||
#endif | ||
; | ||
|
||
return !(PreservedRegMask & (1 << regNum)); | ||
} | ||
|
@@ -978,6 +1011,7 @@ bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) | |
return FALSE; | ||
#endif | ||
} | ||
#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED | ||
|
||
void GcInfoEncoder::Build() | ||
{ | ||
|
@@ -1396,7 +1430,7 @@ void GcInfoEncoder::Build() | |
else | ||
{ | ||
UINT32 slotIndex = pCurrent->SlotId; | ||
if(!IsAlwaysScratch(m_SlotTable[slotIndex])) | ||
if(!DoNotTrackInPartiallyInterruptible(m_SlotTable[slotIndex])) | ||
{ | ||
BYTE becomesLive = pCurrent->BecomesLive; | ||
_ASSERTE((liveState.ReadBit(slotIndex) && !becomesLive) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ | |
// R2R Version 9.1 adds new helpers to allocate objects on frozen segments | ||
// R2R Version 9.2 adds MemZero and NativeMemSet helpers | ||
// R2R Version 9.3 adds BulkWriteBarrier helper | ||
|
||
// uses GCInfo v3, which makes safe points in partially interruptible code interruptible. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MemZero stuff has made it first to revving the minor version to 9.2. |
||
|
||
struct READYTORUN_CORE_HEADER | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ARM/ARM64 has more changes than x64 here because some of this is just to get the filtering to the same level as on x64. (looks like we had some NYIs for ARM)
Otherwise, it would be just removing X0/X1 from being filtered out unconditionally.