-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks #14982
[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks #14982
Conversation
src/gc/gcinterface.ee.h
Outdated
// | ||
// This function is a no-op if "object" is not an OverlappedData object. | ||
virtual | ||
void WalkOverlappedObjectForPromotion(Object* object, ScanContext* sc, promote_func* callback) = 0; |
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.
I would call it AsyncPinned
. AsyncPinned better describes the primitive, and it is what we call it on other places in the gcee interface (e.g. there is RelocateAsyncPinnedHandles method).
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.
will do!
src/gc/objecthandle.cpp
Outdated
{ | ||
OverlappedDataObject::MarkCleanupNeededFromGC(); | ||
} | ||
GCToEEInterface::WalkOverlappedObjectForPromotion(pPinnedObj, (ScanContext *)lp1, callback); |
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.
Is this going to be called even for regular pinned handles? It would be pretty unfortunate to call this for regular pinned handles. We should split this logic so that it is only called for the async pinned handles.
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.
looks like it will. will do.
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.
This looks potentially difficult. In this point of the code we are looking at an object reference only and have no idea what kind of handle it came from, so we don't know if it's an async pin handle. It seems the only surefire way to know if we are going to need to do additional work on a given object is to inspect its method table.
@@ -626,34 +622,31 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value) | |||
FireEtwSetGCHandle((void*) handle, value, hndType, generation, (int64_t) pAppDomain, GetClrInstanceId()); | |||
FireEtwPrvSetGCHandle((void*) handle, value, hndType, generation, (int64_t) pAppDomain, GetClrInstanceId()); | |||
|
|||
#ifndef FEATURE_REDHAWK |
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.
You can delete other FEATURE_REDHAWK
ifdefs around the overlapped stuff.
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.
ok!
src/gc/handletablecore.cpp
Outdated
|
||
overlapped->m_pinSelf = HndCreateHandle((HHANDLETABLE)pTargetTable, HNDTYPE_ASYNCPINNED, ObjectToOBJECTREF(value)); | ||
if (!overlapped->m_pinSelf) | ||
GCToEEInterface::OverlappedClearIfComplete((Object*)value); |
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.
Would it make more sense to have a callback passed into GCHandleStore::RelocateAsyncPinnedHandles
instead of the OverlappedClearIfComplete
+ OverlappedSetPinnedHandle
methods?
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.
That would certainly be more elegant - I'll look into that.
Marking as no-merge for now since the CI is busted. |
I agree with Jan's comments. |
1. Rename OverlappedData->AsyncPinned in interface methods 2. Remove additional FEATURE_REDHAWK defines around async pin relocation code
@@ -320,6 +320,11 @@ inline void* ALIGN_DOWN(void* ptr, size_t alignment) | |||
return reinterpret_cast<void*>(ALIGN_DOWN(as_size_t, alignment)); | |||
} | |||
|
|||
inline int GetRandomInt(int max) |
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.
Why not call rand()
directly? This is used just in one place, in debug-only code.
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.
I heeded this warning that I got when I tried to do that:
e:\github\coreclr\src\gc\handletablecore.cpp(1054): error C3861: 'Do_not_use_rand': identifier not found [E:\GitHub\co reclr\bin\obj\Windows_NT.x64.Debug\src\vm\wks\cee_wks.vcxproj]
I can always undef rand
but it seemed to go against the spirit of the warning 😄 .
…ctly as arguments to a method on IGCHandleStore
The most recent commit eliminates I am still unsure how to avoid the indirection in |
It would need to handled in |
@jkotas Done in the latest commit - thanks! It doesn't look like the coreclr test suite tests this area very much so I'm doing some additional manual testing now on the parts that I can test. |
@@ -0,0 +1,5 @@ | |||
{ | |||
"version": 1, |
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.
I do not think you meant to add all these files.
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.
oh goodness... i certainly did not. I'll fix up the last commit.
5adfff6
to
af847d2
Compare
@dotnet-bot test this please |
I think I've addressed all feedback in this PR and this code has passed all functional testing I've done locally. I think it's ready to merge unless there are any objections. CentOS failure looks unrelated:
|
thanks! |
… through four callbacks (dotnet#14982)" This reverts commit c755e3b.
Revert "[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks (#14982)"
…to the EE through four callbacks (#14982)""
Revert " Revert "[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks (#14982)""
Reverting the change to Enumerator Current for now Fix file formatting Enable Alpine CI (dotnet#15502) * Enable Alpine CI This enables Alpine CI leg on every PR using the pipelines. compare type size instead of var_types get rid of TYP_CHAR Adding support for Acosh, Asinh, Atanh, and Cbrt to Math and MathF Updating the PAL layer to support acosh, asinh, atanh, and cbrt Adding some PAL tests for acosh, asinh, atanh, and cbrt Adding valuenum support for acosh, asinh, atanh, and cbrt Lsra Documentation Update LinearScan section of ryujit-overview.md, and add lsra-detail.md Refactor Unsafe.cs to get it more in sync with CoreRT. (dotnet#15510) * Refactor Unsafe.cs to get it more in sync with CoreRT. * Format the document. * Unifying the copies of Unsafe using ifdefs * Change exception thrown to PlatformNotSupportedException * Addressing PR feedback and moving Unsafe to shared. * Addressing PR feedback * Addressing PR review - adding intrinsic attribute Update CoreClr, CoreFx to preview1-26014-01, preview1-26013-12, respectively (dotnet#15513) Revert "Add optional integer offset to OwnedMemory Pin (dotnet#15410)" This reverts commit 8931cfa. Get rid of old -altjitcrossgen argument now that CI has been updated Merge pull request dotnet/corert#5109 from dotnet/nmirror (dotnet#15518) Merge nmirror to master Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com> Revert " Revert "[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks (dotnet#14982)"" Fix typo `_TARGET_ARM` to `_TARGET_ARM_`. This happens mostly in comments except lsra.cpp. Update CoreClr, CoreFx, PgoData to preview1-26014-04, preview1-26014-03, master-20171214-0043, respectively (dotnet#15520)
Reverting the change to Enumerator Current for now Fix file formatting Enable Alpine CI (dotnet#15502) * Enable Alpine CI This enables Alpine CI leg on every PR using the pipelines. compare type size instead of var_types get rid of TYP_CHAR Adding support for Acosh, Asinh, Atanh, and Cbrt to Math and MathF Updating the PAL layer to support acosh, asinh, atanh, and cbrt Adding some PAL tests for acosh, asinh, atanh, and cbrt Adding valuenum support for acosh, asinh, atanh, and cbrt Lsra Documentation Update LinearScan section of ryujit-overview.md, and add lsra-detail.md Refactor Unsafe.cs to get it more in sync with CoreRT. (dotnet#15510) * Refactor Unsafe.cs to get it more in sync with CoreRT. * Format the document. * Unifying the copies of Unsafe using ifdefs * Change exception thrown to PlatformNotSupportedException * Addressing PR feedback and moving Unsafe to shared. * Addressing PR feedback * Addressing PR review - adding intrinsic attribute Update CoreClr, CoreFx to preview1-26014-01, preview1-26013-12, respectively (dotnet#15513) Revert "Add optional integer offset to OwnedMemory Pin (dotnet#15410)" This reverts commit 8931cfa. Get rid of old -altjitcrossgen argument now that CI has been updated Merge pull request dotnet/corert#5109 from dotnet/nmirror (dotnet#15518) Merge nmirror to master Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com> Revert " Revert "[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks (dotnet#14982)"" Fix typo `_TARGET_ARM` to `_TARGET_ARM_`. This happens mostly in comments except lsra.cpp. Update CoreClr, CoreFx, PgoData to preview1-26014-04, preview1-26014-03, master-20171214-0043, respectively (dotnet#15520)
* Change ReadOnlySpan indexer to return ref readonly. Update JIT to handle changes to ReadOnlySpan indexer Resolving merge conflict and fixing jit importer Update ReadOnlySpan Enumerator Current to use indexer. Removing readonly keyword. * Temporarily disabling Span perf and other tests that use ReadOnlySpan * Isolating the ref readonly indexer change only to CoreCLR for now. Reverting the change to Enumerator Current for now Fix file formatting Enable Alpine CI (#15502) * Enable Alpine CI This enables Alpine CI leg on every PR using the pipelines. compare type size instead of var_types get rid of TYP_CHAR Adding support for Acosh, Asinh, Atanh, and Cbrt to Math and MathF Updating the PAL layer to support acosh, asinh, atanh, and cbrt Adding some PAL tests for acosh, asinh, atanh, and cbrt Adding valuenum support for acosh, asinh, atanh, and cbrt Lsra Documentation Update LinearScan section of ryujit-overview.md, and add lsra-detail.md Refactor Unsafe.cs to get it more in sync with CoreRT. (#15510) * Refactor Unsafe.cs to get it more in sync with CoreRT. * Format the document. * Unifying the copies of Unsafe using ifdefs * Change exception thrown to PlatformNotSupportedException * Addressing PR feedback and moving Unsafe to shared. * Addressing PR feedback * Addressing PR review - adding intrinsic attribute Update CoreClr, CoreFx to preview1-26014-01, preview1-26013-12, respectively (#15513) Revert "Add optional integer offset to OwnedMemory Pin (#15410)" This reverts commit 8931cfa. Get rid of old -altjitcrossgen argument now that CI has been updated Merge pull request dotnet/corert#5109 from dotnet/nmirror (#15518) Merge nmirror to master Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com> Revert " Revert "[Local GC] Move knowledge of overlapped I/O objects to the EE through four callbacks (#14982)"" Fix typo `_TARGET_ARM` to `_TARGET_ARM_`. This happens mostly in comments except lsra.cpp. Update CoreClr, CoreFx, PgoData to preview1-26014-04, preview1-26014-03, master-20171214-0043, respectively (#15520) * Disabling a test that uses ReadOnlySpan indexer * Temporarily disabling the superpmi test and fixing nit * Remove debug statements.
For better or for worse, both the runtime and the GC have deep knowledge about the runtime data structures behind overlapped I/O. This knowledge is centered around the existence and layout of the
System.Threading.OverlappedData
class. The handle table is aware of this class because the runtime creates "async pinned handles" that refer to them and they are treated specially when marking through the handle table.OverlappedData objects are special in that the objects that they refer to are logically pinned, even though there are no pinning handles in the handle table. This is achieved by treating the
m_userObject
field specially when marking through the heap:m_userObject
is an ordinary object, it is reported to the GC as pinnedm_userObject
is an array, all pointers within the array are reported to the GC as pinned, but not the array itself.OverlappedData objects are special also in that their lifetime is based on an overlapped I/O request and as such the kernel may reappear at any time to signal the completion of the request. If an app domain is unloaded while such an I/O request is still in flight, the handle table must relocate these handles to a new app domain to avoid crashing when the I/O request does return. (Does not apply to CoreCLR, which only has one app domain).
This PR attempts to abstract these details behind four new additions to
IGCToCLR
:WalkOverlappedObject
- Given an object, if that object isSystem.Threading.OverlappedData
, invoke a callback on all objects that would be considered pinned by this object.WalkOverlappedObjectForPromotion
- Similar toWalkOverlappedObject
. Given an object, if that object isSystem.Threading.OverlappedData
, invoke the promotion callback on all objects that would be considered pinned. This is different than the above callback because OverlappedData objects are extremely special and it is not correct to update them_userObject
field when doing a GC; this is taken care of after a GC is completed. The runtime accomplishes this with a second fieldm_userObjectInternal
that records any relocations that may occur on the object being reported. (This can happen because, ifm_userObject
is an array, it is not pinned.)OverlappedClearIfComplete
- Once an Overlapped I/O request completes, the objects to which the OverlappedData object refer to no longer need to be pinned. This callback gives the EE a chance to unpin the data associated with an OverlappedData object if the I/O request has completed.OverlappedSetPinnedHandle
- When relocating an OverlappedData handle from a condemned app domain, the handle table allocates a new async pinned handle belonging to another app domain. This callback informs the EE of the existence of this new handle.This set of callbacks is not pretty but it does cover all of the uses of
OverlappedData
within the GC that I could find. Not all of this code can be fully tested (e.g. app domain loading in CoreCLR) but I am in the process of validating the aspects of this change that I can test. A nice side-effect of this change is that it eliminates a number of places where overlapped data object traversal code was copy-pasted between different areas of the handle table.This PR addresses the main blocker for https://github.com/dotnet/coreclr/issues/14701.
cc @jkotas @sergiy-k @Maoni0 PTAL?