Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices')
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs17
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs66
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorStateMachineAttribute.cs18
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs21
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs158
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs15
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskCache.cs66
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilder.cs144
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs607
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs175
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs513
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs163
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerArgumentExpressionAttribute.cs17
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs15
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs22
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConditionalWeakTable.cs806
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredAsyncDisposable.cs27
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredCancelableAsyncEnumerable.cs78
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs225
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ContractHelper.cs156
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CustomConstantAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs21
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DecimalConstantAttribute.cs39
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs17
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs19
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs13
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs30
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs58
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs27
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachineBox.cs24
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ICastable.cs61
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs36
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ITuple.cs22
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs18
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsByRefLikeAttribute.cs21
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsConst.cs10
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsReadOnlyAttribute.cs21
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsVolatile.cs11
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs15
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/LoadHint.cs13
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodCodeType.cs16
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplAttribute.cs29
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs22
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/PreserveDependencyAttribute.cs62
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs32
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs30
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs42
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs109
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs41
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs17
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs14
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StrongBox.cs54
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs12
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs556
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs57
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs20
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs17
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs11
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs198
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/YieldAwaitable.cs195
71 files changed, 0 insertions, 5475 deletions
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
deleted file mode 100644
index 25efcafa3fd..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field)]
- public sealed class AccessedThroughPropertyAttribute : Attribute
- {
- public AccessedThroughPropertyAttribute(string propertyName)
- {
- PropertyName = propertyName;
- }
-
- public string PropertyName { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs
deleted file mode 100644
index 4c4e2ebc05a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorMethodBuilder.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Represents a builder for asynchronous iterators.</summary>
- [StructLayout(LayoutKind.Auto)]
- public struct AsyncIteratorMethodBuilder
- {
- // AsyncIteratorMethodBuilder is used by the language compiler as part of generating
- // async iterators. For now, the implementation just wraps AsyncTaskMethodBuilder, as
- // most of the logic is shared. However, in the future this could be changed and
- // optimized. For example, we do need to allocate an object (once) to flow state like
- // ExecutionContext, which AsyncTaskMethodBuilder handles, but it handles it by
- // allocating a Task-derived object. We could optimize this further by removing
- // the Task from the hierarchy, but in doing so we'd also lose a variety of optimizations
- // related to it, so we'd need to replicate all of those optimizations (e.g. storing
- // that box object directly into a Task's continuation field).
-
- private AsyncTaskMethodBuilder _methodBuilder; // mutable struct; do not make it readonly
-
- /// <summary>Creates an instance of the <see cref="AsyncIteratorMethodBuilder"/> struct.</summary>
- /// <returns>The initialized instance.</returns>
- public static AsyncIteratorMethodBuilder Create() =>
- // _methodBuilder should be initialized to AsyncTaskMethodBuilder.Create(), but on coreclr
- // that Create() is a nop, so we can just return the default here.
- default;
-
- /// <summary>Invokes <see cref="IAsyncStateMachine.MoveNext"/> on the state machine while guarding the <see cref="ExecutionContext"/>.</summary>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void MoveNext<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
-
- /// <summary>Marks iteration as being completed, whether successfully or otherwise.</summary>
- public void Complete() => _methodBuilder.SetResult();
-
- /// <summary>Gets an object that may be used to uniquely identify this builder to the debugger.</summary>
- internal object ObjectIdForDebugger => _methodBuilder.ObjectIdForDebugger;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorStateMachineAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorStateMachineAttribute.cs
deleted file mode 100644
index 489195569de..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncIteratorStateMachineAttribute.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Indicates whether a method is an asynchronous iterator.</summary>
- [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public sealed class AsyncIteratorStateMachineAttribute : StateMachineAttribute
- {
- /// <summary>Initializes a new instance of the <see cref="AsyncIteratorStateMachineAttribute"/> class.</summary>
- /// <param name="stateMachineType">The type object for the underlying state machine type that's used to implement a state machine method.</param>
- public AsyncIteratorStateMachineAttribute(Type stateMachineType)
- : base(stateMachineType)
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs
deleted file mode 100644
index 688a3a01ba7..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Indicates the type of the async method builder that should be used by a language compiler to
- /// build the attributed type when used as the return type of an async method.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
- public sealed class AsyncMethodBuilderAttribute : Attribute
- {
- /// <summary>Initializes the <see cref="AsyncMethodBuilderAttribute"/>.</summary>
- /// <param name="builderType">The <see cref="Type"/> of the associated builder.</param>
- public AsyncMethodBuilderAttribute(Type builderType) => BuilderType = builderType;
-
- /// <summary>Gets the <see cref="Type"/> of the associated builder.</summary>
- public Type BuilderType { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs
deleted file mode 100644
index f8aad2f0178..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Diagnostics.Tracing;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Text;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Shared helpers for manipulating state related to async state machines.</summary>
- internal static class AsyncMethodBuilderCore // debugger depends on this exact name
- {
- /// <summary>Initiates the builder's execution with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [DebuggerStepThrough]
- public static void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
- {
- if (stateMachine == null) // TStateMachines are generally non-nullable value types, so this check will be elided
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
- }
-
- // enregistrer variables with 0 post-fix so they can be used in registers without EH forcing them to stack
- // Capture references to Thread Contexts
- Thread currentThread0 = Thread.CurrentThread;
- Thread currentThread = currentThread0;
- ExecutionContext? previousExecutionCtx0 = currentThread0._executionContext;
-
- // Store current ExecutionContext and SynchronizationContext as "previousXxx".
- // This allows us to restore them and undo any Context changes made in stateMachine.MoveNext
- // so that they won't "leak" out of the first await.
- ExecutionContext? previousExecutionCtx = previousExecutionCtx0;
- SynchronizationContext? previousSyncCtx = currentThread0._synchronizationContext;
-
- try
- {
- stateMachine.MoveNext();
- }
- finally
- {
- // Re-enregistrer variables post EH with 1 post-fix so they can be used in registers rather than from stack
- SynchronizationContext? previousSyncCtx1 = previousSyncCtx;
- Thread currentThread1 = currentThread;
- // The common case is that these have not changed, so avoid the cost of a write barrier if not needed.
- if (previousSyncCtx1 != currentThread1._synchronizationContext)
- {
- // Restore changed SynchronizationContext back to previous
- currentThread1._synchronizationContext = previousSyncCtx1;
- }
-
- ExecutionContext? previousExecutionCtx1 = previousExecutionCtx;
- ExecutionContext? currentExecutionCtx1 = currentThread1._executionContext;
- if (previousExecutionCtx1 != currentExecutionCtx1)
- {
- ExecutionContext.RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1);
- }
- }
- }
-
- public static void SetStateMachine(IAsyncStateMachine stateMachine, Task? task)
- {
- if (stateMachine == null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
- }
-
- if (task != null)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.AsyncMethodBuilder_InstanceNotInitialized);
- }
-
- // SetStateMachine was originally needed in order to store the boxed state machine reference into
- // the boxed copy. Now that a normal box is no longer used, SetStateMachine is also legacy. We need not
- // do anything here, and thus assert to ensure we're not calling this from our own implementations.
- Debug.Fail("SetStateMachine should not be used.");
- }
-
-#if !CORERT
- /// <summary>Gets whether we should be tracking async method completions for eventing.</summary>
- internal static bool TrackAsyncMethodCompletion
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => TplEventSource.Log.IsEnabled(EventLevel.Warning, TplEventSource.Keywords.AsyncMethod);
- }
-#endif
-
- /// <summary>Gets a description of the state of the state machine object, suitable for debug purposes.</summary>
- /// <param name="stateMachine">The state machine object.</param>
- /// <returns>A description of the state machine.</returns>
- internal static string GetAsyncStateMachineDescription(IAsyncStateMachine stateMachine)
- {
- Debug.Assert(stateMachine != null);
-
- Type stateMachineType = stateMachine.GetType();
- FieldInfo[] fields = stateMachineType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
- var sb = new StringBuilder();
- sb.AppendLine(stateMachineType.FullName);
- foreach (FieldInfo fi in fields)
- {
- sb.Append(" ").Append(fi.Name).Append(": ").Append(fi.GetValue(stateMachine)).AppendLine();
- }
- return sb.ToString();
- }
-
- internal static Action CreateContinuationWrapper(Action continuation, Action<Action, Task> invokeAction, Task innerTask) =>
- new ContinuationWrapper(continuation, invokeAction, innerTask).Invoke;
-
- /// <summary>This helper routine is targeted by the debugger. Its purpose is to remove any delegate wrappers introduced by
- /// the framework that the debugger doesn't want to see.</summary>
- internal static Action TryGetStateMachineForDebugger(Action action) // debugger depends on this exact name/signature
- {
- object? target = action.Target;
- return
- target is IAsyncStateMachineBox sm ? sm.GetStateMachineObject().MoveNext :
- target is ContinuationWrapper cw ? TryGetStateMachineForDebugger(cw._continuation) :
- action;
- }
-
- internal static Task? TryGetContinuationTask(Action continuation) =>
- (continuation.Target is ContinuationWrapper wrapper) ?
- wrapper._innerTask : // A wrapped continuation, created by an awaiter
- continuation.Target as Task; // The continuation targets a task directly, such as with AsyncStateMachineBox
-
- /// <summary>
- /// Logically we pass just an Action (delegate) to a task for its action to 'ContinueWith' when it completes.
- /// However debuggers and profilers need more information about what that action is. (In particular what
- /// the action after that is and after that. To solve this problem we create a 'ContinuationWrapper
- /// which when invoked just does the original action (the invoke action), but also remembers other information
- /// (like the action after that (which is also a ContinuationWrapper and thus form a linked list).
- /// We also store that task if the action is associate with at task.
- /// </summary>
- private sealed class ContinuationWrapper // SOS DumpAsync command depends on this name
- {
- private readonly Action<Action, Task> _invokeAction; // This wrapper is an action that wraps another action, this is that Action.
- internal readonly Action _continuation; // This is continuation which will happen after m_invokeAction (and is probably a ContinuationWrapper). SOS DumpAsync command depends on this name.
- internal readonly Task _innerTask; // If the continuation is logically going to invoke a task, this is that task (may be null)
-
- internal ContinuationWrapper(Action continuation, Action<Action, Task> invokeAction, Task innerTask)
- {
- Debug.Assert(continuation != null, "Expected non-null continuation");
- Debug.Assert(invokeAction != null, "Expected non-null invokeAction");
- Debug.Assert(innerTask != null, "Expected non-null innerTask");
-
- _invokeAction = invokeAction;
- _continuation = continuation;
- _innerTask = innerTask;
- }
-
- internal void Invoke() => _invokeAction(_continuation, _innerTask);
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
deleted file mode 100644
index 66c9175ee75..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public sealed class AsyncStateMachineAttribute : StateMachineAttribute
- {
- public AsyncStateMachineAttribute(Type stateMachineType)
- : base(stateMachineType)
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskCache.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskCache.cs
deleted file mode 100644
index 3f164a02c43..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskCache.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Threading.Tasks;
-using System.Diagnostics.CodeAnalysis;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides a cache of closed generic tasks for async methods.</summary>
- internal static class AsyncTaskCache
- {
- /// <summary>A cached Task{Boolean}.Result == true.</summary>
- internal static readonly Task<bool> s_trueTask = CreateCacheableTask(result: true);
- /// <summary>A cached Task{Boolean}.Result == false.</summary>
- internal static readonly Task<bool> s_falseTask = CreateCacheableTask(result: false);
- /// <summary>The cache of Task{Int32}.</summary>
- internal static readonly Task<int>[] s_int32Tasks = CreateInt32Tasks();
- /// <summary>The minimum value, inclusive, for which we want a cached task.</summary>
- internal const int InclusiveInt32Min = -1;
- /// <summary>The maximum value, exclusive, for which we want a cached task.</summary>
- internal const int ExclusiveInt32Max = 9;
-
- /// <summary>true if we should use reusable boxes for async completions of ValueTask methods; false if we should use tasks.</summary>
- /// <remarks>
- /// We rely on tiered compilation turning this into a const and doing dead code elimination to make checks on this efficient.
- /// It's also required for safety that this value never changes once observed, as Unsafe.As casts are employed based on its value.
- /// </remarks>
- internal static readonly bool s_valueTaskPoolingEnabled = GetPoolAsyncValueTasksSwitch();
- /// <summary>Maximum number of boxes that are allowed to be cached per state machine type.</summary>
- internal static readonly int s_valueTaskPoolingCacheSize = GetPoolAsyncValueTasksLimitValue();
-
- private static bool GetPoolAsyncValueTasksSwitch()
- {
- string? value = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_THREADING_POOLASYNCVALUETASKS");
- return value != null && (bool.IsTrueStringIgnoreCase(value) || value.Equals("1"));
- }
-
- private static int GetPoolAsyncValueTasksLimitValue() =>
- int.TryParse(Environment.GetEnvironmentVariable("DOTNET_SYSTEM_THREADING_POOLASYNCVALUETASKSLIMIT"), out int result) && result > 0 ?
- result :
- Environment.ProcessorCount * 4; // arbitrary default value
-
- /// <summary>Creates a non-disposable task.</summary>
- /// <typeparam name="TResult">Specifies the result type.</typeparam>
- /// <param name="result">The result for the task.</param>
- /// <returns>The cacheable task.</returns>
- internal static Task<TResult> CreateCacheableTask<TResult>([AllowNull] TResult result) =>
- new Task<TResult>(false, result, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default);
-
- /// <summary>Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX).</summary>
- private static Task<int>[] CreateInt32Tasks()
- {
- Debug.Assert(ExclusiveInt32Max >= InclusiveInt32Min, "Expected max to be at least min");
-
- var tasks = new Task<int>[ExclusiveInt32Max - InclusiveInt32Min];
- for (int i = 0; i < tasks.Length; i++)
- {
- tasks[i] = CreateCacheableTask(i + InclusiveInt32Min);
- }
-
- return tasks;
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilder.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilder.cs
deleted file mode 100644
index a3e7e5fe068..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilder.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Provides a builder for asynchronous methods that return <see cref="System.Threading.Tasks.Task"/>.
- /// This type is intended for compiler use only.
- /// </summary>
- /// <remarks>
- /// AsyncTaskMethodBuilder is a value type, and thus it is copied by value.
- /// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
- /// or else the copies may end up building distinct Task instances.
- /// </remarks>
- public struct AsyncTaskMethodBuilder
- {
- /// <summary>The lazily-initialized built task.</summary>
- private Task<VoidTaskResult>? m_task; // Debugger depends on the exact name of this field.
-
- /// <summary>Initializes a new <see cref="AsyncTaskMethodBuilder"/>.</summary>
- /// <returns>The initialized <see cref="AsyncTaskMethodBuilder"/>.</returns>
- public static AsyncTaskMethodBuilder Create() => default;
-
- /// <summary>Initiates the builder's execution with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [DebuggerStepThrough]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Associates the builder with the state machine it represents.</summary>
- /// <param name="stateMachine">The heap-allocated state machine object.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
- public void SetStateMachine(IAsyncStateMachine stateMachine) =>
- AsyncMethodBuilderCore.SetStateMachine(stateMachine, task: null);
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- AsyncTaskMethodBuilder<VoidTaskResult>.AwaitOnCompleted(ref awaiter, ref stateMachine, ref m_task);
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- AsyncTaskMethodBuilder<VoidTaskResult>.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref m_task);
-
- /// <summary>Gets the <see cref="System.Threading.Tasks.Task"/> for this builder.</summary>
- /// <returns>The <see cref="System.Threading.Tasks.Task"/> representing the builder's asynchronous operation.</returns>
- /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
- public Task Task
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => m_task ?? InitializeTaskAsPromise();
- }
-
- /// <summary>
- /// Initializes the task, which must not yet be initialized. Used only when the Task is being forced into
- /// existence when no state machine is needed, e.g. when the builder is being synchronously completed with
- /// an exception, when the builder is being used out of the context of an async method, etc.
- /// </summary>
- [MethodImpl(MethodImplOptions.NoInlining)]
- private Task<VoidTaskResult> InitializeTaskAsPromise()
- {
- Debug.Assert(m_task == null);
- return m_task = new Task<VoidTaskResult>();
- }
-
- /// <summary>
- /// Completes the <see cref="System.Threading.Tasks.Task"/> in the
- /// <see cref="System.Threading.Tasks.TaskStatus">RanToCompletion</see> state.
- /// </summary>
- /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
- /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
- public void SetResult()
- {
- // Get the currently stored task, which will be non-null if get_Task has already been accessed.
- // If there isn't one, store the supplied completed task.
- if (m_task is null)
- {
- m_task = Task.s_cachedCompleted;
- }
- else
- {
- // Otherwise, complete the task that's there.
- AsyncTaskMethodBuilder<VoidTaskResult>.SetExistingTaskResult(m_task, default!);
- }
- }
-
- /// <summary>
- /// Completes the <see cref="System.Threading.Tasks.Task"/> in the
- /// <see cref="System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
- /// </summary>
- /// <param name="exception">The <see cref="System.Exception"/> to use to fault the task.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
- /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
- public void SetException(Exception exception) =>
- AsyncTaskMethodBuilder<VoidTaskResult>.SetException(exception, ref m_task);
-
- /// <summary>
- /// Called by the debugger to request notification when the first wait operation
- /// (await, Wait, Result, etc.) on this builder's task completes.
- /// </summary>
- /// <param name="enabled">
- /// true to enable notification; false to disable a previously set notification.
- /// </param>
- internal void SetNotificationForWaitCompletion(bool enabled) =>
- AsyncTaskMethodBuilder<VoidTaskResult>.SetNotificationForWaitCompletion(enabled, ref m_task);
-
- /// <summary>
- /// Gets an object that may be used to uniquely identify this builder to the debugger.
- /// </summary>
- /// <remarks>
- /// This property lazily instantiates the ID in a non-thread-safe manner.
- /// It must only be used by the debugger and tracing purposes, and only in a single-threaded manner
- /// when no other threads are in the middle of accessing this property or this.Task.
- /// </remarks>
- internal object ObjectIdForDebugger =>
- m_task ??= AsyncTaskMethodBuilder<VoidTaskResult>.CreateWeaklyTypedStateMachineBox();
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs
deleted file mode 100644
index 043a133ab13..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs
+++ /dev/null
@@ -1,607 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Threading;
-using System.Threading.Tasks;
-using Internal.Runtime.CompilerServices;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Provides a builder for asynchronous methods that return <see cref="System.Threading.Tasks.Task{TResult}"/>.
- /// This type is intended for compiler use only.
- /// </summary>
- /// <remarks>
- /// AsyncTaskMethodBuilder{TResult} is a value type, and thus it is copied by value.
- /// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
- /// or else the copies may end up building distinct Task instances.
- /// </remarks>
- public struct AsyncTaskMethodBuilder<TResult>
- {
- /// <summary>A cached task for default(TResult).</summary>
- internal static readonly Task<TResult> s_defaultResultTask = AsyncTaskCache.CreateCacheableTask<TResult>(default);
-
- /// <summary>The lazily-initialized built task.</summary>
- private Task<TResult>? m_task; // Debugger depends on the exact name of this field.
-
- /// <summary>Initializes a new <see cref="AsyncTaskMethodBuilder"/>.</summary>
- /// <returns>The initialized <see cref="AsyncTaskMethodBuilder"/>.</returns>
- public static AsyncTaskMethodBuilder<TResult> Create() => default;
-
- /// <summary>Initiates the builder's execution with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [DebuggerStepThrough]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Associates the builder with the state machine it represents.</summary>
- /// <param name="stateMachine">The heap-allocated state machine object.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
- public void SetStateMachine(IAsyncStateMachine stateMachine) =>
- AsyncMethodBuilderCore.SetStateMachine(stateMachine, m_task);
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- AwaitOnCompleted(ref awaiter, ref stateMachine, ref m_task);
-
- internal static void AwaitOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref Task<TResult>? taskField)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- try
- {
- awaiter.OnCompleted(GetStateMachineBox(ref stateMachine, ref taskField).MoveNextAction);
- }
- catch (Exception e)
- {
- System.Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
- }
- }
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref m_task);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref Task<TResult>? taskField)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- IAsyncStateMachineBox box = GetStateMachineBox(ref stateMachine, ref taskField);
- AwaitUnsafeOnCompleted(ref awaiter, box);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveOptimization)] // workaround boxing allocations in Tier0: https://github.com/dotnet/coreclr/issues/14474
- internal static void AwaitUnsafeOnCompleted<TAwaiter>(
- ref TAwaiter awaiter, IAsyncStateMachineBox box)
- where TAwaiter : ICriticalNotifyCompletion
- {
- // The null tests here ensure that the jit can optimize away the interface
- // tests when TAwaiter is a ref type.
-
- if ((null != (object)default(TAwaiter)!) && (awaiter is ITaskAwaiter)) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- ref TaskAwaiter ta = ref Unsafe.As<TAwaiter, TaskAwaiter>(ref awaiter); // relies on TaskAwaiter/TaskAwaiter<T> having the same layout
- TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, continueOnCapturedContext: true);
- }
- else if ((null != (object)default(TAwaiter)!) && (awaiter is IConfiguredTaskAwaiter)) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- ref ConfiguredTaskAwaitable.ConfiguredTaskAwaiter ta = ref Unsafe.As<TAwaiter, ConfiguredTaskAwaitable.ConfiguredTaskAwaiter>(ref awaiter);
- TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, ta.m_continueOnCapturedContext);
- }
- else if ((null != (object)default(TAwaiter)!) && (awaiter is IStateMachineBoxAwareAwaiter)) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- try
- {
- ((IStateMachineBoxAwareAwaiter)awaiter).AwaitUnsafeOnCompleted(box);
- }
- catch (Exception e)
- {
- // Whereas with Task the code that hooks up and invokes the continuation is all local to corelib,
- // with ValueTaskAwaiter we may be calling out to an arbitrary implementation of IValueTaskSource
- // wrapped in the ValueTask, and as such we protect against errant exceptions that may emerge.
- // We don't want such exceptions propagating back into the async method, which can't handle
- // exceptions well at that location in the state machine, especially if the exception may occur
- // after the ValueTaskAwaiter already successfully hooked up the callback, in which case it's possible
- // two different flows of execution could end up happening in the same async method call.
- System.Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
- }
- }
- else
- {
- // The awaiter isn't specially known. Fall back to doing a normal await.
- try
- {
- awaiter.UnsafeOnCompleted(box.MoveNextAction);
- }
- catch (Exception e)
- {
- System.Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
- }
- }
- }
-
- /// <summary>Gets the "boxed" state machine object.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the async state machine.</typeparam>
- /// <param name="stateMachine">The state machine.</param>
- /// <returns>The "boxed" state machine.</returns>
- private static IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(
- ref TStateMachine stateMachine,
- [NotNull] ref Task<TResult>? taskField)
- where TStateMachine : IAsyncStateMachine
- {
- ExecutionContext? currentContext = ExecutionContext.Capture();
-
- // Check first for the most common case: not the first yield in an async method.
- // In this case, the first yield will have already "boxed" the state machine in
- // a strongly-typed manner into an AsyncStateMachineBox. It will already contain
- // the state machine as well as a MoveNextDelegate and a context. The only thing
- // we might need to do is update the context if that's changed since it was stored.
- if (taskField is AsyncStateMachineBox<TStateMachine> stronglyTypedBox)
- {
- if (stronglyTypedBox.Context != currentContext)
- {
- stronglyTypedBox.Context = currentContext;
- }
- return stronglyTypedBox;
- }
-
- // The least common case: we have a weakly-typed boxed. This results if the debugger
- // or some other use of reflection accesses a property like ObjectIdForDebugger or a
- // method like SetNotificationForWaitCompletion prior to the first await happening. In
- // such situations, we need to get an object to represent the builder, but we don't yet
- // know the type of the state machine, and thus can't use TStateMachine. Instead, we
- // use the IAsyncStateMachine interface, which all TStateMachines implement. This will
- // result in a boxing allocation when storing the TStateMachine if it's a struct, but
- // this only happens in active debugging scenarios where such performance impact doesn't
- // matter.
- if (taskField is AsyncStateMachineBox<IAsyncStateMachine> weaklyTypedBox)
- {
- // If this is the first await, we won't yet have a state machine, so store it.
- if (weaklyTypedBox.StateMachine == null)
- {
- Debugger.NotifyOfCrossThreadDependency(); // same explanation as with usage below
- weaklyTypedBox.StateMachine = stateMachine;
- }
-
- // Update the context. This only happens with a debugger, so no need to spend
- // extra IL checking for equality before doing the assignment.
- weaklyTypedBox.Context = currentContext;
- return weaklyTypedBox;
- }
-
- // Alert a listening debugger that we can't make forward progress unless it slips threads.
- // If we don't do this, and a method that uses "await foo;" is invoked through funceval,
- // we could end up hooking up a callback to push forward the async method's state machine,
- // the debugger would then abort the funceval after it takes too long, and then continuing
- // execution could result in another callback being hooked up. At that point we have
- // multiple callbacks registered to push the state machine, which could result in bad behavior.
- Debugger.NotifyOfCrossThreadDependency();
-
- // At this point, taskField should really be null, in which case we want to create the box.
- // However, in a variety of debugger-related (erroneous) situations, it might be non-null,
- // e.g. if the Task property is examined in a Watch window, forcing it to be lazily-intialized
- // as a Task<TResult> rather than as an AsyncStateMachineBox. The worst that happens in such
- // cases is we lose the ability to properly step in the debugger, as the debugger uses that
- // object's identity to track this specific builder/state machine. As such, we proceed to
- // overwrite whatever's there anyway, even if it's non-null.
-#if CORERT
- // DebugFinalizableAsyncStateMachineBox looks like a small type, but it actually is not because
- // it will have a copy of all the slots from its parent. It will add another hundred(s) bytes
- // per each async method in CoreRT / ProjectN binaries without adding much value. Avoid
- // generating this extra code until a better solution is implemented.
- var box = new AsyncStateMachineBox<TStateMachine>();
-#else
- AsyncStateMachineBox<TStateMachine> box = AsyncMethodBuilderCore.TrackAsyncMethodCompletion ?
- CreateDebugFinalizableAsyncStateMachineBox<TStateMachine>() :
- new AsyncStateMachineBox<TStateMachine>();
-#endif
- taskField = box; // important: this must be done before storing stateMachine into box.StateMachine!
- box.StateMachine = stateMachine;
- box.Context = currentContext;
-
- // Log the creation of the state machine box object / task for this async method.
- if (AsyncCausalityTracer.LoggingOn)
- {
- AsyncCausalityTracer.TraceOperationCreation(box, "Async: " + stateMachine.GetType().Name);
- }
-
- // And if async debugging is enabled, track the task.
- if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
- {
- System.Threading.Tasks.Task.AddToActiveTasks(box);
- }
-
- return box;
- }
-
-#if !CORERT
- // Avoid forcing the JIT to build DebugFinalizableAsyncStateMachineBox<TStateMachine> unless it's actually needed.
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static AsyncStateMachineBox<TStateMachine> CreateDebugFinalizableAsyncStateMachineBox<TStateMachine>()
- where TStateMachine : IAsyncStateMachine =>
- new DebugFinalizableAsyncStateMachineBox<TStateMachine>();
-
- /// <summary>
- /// Provides an async state machine box with a finalizer that will fire an EventSource
- /// event about the state machine if it's being finalized without having been completed.
- /// </summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- private sealed class DebugFinalizableAsyncStateMachineBox<TStateMachine> : // SOS DumpAsync command depends on this name
- AsyncStateMachineBox<TStateMachine>
- where TStateMachine : IAsyncStateMachine
- {
- ~DebugFinalizableAsyncStateMachineBox()
- {
- // If the state machine is being finalized, something went wrong during its processing,
- // e.g. it awaited something that got collected without itself having been completed.
- // Fire an event with details about the state machine to help with debugging.
- if (!IsCompleted) // double-check it's not completed, just to help minimize false positives
- {
- TplEventSource.Log.IncompleteAsyncMethod(this);
- }
- }
- }
-#endif
-
- /// <summary>A strongly-typed box for Task-based async state machines.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- private class AsyncStateMachineBox<TStateMachine> : // SOS DumpAsync command depends on this name
- Task<TResult>, IAsyncStateMachineBox
- where TStateMachine : IAsyncStateMachine
- {
- /// <summary>Delegate used to invoke on an ExecutionContext when passed an instance of this box type.</summary>
- private static readonly ContextCallback s_callback = ExecutionContextCallback;
-
- // Used to initialize s_callback above. We don't use a lambda for this on purpose: a lambda would
- // introduce a new generic type behind the scenes that comes with a hefty size penalty in AOT builds.
- private static void ExecutionContextCallback(object? s)
- {
- Debug.Assert(s is AsyncStateMachineBox<TStateMachine>);
- // Only used privately to pass directly to EC.Run
- Unsafe.As<AsyncStateMachineBox<TStateMachine>>(s).StateMachine!.MoveNext();
- }
-
- /// <summary>A delegate to the <see cref="MoveNext()"/> method.</summary>
- private Action? _moveNextAction;
- /// <summary>The state machine itself.</summary>
- [AllowNull, MaybeNull]
- public TStateMachine StateMachine = default; // mutable struct; do not make this readonly. SOS DumpAsync command depends on this name.
- /// <summary>Captured ExecutionContext with which to invoke <see cref="MoveNextAction"/>; may be null.</summary>
- public ExecutionContext? Context;
-
- /// <summary>A delegate to the <see cref="MoveNext()"/> method.</summary>
- public Action MoveNextAction => _moveNextAction ??= new Action(MoveNext);
-
- internal sealed override void ExecuteFromThreadPool(Thread threadPoolThread) => MoveNext(threadPoolThread);
-
- /// <summary>Calls MoveNext on <see cref="StateMachine"/></summary>
- public void MoveNext() => MoveNext(threadPoolThread: null);
-
- private void MoveNext(Thread? threadPoolThread)
- {
- Debug.Assert(!IsCompleted);
-
- bool loggingOn = AsyncCausalityTracer.LoggingOn;
- if (loggingOn)
- {
- AsyncCausalityTracer.TraceSynchronousWorkStart(this, CausalitySynchronousWork.Execution);
- }
-
- ExecutionContext? context = Context;
- if (context == null)
- {
- Debug.Assert(StateMachine != null);
- StateMachine.MoveNext();
- }
- else
- {
- if (threadPoolThread is null)
- {
- ExecutionContext.RunInternal(context, s_callback, this);
- }
- else
- {
- ExecutionContext.RunFromThreadPoolDispatchLoop(threadPoolThread, context, s_callback, this);
- }
- }
-
- if (IsCompleted)
- {
- // If async debugging is enabled, remove the task from tracking.
- if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
- {
- System.Threading.Tasks.Task.RemoveFromActiveTasks(this);
- }
-
- // Clear out state now that the async method has completed.
- // This avoids keeping arbitrary state referenced by lifted locals
- // if this Task / state machine box is held onto.
- StateMachine = default;
- Context = default;
-
-#if !CORERT
- // In case this is a state machine box with a finalizer, suppress its finalization
- // as it's now complete. We only need the finalizer to run if the box is collected
- // without having been completed.
- if (AsyncMethodBuilderCore.TrackAsyncMethodCompletion)
- {
- GC.SuppressFinalize(this);
- }
-#endif
- }
-
- if (loggingOn)
- {
- AsyncCausalityTracer.TraceSynchronousWorkCompletion(CausalitySynchronousWork.Execution);
- }
- }
-
- /// <summary>Gets the state machine as a boxed object. This should only be used for debugging purposes.</summary>
- IAsyncStateMachine IAsyncStateMachineBox.GetStateMachineObject() => StateMachine!; // likely boxes, only use for debugging
- }
-
- /// <summary>Gets the <see cref="System.Threading.Tasks.Task{TResult}"/> for this builder.</summary>
- /// <returns>The <see cref="System.Threading.Tasks.Task{TResult}"/> representing the builder's asynchronous operation.</returns>
- public Task<TResult> Task
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => m_task ?? InitializeTaskAsPromise();
- }
-
- /// <summary>
- /// Initializes the task, which must not yet be initialized. Used only when the Task is being forced into
- /// existence when no state machine is needed, e.g. when the builder is being synchronously completed with
- /// an exception, when the builder is being used out of the context of an async method, etc.
- /// </summary>
- [MethodImpl(MethodImplOptions.NoInlining)]
- private Task<TResult> InitializeTaskAsPromise()
- {
- Debug.Assert(m_task == null);
- return m_task = new Task<TResult>();
- }
-
- internal static Task<TResult> CreateWeaklyTypedStateMachineBox()
- {
-#if CORERT
- // DebugFinalizableAsyncStateMachineBox looks like a small type, but it actually is not because
- // it will have a copy of all the slots from its parent. It will add another hundred(s) bytes
- // per each async method in CoreRT / ProjectN binaries without adding much value. Avoid
- // generating this extra code until a better solution is implemented.
- return new AsyncStateMachineBox<IAsyncStateMachine>();
-#else
- return AsyncMethodBuilderCore.TrackAsyncMethodCompletion ?
- CreateDebugFinalizableAsyncStateMachineBox<IAsyncStateMachine>() :
- new AsyncStateMachineBox<IAsyncStateMachine>();
-#endif
- }
-
- /// <summary>
- /// Completes the <see cref="System.Threading.Tasks.Task{TResult}"/> in the
- /// <see cref="System.Threading.Tasks.TaskStatus">RanToCompletion</see> state with the specified result.
- /// </summary>
- /// <param name="result">The result to use to complete the task.</param>
- /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
- public void SetResult(TResult result)
- {
- // Get the currently stored task, which will be non-null if get_Task has already been accessed.
- // If there isn't one, get a task and store it.
- if (m_task is null)
- {
- m_task = GetTaskForResult(result);
- Debug.Assert(m_task != null, $"{nameof(GetTaskForResult)} should never return null");
- }
- else
- {
- // Slow path: complete the existing task.
- SetExistingTaskResult(m_task, result);
- }
- }
-
- /// <summary>Completes the already initialized task with the specified result.</summary>
- /// <param name="result">The result to use to complete the task.</param>
- internal static void SetExistingTaskResult(Task<TResult> taskField, [AllowNull] TResult result)
- {
- Debug.Assert(taskField != null, "Expected non-null task");
-
- if (AsyncCausalityTracer.LoggingOn)
- {
- AsyncCausalityTracer.TraceOperationCompletion(taskField, AsyncCausalityStatus.Completed);
- }
-
- if (!taskField.TrySetResult(result))
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
- }
- }
-
- /// <summary>
- /// Completes the <see cref="System.Threading.Tasks.Task{TResult}"/> in the
- /// <see cref="System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
- /// </summary>
- /// <param name="exception">The <see cref="System.Exception"/> to use to fault the task.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
- public void SetException(Exception exception) => SetException(exception, ref m_task);
-
- internal static void SetException(Exception exception, ref Task<TResult>? taskField)
- {
- if (exception == null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
- }
-
- // Get the task, forcing initialization if it hasn't already been initialized.
- Task<TResult> task = (taskField ??= new Task<TResult>());
-
- // If the exception represents cancellation, cancel the task. Otherwise, fault the task.
- bool successfullySet = exception is OperationCanceledException oce ?
- task.TrySetCanceled(oce.CancellationToken, oce) :
- task.TrySetException(exception);
-
- // Unlike with TaskCompletionSource, we do not need to spin here until _taskAndStateMachine is completed,
- // since AsyncTaskMethodBuilder.SetException should not be immediately followed by any code
- // that depends on the task having completely completed. Moreover, with correct usage,
- // SetResult or SetException should only be called once, so the Try* methods should always
- // return true, so no spinning would be necessary anyway (the spinning in TCS is only relevant
- // if another thread completes the task first).
- if (!successfullySet)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
- }
- }
-
- /// <summary>
- /// Called by the debugger to request notification when the first wait operation
- /// (await, Wait, Result, etc.) on this builder's task completes.
- /// </summary>
- /// <param name="enabled">
- /// true to enable notification; false to disable a previously set notification.
- /// </param>
- /// <remarks>
- /// This should only be invoked from within an asynchronous method,
- /// and only by the debugger.
- /// </remarks>
- internal void SetNotificationForWaitCompletion(bool enabled) =>
- SetNotificationForWaitCompletion(enabled, ref m_task);
-
- internal static void SetNotificationForWaitCompletion(bool enabled, [NotNull] ref Task<TResult>? taskField)
- {
- // Get the task (forcing initialization if not already initialized), and set debug notification
- (taskField ??= CreateWeaklyTypedStateMachineBox()).SetNotificationForWaitCompletion(enabled);
-
- // NOTE: It's important that the debugger use builder.SetNotificationForWaitCompletion
- // rather than builder.Task.SetNotificationForWaitCompletion. Even though the latter will
- // lazily-initialize the task as well, it'll initialize it to a Task<T> (which is important
- // to minimize size for cases where an ATMB is used directly by user code to avoid the
- // allocation overhead of a TaskCompletionSource). If that's done prior to the first await,
- // the GetMoveNextDelegate code, which needs an AsyncStateMachineBox, will end up creating
- // a new box and overwriting the previously created task. That'll change the object identity
- // of the task being used for wait completion notification, and no notification will
- // ever arrive, breaking step-out behavior when stepping out before the first yielding await.
- }
-
- /// <summary>
- /// Gets an object that may be used to uniquely identify this builder to the debugger.
- /// </summary>
- /// <remarks>
- /// This property lazily instantiates the ID in a non-thread-safe manner.
- /// It must only be used by the debugger and tracing purposes, and only in a single-threaded manner
- /// when no other threads are in the middle of accessing this or other members that lazily initialize the task.
- /// </remarks>
- internal object ObjectIdForDebugger => m_task ??= CreateWeaklyTypedStateMachineBox();
-
- /// <summary>
- /// Gets a task for the specified result. This will either
- /// be a cached or new task, never null.
- /// </summary>
- /// <param name="result">The result for which we need a task.</param>
- /// <returns>The completed task containing the result.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)] // method looks long, but for a given TResult it results in a relatively small amount of asm
- internal static Task<TResult> GetTaskForResult(TResult result)
- {
- // The goal of this function is to be give back a cached task if possible,
- // or to otherwise give back a new task. To give back a cached task,
- // we need to be able to evaluate the incoming result value, and we need
- // to avoid as much overhead as possible when doing so, as this function
- // is invoked as part of the return path from every async method.
- // Most tasks won't be cached, and thus we need the checks for those that are
- // to be as close to free as possible. This requires some trickiness given the
- // lack of generic specialization in .NET.
- //
- // Be very careful when modifying this code. It has been tuned
- // to comply with patterns recognized by both 32-bit and 64-bit JITs.
- // If changes are made here, be sure to look at the generated assembly, as
- // small tweaks can have big consequences for what does and doesn't get optimized away.
- //
- // Note that this code only ever accesses a static field when it knows it'll
- // find a cached value, since static fields (even if readonly and integral types)
- // require special access helpers in this NGEN'd and domain-neutral.
-
- if (null != (object)default(TResult)!) // help the JIT avoid the value type branches for ref types // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- // Special case simple value types:
- // - Boolean
- // - Byte, SByte
- // - Char
- // - Int32, UInt32
- // - Int64, UInt64
- // - Int16, UInt16
- // - IntPtr, UIntPtr
- // As of .NET 4.5, the (Type)(object)result pattern used below
- // is recognized and optimized by both 32-bit and 64-bit JITs.
-
- // For Boolean, we cache all possible values.
- if (typeof(TResult) == typeof(bool)) // only the relevant branches are kept for each value-type generic instantiation
- {
- bool value = (bool)(object)result!;
- Task<bool> task = value ? AsyncTaskCache.s_trueTask : AsyncTaskCache.s_falseTask;
- return Unsafe.As<Task<TResult>>(task); // UnsafeCast avoids type check we know will succeed
- }
- // For Int32, we cache a range of common values, e.g. [-1,9).
- else if (typeof(TResult) == typeof(int))
- {
- // Compare to constants to avoid static field access if outside of cached range.
- // We compare to the upper bound first, as we're more likely to cache miss on the upper side than on the
- // lower side, due to positive values being more common than negative as return values.
- int value = (int)(object)result!;
- if (value < AsyncTaskCache.ExclusiveInt32Max &&
- value >= AsyncTaskCache.InclusiveInt32Min)
- {
- Task<int> task = AsyncTaskCache.s_int32Tasks[value - AsyncTaskCache.InclusiveInt32Min];
- return Unsafe.As<Task<TResult>>(task); // UnsafeCast avoids a type check we know will succeed
- }
- }
- // For other known value types, we only special-case 0 / default(TResult).
- else if (
- (typeof(TResult) == typeof(uint) && default == (uint)(object)result!) ||
- (typeof(TResult) == typeof(byte) && default(byte) == (byte)(object)result!) ||
- (typeof(TResult) == typeof(sbyte) && default(sbyte) == (sbyte)(object)result!) ||
- (typeof(TResult) == typeof(char) && default(char) == (char)(object)result!) ||
- (typeof(TResult) == typeof(long) && default == (long)(object)result!) ||
- (typeof(TResult) == typeof(ulong) && default == (ulong)(object)result!) ||
- (typeof(TResult) == typeof(short) && default(short) == (short)(object)result!) ||
- (typeof(TResult) == typeof(ushort) && default(ushort) == (ushort)(object)result!) ||
- (typeof(TResult) == typeof(IntPtr) && default == (IntPtr)(object)result!) ||
- (typeof(TResult) == typeof(UIntPtr) && default == (UIntPtr)(object)result!))
- {
- return s_defaultResultTask;
- }
- }
- else if (result == null) // optimized away for value types
- {
- return s_defaultResultTask;
- }
-
- // No cached task is available. Manufacture a new one for this result.
- return new Task<TResult>(result);
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs
deleted file mode 100644
index bb5bd28393c..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using Internal.Runtime.CompilerServices;
-
-using StateMachineBox = System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.StateMachineBox;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Represents a builder for asynchronous methods that return a <see cref="ValueTask"/>.</summary>
- [StructLayout(LayoutKind.Auto)]
- public struct AsyncValueTaskMethodBuilder
- {
- /// <summary>Sentinel object used to indicate that the builder completed synchronously and successfully.</summary>
- private static readonly object s_syncSuccessSentinel = AsyncValueTaskMethodBuilder<VoidTaskResult>.s_syncSuccessSentinel;
-
- /// <summary>The wrapped state machine box or task, based on the value of <see cref="AsyncTaskCache.s_valueTaskPoolingEnabled"/>.</summary>
- /// <remarks>
- /// If the operation completed synchronously and successfully, this will be <see cref="s_syncSuccessSentinel"/>.
- /// </remarks>
- private object? m_task; // Debugger depends on the exact name of this field.
-
- /// <summary>Creates an instance of the <see cref="AsyncValueTaskMethodBuilder"/> struct.</summary>
- /// <returns>The initialized instance.</returns>
- public static AsyncValueTaskMethodBuilder Create() => default;
-
- /// <summary>Begins running the builder with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Start<TStateMachine>(ref TStateMachine stateMachine)
- where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Associates the builder with the specified state machine.</summary>
- /// <param name="stateMachine">The state machine instance to associate with the builder.</param>
- public void SetStateMachine(IAsyncStateMachine stateMachine) =>
- AsyncMethodBuilderCore.SetStateMachine(stateMachine, task: null);
-
- /// <summary>Marks the task as successfully completed.</summary>
- public void SetResult()
- {
- if (m_task is null)
- {
- m_task = s_syncSuccessSentinel;
- }
- else if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- Unsafe.As<StateMachineBox>(m_task).SetResult(default);
- }
- else
- {
- AsyncTaskMethodBuilder<VoidTaskResult>.SetExistingTaskResult(Unsafe.As<Task<VoidTaskResult>>(m_task), default);
- }
- }
-
- /// <summary>Marks the task as failed and binds the specified exception to the task.</summary>
- /// <param name="exception">The exception to bind to the task.</param>
- public void SetException(Exception exception)
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- AsyncValueTaskMethodBuilder<VoidTaskResult>.SetException(exception, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<VoidTaskResult>.SetException(exception, ref Unsafe.As<object?, Task<VoidTaskResult>?>(ref m_task));
- }
- }
-
- /// <summary>Gets the task for this builder.</summary>
- public ValueTask Task
- {
- get
- {
- if (m_task == s_syncSuccessSentinel)
- {
- return default;
- }
-
- // With normal access paterns, m_task should always be non-null here: the async method should have
- // either completed synchronously, in which case SetResult would have set m_task to a non-null object,
- // or it should be completing asynchronously, in which case AwaitUnsafeOnCompleted would have similarly
- // initialized m_task to a state machine object. However, if the type is used manually (not via
- // compiler-generated code) and accesses Task directly, we force it to be initialized. Things will then
- // "work" but in a degraded mode, as we don't know the TStateMachine type here, and thus we use a box around
- // the interface instead.
-
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- var box = Unsafe.As<StateMachineBox?>(m_task);
- if (box is null)
- {
- m_task = box = AsyncValueTaskMethodBuilder<VoidTaskResult>.CreateWeaklyTypedStateMachineBox();
- }
- return new ValueTask(box, box.Version);
- }
- else
- {
- var task = Unsafe.As<Task<VoidTaskResult>?>(m_task);
- if (task is null)
- {
- m_task = task = new Task<VoidTaskResult>(); // base task used rather than box to minimize size when used as manual promise
- }
- return new ValueTask(task);
- }
- }
- }
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- AsyncValueTaskMethodBuilder<VoidTaskResult>.AwaitOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<VoidTaskResult>.AwaitOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, Task<VoidTaskResult>?>(ref m_task));
- }
- }
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- AsyncValueTaskMethodBuilder<VoidTaskResult>.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<VoidTaskResult>.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, Task<VoidTaskResult>?>(ref m_task));
- }
- }
-
- /// <summary>
- /// Gets an object that may be used to uniquely identify this builder to the debugger.
- /// </summary>
- /// <remarks>
- /// This property lazily instantiates the ID in a non-thread-safe manner.
- /// It must only be used by the debugger and tracing purposes, and only in a single-threaded manner
- /// when no other threads are in the middle of accessing this or other members that lazily initialize the box.
- /// </remarks>
- internal object ObjectIdForDebugger
- {
- get
- {
- if (m_task is null)
- {
- m_task = AsyncTaskCache.s_valueTaskPoolingEnabled ? (object)
- AsyncValueTaskMethodBuilder<VoidTaskResult>.CreateWeaklyTypedStateMachineBox() :
- AsyncTaskMethodBuilder<VoidTaskResult>.CreateWeaklyTypedStateMachineBox();
- }
-
- return m_task;
- }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs
deleted file mode 100644
index d2bd7ec111a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilderT.cs
+++ /dev/null
@@ -1,513 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Threading.Tasks.Sources;
-using Internal.Runtime.CompilerServices;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Represents a builder for asynchronous methods that returns a <see cref="ValueTask{TResult}"/>.</summary>
- /// <typeparam name="TResult">The type of the result.</typeparam>
- [StructLayout(LayoutKind.Auto)]
- public struct AsyncValueTaskMethodBuilder<TResult>
- {
- /// <summary>Sentinel object used to indicate that the builder completed synchronously and successfully.</summary>
- /// <remarks>
- /// To avoid memory safety issues even in the face of invalid race conditions, we ensure that the type of this object
- /// is valid for the mode in which we're operating. As such, it's cached on the generic builder per TResult
- /// rather than having one sentinel instance for all types.
- /// </remarks>
- internal static readonly object s_syncSuccessSentinel = AsyncTaskCache.s_valueTaskPoolingEnabled ? (object)
- new SyncSuccessSentinelStateMachineBox() :
- new Task<TResult>(default(TResult)!);
-
- /// <summary>The wrapped state machine or task. If the operation completed synchronously and successfully, this will be a sentinel object compared by reference identity.</summary>
- private object? m_task; // Debugger depends on the exact name of this field.
- /// <summary>The result for this builder if it's completed synchronously, in which case <see cref="m_task"/> will be <see cref="s_syncSuccessSentinel"/>.</summary>
- private TResult _result;
-
- /// <summary>Creates an instance of the <see cref="AsyncValueTaskMethodBuilder{TResult}"/> struct.</summary>
- /// <returns>The initialized instance.</returns>
- public static AsyncValueTaskMethodBuilder<TResult> Create() => default;
-
- /// <summary>Begins running the builder with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Associates the builder with the specified state machine.</summary>
- /// <param name="stateMachine">The state machine instance to associate with the builder.</param>
- public void SetStateMachine(IAsyncStateMachine stateMachine) =>
- AsyncMethodBuilderCore.SetStateMachine(stateMachine, task: null);
-
- /// <summary>Marks the value task as successfully completed.</summary>
- /// <param name="result">The result to use to complete the value task.</param>
- public void SetResult(TResult result)
- {
- if (m_task is null)
- {
- _result = result;
- m_task = s_syncSuccessSentinel;
- }
- else if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- Unsafe.As<StateMachineBox>(m_task).SetResult(result);
- }
- else
- {
- AsyncTaskMethodBuilder<TResult>.SetExistingTaskResult(Unsafe.As<Task<TResult>>(m_task), result);
- }
- }
-
- /// <summary>Marks the value task as failed and binds the specified exception to the value task.</summary>
- /// <param name="exception">The exception to bind to the value task.</param>
- public void SetException(Exception exception)
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- SetException(exception, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<TResult>.SetException(exception, ref Unsafe.As<object?, Task<TResult>?>(ref m_task));
- }
- }
-
- internal static void SetException(Exception exception, [NotNull] ref StateMachineBox? boxFieldRef)
- {
- if (exception is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
- }
-
- (boxFieldRef ??= CreateWeaklyTypedStateMachineBox()).SetException(exception);
- }
-
- /// <summary>Gets the value task for this builder.</summary>
- public ValueTask<TResult> Task
- {
- get
- {
- if (m_task == s_syncSuccessSentinel)
- {
- return new ValueTask<TResult>(_result);
- }
-
- // With normal access paterns, m_task should always be non-null here: the async method should have
- // either completed synchronously, in which case SetResult would have set m_task to a non-null object,
- // or it should be completing asynchronously, in which case AwaitUnsafeOnCompleted would have similarly
- // initialized m_task to a state machine object. However, if the type is used manually (not via
- // compiler-generated code) and accesses Task directly, we force it to be initialized. Things will then
- // "work" but in a degraded mode, as we don't know the TStateMachine type here, and thus we use a box around
- // the interface instead.
-
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- var box = Unsafe.As<StateMachineBox?>(m_task);
- if (box is null)
- {
- m_task = box = CreateWeaklyTypedStateMachineBox();
- }
- return new ValueTask<TResult>(box, box.Version);
- }
- else
- {
- var task = Unsafe.As<Task<TResult>?>(m_task);
- if (task is null)
- {
- m_task = task = new Task<TResult>(); // base task used rather than box to minimize size when used as manual promise
- }
- return new ValueTask<TResult>(task);
- }
- }
- }
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">the awaiter</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- AwaitOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<TResult>.AwaitOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, Task<TResult>?>(ref m_task));
- }
- }
-
- internal static void AwaitOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref StateMachineBox? box)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- try
- {
- awaiter.OnCompleted(GetStateMachineBox(ref stateMachine, ref box).MoveNextAction);
- }
- catch (Exception e)
- {
- System.Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
- }
- }
-
- /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
- /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
- /// <param name="awaiter">the awaiter</param>
- /// <param name="stateMachine">The state machine.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- if (AsyncTaskCache.s_valueTaskPoolingEnabled)
- {
- AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, StateMachineBox?>(ref m_task));
- }
- else
- {
- AsyncTaskMethodBuilder<TResult>.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref Unsafe.As<object?, Task<TResult>?>(ref m_task));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref StateMachineBox? boxRef)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- {
- IAsyncStateMachineBox box = GetStateMachineBox(ref stateMachine, ref boxRef);
- AsyncTaskMethodBuilder<VoidTaskResult>.AwaitUnsafeOnCompleted(ref awaiter, box);
- }
-
- /// <summary>Gets the "boxed" state machine object.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the async state machine.</typeparam>
- /// <param name="stateMachine">The state machine.</param>
- /// <param name="boxFieldRef">A reference to the field containing the initialized state machine box.</param>
- /// <returns>The "boxed" state machine.</returns>
- private static IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(
- ref TStateMachine stateMachine,
- [NotNull] ref StateMachineBox? boxFieldRef)
- where TStateMachine : IAsyncStateMachine
- {
- ExecutionContext? currentContext = ExecutionContext.Capture();
-
- // Check first for the most common case: not the first yield in an async method.
- // In this case, the first yield will have already "boxed" the state machine in
- // a strongly-typed manner into an AsyncStateMachineBox. It will already contain
- // the state machine as well as a MoveNextDelegate and a context. The only thing
- // we might need to do is update the context if that's changed since it was stored.
- if (boxFieldRef is StateMachineBox<TStateMachine> stronglyTypedBox)
- {
- if (stronglyTypedBox.Context != currentContext)
- {
- stronglyTypedBox.Context = currentContext;
- }
-
- return stronglyTypedBox;
- }
-
- // The least common case: we have a weakly-typed boxed. This results if the debugger
- // or some other use of reflection accesses a property like ObjectIdForDebugger. In
- // such situations, we need to get an object to represent the builder, but we don't yet
- // know the type of the state machine, and thus can't use TStateMachine. Instead, we
- // use the IAsyncStateMachine interface, which all TStateMachines implement. This will
- // result in a boxing allocation when storing the TStateMachine if it's a struct, but
- // this only happens in active debugging scenarios where such performance impact doesn't
- // matter.
- if (boxFieldRef is StateMachineBox<IAsyncStateMachine> weaklyTypedBox)
- {
- // If this is the first await, we won't yet have a state machine, so store it.
- if (weaklyTypedBox.StateMachine is null)
- {
- Debugger.NotifyOfCrossThreadDependency(); // same explanation as with usage below
- weaklyTypedBox.StateMachine = stateMachine;
- }
-
- // Update the context. This only happens with a debugger, so no need to spend
- // extra IL checking for equality before doing the assignment.
- weaklyTypedBox.Context = currentContext;
- return weaklyTypedBox;
- }
-
- // Alert a listening debugger that we can't make forward progress unless it slips threads.
- // If we don't do this, and a method that uses "await foo;" is invoked through funceval,
- // we could end up hooking up a callback to push forward the async method's state machine,
- // the debugger would then abort the funceval after it takes too long, and then continuing
- // execution could result in another callback being hooked up. At that point we have
- // multiple callbacks registered to push the state machine, which could result in bad behavior.
- Debugger.NotifyOfCrossThreadDependency();
-
- // At this point, m_task should really be null, in which case we want to create the box.
- // However, in a variety of debugger-related (erroneous) situations, it might be non-null,
- // e.g. if the Task property is examined in a Watch window, forcing it to be lazily-intialized
- // as a Task<TResult> rather than as an ValueTaskStateMachineBox. The worst that happens in such
- // cases is we lose the ability to properly step in the debugger, as the debugger uses that
- // object's identity to track this specific builder/state machine. As such, we proceed to
- // overwrite whatever's there anyway, even if it's non-null.
- var box = StateMachineBox<TStateMachine>.GetOrCreateBox();
- boxFieldRef = box; // important: this must be done before storing stateMachine into box.StateMachine!
- box.StateMachine = stateMachine;
- box.Context = currentContext;
-
- return box;
- }
-
- /// <summary>
- /// Creates a box object for use when a non-standard access pattern is employed, e.g. when Task
- /// is evaluated in the debugger prior to the async method yielding for the first time.
- /// </summary>
- internal static StateMachineBox CreateWeaklyTypedStateMachineBox() => new StateMachineBox<IAsyncStateMachine>();
-
- /// <summary>
- /// Gets an object that may be used to uniquely identify this builder to the debugger.
- /// </summary>
- /// <remarks>
- /// This property lazily instantiates the ID in a non-thread-safe manner.
- /// It must only be used by the debugger and tracing purposes, and only in a single-threaded manner
- /// when no other threads are in the middle of accessing this or other members that lazily initialize the box.
- /// </remarks>
- internal object ObjectIdForDebugger
- {
- get
- {
- if (m_task is null)
- {
- m_task = AsyncTaskCache.s_valueTaskPoolingEnabled ? (object)
- CreateWeaklyTypedStateMachineBox() :
- AsyncTaskMethodBuilder<TResult>.CreateWeaklyTypedStateMachineBox();
- }
-
- return m_task;
- }
- }
-
- /// <summary>The base type for all value task box reusable box objects, regardless of state machine type.</summary>
- internal abstract class StateMachineBox :
- IValueTaskSource<TResult>, IValueTaskSource
- {
- /// <summary>A delegate to the MoveNext method.</summary>
- protected Action? _moveNextAction;
- /// <summary>Captured ExecutionContext with which to invoke MoveNext.</summary>
- public ExecutionContext? Context;
- /// <summary>Implementation for IValueTaskSource interfaces.</summary>
- protected ManualResetValueTaskSourceCore<TResult> _valueTaskSource;
-
- /// <summary>Completes the box with a result.</summary>
- /// <param name="result">The result.</param>
- public void SetResult(TResult result) =>
- _valueTaskSource.SetResult(result);
-
- /// <summary>Completes the box with an error.</summary>
- /// <param name="error">The exception.</param>
- public void SetException(Exception error) =>
- _valueTaskSource.SetException(error);
-
- /// <summary>Gets the status of the box.</summary>
- public ValueTaskSourceStatus GetStatus(short token) => _valueTaskSource.GetStatus(token);
-
- /// <summary>Schedules the continuation action for this box.</summary>
- public void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) =>
- _valueTaskSource.OnCompleted(continuation, state, token, flags);
-
- /// <summary>Gets the current version number of the box.</summary>
- public short Version => _valueTaskSource.Version;
-
- /// <summary>Implemented by derived type.</summary>
- TResult IValueTaskSource<TResult>.GetResult(short token) => throw NotImplemented.ByDesign;
-
- /// <summary>Implemented by derived type.</summary>
- void IValueTaskSource.GetResult(short token) => throw NotImplemented.ByDesign;
- }
-
- private sealed class SyncSuccessSentinelStateMachineBox : StateMachineBox
- {
- public SyncSuccessSentinelStateMachineBox() => SetResult(default!);
- }
-
- /// <summary>Provides a strongly-typed box object based on the specific state machine type in use.</summary>
- private sealed class StateMachineBox<TStateMachine> :
- StateMachineBox,
- IValueTaskSource<TResult>, IValueTaskSource, IAsyncStateMachineBox, IThreadPoolWorkItem
- where TStateMachine : IAsyncStateMachine
- {
- /// <summary>Delegate used to invoke on an ExecutionContext when passed an instance of this box type.</summary>
- private static readonly ContextCallback s_callback = ExecutionContextCallback;
- /// <summary>Lock used to protected the shared cache of boxes.</summary>
- /// <remarks>The code that uses this assumes a runtime without thread aborts.</remarks>
- private static int s_cacheLock;
- /// <summary>Singly-linked list cache of boxes.</summary>
- private static StateMachineBox<TStateMachine>? s_cache;
- /// <summary>The number of items stored in <see cref="s_cache"/>.</summary>
- private static int s_cacheSize;
-
- // TODO:
- // AsyncTaskMethodBuilder logs about the state machine box lifecycle; AsyncValueTaskMethodBuilder currently
- // does not when it employs these pooled boxes. That logging is based on Task IDs, which we lack here.
- // We could use the box's Version, but that is very likely to conflict with the IDs of other tasks in the system.
- // For now, we don't log, but should we choose to we'll probably want to store an int ID on the state machine box,
- // and initialize it an ID from Task's generator.
-
- /// <summary>If this box is stored in the cache, the next box in the cache.</summary>
- private StateMachineBox<TStateMachine>? _next;
- /// <summary>The state machine itself.</summary>
- [AllowNull, MaybeNull]
- public TStateMachine StateMachine = default;
-
- /// <summary>Gets a box object to use for an operation. This may be a reused, pooled object, or it may be new.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)] // only one caller
- internal static StateMachineBox<TStateMachine> GetOrCreateBox()
- {
- // Try to acquire the lock to access the cache. If there's any contention, don't use the cache.
- if (Interlocked.CompareExchange(ref s_cacheLock, 1, 0) == 0)
- {
- // If there are any instances cached, take one from the cache stack and use it.
- StateMachineBox<TStateMachine>? box = s_cache;
- if (!(box is null))
- {
- s_cache = box._next;
- box._next = null;
- s_cacheSize--;
- Debug.Assert(s_cacheSize >= 0, "Expected the cache size to be non-negative.");
-
- // Release the lock and return the box.
- Volatile.Write(ref s_cacheLock, 0);
- return box;
- }
-
- // No objects were cached. We'll just create a new instance.
- Debug.Assert(s_cacheSize == 0, "Expected cache size to be 0.");
-
- // Release the lock.
- Volatile.Write(ref s_cacheLock, 0);
- }
-
- // Couldn't quickly get a cached instance, so create a new instance.
- return new StateMachineBox<TStateMachine>();
- }
-
- private void ReturnOrDropBox()
- {
- Debug.Assert(_next is null, "Expected box to not be part of cached list.");
-
- // Clear out the state machine and associated context to avoid keeping arbitrary state referenced by
- // lifted locals. We want to do this regardless of whether we end up caching the box or not, in case
- // the caller keeps the box alive for an arbitrary period of time.
- StateMachine = default;
- Context = default;
-
- // Reset the MRVTSC. We can either do this here, in which case we may be paying the (small) overhead
- // to reset the box even if we're going to drop it, or we could do it while holding the lock, in which
- // case we'll only reset it if necessary but causing the lock to be held for longer, thereby causing
- // more contention. For now at least, we do it outside of the lock. (This must not be done after
- // the lock is released, since at that point the instance could already be in use elsewhere.)
- // We also want to increment the version number even if we're going to drop it, to maximize the chances
- // that incorrectly double-awaiting a ValueTask will produce an error.
- _valueTaskSource.Reset();
-
- // If reusing the object would result in potentially wrapping around its version number, just throw it away.
- // This provides a modicum of additional safety when ValueTasks are misused (helping to avoid the case where
- // a ValueTask is illegally re-awaited and happens to do so at exactly 2^16 uses later on this exact same instance),
- // at the expense of potentially incurring an additional allocation every 65K uses.
- if ((ushort)_valueTaskSource.Version == ushort.MaxValue)
- {
- return;
- }
-
- // Try to acquire the cache lock. If there's any contention, or if the cache is full, we just throw away the object.
- if (Interlocked.CompareExchange(ref s_cacheLock, 1, 0) == 0)
- {
- if (s_cacheSize < AsyncTaskCache.s_valueTaskPoolingCacheSize)
- {
- // Push the box onto the cache stack for subsequent reuse.
- _next = s_cache;
- s_cache = this;
- s_cacheSize++;
- Debug.Assert(s_cacheSize > 0 && s_cacheSize <= AsyncTaskCache.s_valueTaskPoolingCacheSize, "Expected cache size to be within bounds.");
- }
-
- // Release the lock.
- Volatile.Write(ref s_cacheLock, 0);
- }
- }
-
- /// <summary>
- /// Used to initialize s_callback above. We don't use a lambda for this on purpose: a lambda would
- /// introduce a new generic type behind the scenes that comes with a hefty size penalty in AOT builds.
- /// </summary>
- private static void ExecutionContextCallback(object? s)
- {
- // Only used privately to pass directly to EC.Run
- Debug.Assert(s is StateMachineBox<TStateMachine>);
- Unsafe.As<StateMachineBox<TStateMachine>>(s).StateMachine!.MoveNext();
- }
-
- /// <summary>A delegate to the <see cref="MoveNext()"/> method.</summary>
- public Action MoveNextAction => _moveNextAction ??= new Action(MoveNext);
-
- /// <summary>Invoked to run MoveNext when this instance is executed from the thread pool.</summary>
- void IThreadPoolWorkItem.Execute() => MoveNext();
-
- /// <summary>Calls MoveNext on <see cref="StateMachine"/></summary>
- public void MoveNext()
- {
- ExecutionContext? context = Context;
-
- if (context is null)
- {
- Debug.Assert(!(StateMachine is null));
- StateMachine.MoveNext();
- }
- else
- {
- ExecutionContext.RunInternal(context, s_callback, this);
- }
- }
-
- /// <summary>Get the result of the operation.</summary>
- TResult IValueTaskSource<TResult>.GetResult(short token)
- {
- try
- {
- return _valueTaskSource.GetResult(token);
- }
- finally
- {
- // Reuse this instance if possible, otherwise clear and drop it.
- ReturnOrDropBox();
- }
- }
-
- /// <summary>Get the result of the operation.</summary>
- void IValueTaskSource.GetResult(short token)
- {
- try
- {
- _valueTaskSource.GetResult(token);
- }
- finally
- {
- // Reuse this instance if possible, otherwise clear and drop it.
- ReturnOrDropBox();
- }
- }
-
- /// <summary>Gets the state machine as a boxed object. This should only be used for debugging purposes.</summary>
- IAsyncStateMachine IAsyncStateMachineBox.GetStateMachineObject() => StateMachine!; // likely boxes, only use for debugging
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs
deleted file mode 100644
index 3a0a0a2c630..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Provides a builder for asynchronous methods that return void.
- /// This type is intended for compiler use only.
- /// </summary>
- public struct AsyncVoidMethodBuilder
- {
- /// <summary>The synchronization context associated with this operation.</summary>
- private SynchronizationContext? _synchronizationContext;
- /// <summary>The builder this void builder wraps.</summary>
- private AsyncTaskMethodBuilder _builder; // mutable struct: must not be readonly
-
- /// <summary>Initializes a new <see cref="AsyncVoidMethodBuilder"/>.</summary>
- /// <returns>The initialized <see cref="AsyncVoidMethodBuilder"/>.</returns>
- public static AsyncVoidMethodBuilder Create()
- {
- SynchronizationContext? sc = SynchronizationContext.Current;
- sc?.OperationStarted();
-
- // _builder should be initialized to AsyncTaskMethodBuilder.Create(), but on coreclr
- // that Create() is a nop, so we can just return the default here.
- return new AsyncVoidMethodBuilder() { _synchronizationContext = sc };
- }
-
- /// <summary>Initiates the builder's execution with the associated state machine.</summary>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="stateMachine">The state machine instance, passed by reference.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
- [DebuggerStepThrough]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
- AsyncMethodBuilderCore.Start(ref stateMachine);
-
- /// <summary>Associates the builder with the state machine it represents.</summary>
- /// <param name="stateMachine">The heap-allocated state machine object.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
- public void SetStateMachine(IAsyncStateMachine stateMachine) =>
- _builder.SetStateMachine(stateMachine);
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- _builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
-
- /// <summary>
- /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
- /// </summary>
- /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
- /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
- /// <param name="awaiter">The awaiter.</param>
- /// <param name="stateMachine">The state machine.</param>
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
- ref TAwaiter awaiter, ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine =>
- _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
-
- /// <summary>Completes the method builder successfully.</summary>
- public void SetResult()
- {
- if (AsyncCausalityTracer.LoggingOn)
- {
- AsyncCausalityTracer.TraceOperationCompletion(this.Task, AsyncCausalityStatus.Completed);
- }
-
- // Mark the builder as completed. As this is a void-returning method, this mostly
- // doesn't matter, but it can affect things like debug events related to finalization.
- _builder.SetResult();
-
- if (_synchronizationContext != null)
- {
- NotifySynchronizationContextOfCompletion();
- }
- }
-
- /// <summary>Faults the method builder with an exception.</summary>
- /// <param name="exception">The exception that is the cause of this fault.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
- public void SetException(Exception exception)
- {
- if (exception == null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
- }
-
- if (AsyncCausalityTracer.LoggingOn)
- {
- AsyncCausalityTracer.TraceOperationCompletion(this.Task, AsyncCausalityStatus.Error);
- }
-
- if (_synchronizationContext != null)
- {
- // If we captured a synchronization context, Post the throwing of the exception to it
- // and decrement its outstanding operation count.
- try
- {
- System.Threading.Tasks.Task.ThrowAsync(exception, targetContext: _synchronizationContext);
- }
- finally
- {
- NotifySynchronizationContextOfCompletion();
- }
- }
- else
- {
- // Otherwise, queue the exception to be thrown on the ThreadPool. This will
- // result in a crash unless legacy exception behavior is enabled by a config
- // file or a CLR host.
- System.Threading.Tasks.Task.ThrowAsync(exception, targetContext: null);
- }
-
- // The exception was propagated already; we don't need or want to fault the builder, just mark it as completed.
- _builder.SetResult();
- }
-
- /// <summary>Notifies the current synchronization context that the operation completed.</summary>
- private void NotifySynchronizationContextOfCompletion()
- {
- Debug.Assert(_synchronizationContext != null, "Must only be used with a non-null context.");
- try
- {
- _synchronizationContext.OperationCompleted();
- }
- catch (Exception exc)
- {
- // If the interaction with the SynchronizationContext goes awry,
- // fall back to propagating on the ThreadPool.
- Task.ThrowAsync(exc, targetContext: null);
- }
- }
-
- /// <summary>Lazily instantiate the Task in a non-thread-safe manner.</summary>
- private Task Task => _builder.Task;
-
- /// <summary>
- /// Gets an object that may be used to uniquely identify this builder to the debugger.
- /// </summary>
- /// <remarks>
- /// This property lazily instantiates the ID in a non-thread-safe manner.
- /// It must only be used by the debugger and AsyncCausalityTracer in a single-threaded manner.
- /// </remarks>
- internal object ObjectIdForDebugger => _builder.ObjectIdForDebugger;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerArgumentExpressionAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerArgumentExpressionAttribute.cs
deleted file mode 100644
index 6e1c4c56cd0..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerArgumentExpressionAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
- public sealed class CallerArgumentExpressionAttribute : Attribute
- {
- public CallerArgumentExpressionAttribute(string parameterName)
- {
- ParameterName = parameterName;
- }
-
- public string ParameterName { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
deleted file mode 100644
index 5858634b427..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerFilePathAttribute : Attribute
- {
- public CallerFilePathAttribute()
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
deleted file mode 100644
index 5bd2fcb91b9..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerLineNumberAttribute : Attribute
- {
- public CallerLineNumberAttribute()
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
deleted file mode 100644
index 8b046335b5a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerMemberNameAttribute : Attribute
- {
- public CallerMemberNameAttribute()
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs
deleted file mode 100644
index 2d1763327ac..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// IMPORTANT: Keep this in sync with corhdr.h
- [Flags]
- public enum CompilationRelaxations : int
- {
- NoStringInterning = 0x0008 // Start in 0x0008, we had other non public flags in this enum before,
- // so we'll start here just in case somebody used them. This flag is only
- // valid when set for Assemblies.
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs
deleted file mode 100644
index d6da23fdf2a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Method)]
- public class CompilationRelaxationsAttribute : Attribute
- {
- public CompilationRelaxationsAttribute(int relaxations)
- {
- CompilationRelaxations = relaxations;
- }
-
- public CompilationRelaxationsAttribute(CompilationRelaxations relaxations)
- {
- CompilationRelaxations = (int)relaxations;
- }
-
- public int CompilationRelaxations { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
deleted file mode 100644
index 1c05abd1fec..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.All, Inherited = true)]
- public sealed class CompilerGeneratedAttribute : Attribute
- {
- public CompilerGeneratedAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
deleted file mode 100644
index 542181ce91f..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // Attribute used to communicate to the VS7 debugger that a class should be treated as if it has global scope.
-
- [AttributeUsage(AttributeTargets.Class)]
- public class CompilerGlobalScopeAttribute : Attribute
- {
- public CompilerGlobalScopeAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConditionalWeakTable.cs
deleted file mode 100644
index ae749f45b8d..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConditionalWeakTable.cs
+++ /dev/null
@@ -1,806 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Threading;
-using Internal.Runtime.CompilerServices;
-
-namespace System.Runtime.CompilerServices
-{
- public sealed class ConditionalWeakTable<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
- where TKey : class
- where TValue : class?
- {
- // Lifetimes of keys and values:
- // Inserting a key and value into the dictonary will not
- // prevent the key from dying, even if the key is strongly reachable
- // from the value. Once the key dies, the dictionary automatically removes
- // the key/value entry.
- //
- // Thread safety guarantees:
- // ConditionalWeakTable is fully thread-safe and requires no
- // additional locking to be done by callers.
- //
- // OOM guarantees:
- // Will not corrupt unmanaged handle table on OOM. No guarantees
- // about managed weak table consistency. Native handles reclamation
- // may be delayed until appdomain shutdown.
-
- private const int InitialCapacity = 8; // Initial length of the table. Must be a power of two.
- private readonly object _lock; // This lock protects all mutation of data in the table. Readers do not take this lock.
- private volatile Container _container; // The actual storage for the table; swapped out as the table grows.
- private int _activeEnumeratorRefCount; // The number of outstanding enumerators on the table
-
- public ConditionalWeakTable()
- {
- _lock = new object();
- _container = new Container(this);
- }
-
- /// <summary>Gets the value of the specified key.</summary>
- /// <param name="key">key of the value to find. Cannot be null.</param>
- /// <param name="value">
- /// If the key is found, contains the value associated with the key upon method return.
- /// If the key is not found, contains default(TValue).
- /// </param>
- /// <returns>Returns "true" if key was found, "false" otherwise.</returns>
- /// <remarks>
- /// The key may get garbaged collected during the TryGetValue operation. If so, TryGetValue
- /// may at its discretion, return "false" and set "value" to the default (as if the key was not present.)
- /// </remarks>
- public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
- {
- if (key is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- return _container.TryGetValueWorker(key, out value);
- }
-
- /// <summary>Adds a key to the table.</summary>
- /// <param name="key">key to add. May not be null.</param>
- /// <param name="value">value to associate with key.</param>
- /// <remarks>
- /// If the key is already entered into the dictionary, this method throws an exception.
- /// The key may get garbage collected during the Add() operation. If so, Add()
- /// has the right to consider any prior entries successfully removed and add a new entry without
- /// throwing an exception.
- /// </remarks>
- public void Add(TKey key, TValue value)
- {
- if (key is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- lock (_lock)
- {
- int entryIndex = _container.FindEntry(key, out _);
- if (entryIndex != -1)
- {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
- }
-
- CreateEntry(key, value);
- }
- }
-
- /// <summary>Adds the key and value if the key doesn't exist, or updates the existing key's value if it does exist.</summary>
- /// <param name="key">key to add or update. May not be null.</param>
- /// <param name="value">value to associate with key.</param>
- public void AddOrUpdate(TKey key, TValue value)
- {
- if (key is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- lock (_lock)
- {
- int entryIndex = _container.FindEntry(key, out _);
-
- // if we found a key we should just update, if no we should create a new entry.
- if (entryIndex != -1)
- {
- _container.UpdateValue(entryIndex, value);
- }
- else
- {
- CreateEntry(key, value);
- }
- }
- }
-
- /// <summary>Removes a key and its value from the table.</summary>
- /// <param name="key">key to remove. May not be null.</param>
- /// <returns>true if the key is found and removed. Returns false if the key was not in the dictionary.</returns>
- /// <remarks>
- /// The key may get garbage collected during the Remove() operation. If so,
- /// Remove() will not fail or throw, however, the return value can be either true or false
- /// depending on who wins the race.
- /// </remarks>
- public bool Remove(TKey key)
- {
- if (key is null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- lock (_lock)
- {
- return _container.Remove(key);
- }
- }
-
- /// <summary>Clear all the key/value pairs</summary>
- public void Clear()
- {
- lock (_lock)
- {
- // To clear, we would prefer to simply drop the existing container
- // and replace it with an empty one, as that's overall more efficient.
- // However, if there are any active enumerators, we don't want to do
- // that as it will end up removing all of the existing entries and
- // allowing new items to be added at the same indices when the container
- // is filled and replaced, and one of the guarantees we try to make with
- // enumeration is that new items added after enumeration starts won't be
- // included in the enumeration. As such, if there are active enumerators,
- // we simply use the container's removal functionality to remove all of the
- // keys; then when the table is resized, if there are still active enumerators,
- // these empty slots will be maintained.
- if (_activeEnumeratorRefCount > 0)
- {
- _container.RemoveAllKeys();
- }
- else
- {
- _container = new Container(this);
- }
- }
- }
-
- /// <summary>
- /// Atomically searches for a specified key in the table and returns the corresponding value.
- /// If the key does not exist in the table, the method invokes a callback method to create a
- /// value that is bound to the specified key.
- /// </summary>
- /// <param name="key">key of the value to find. Cannot be null.</param>
- /// <param name="createValueCallback">callback that creates value for key. Cannot be null.</param>
- /// <returns></returns>
- /// <remarks>
- /// If multiple threads try to initialize the same key, the table may invoke createValueCallback
- /// multiple times with the same key. Exactly one of these calls will succeed and the returned
- /// value of that call will be the one added to the table and returned by all the racing GetValue() calls.
- /// This rule permits the table to invoke createValueCallback outside the internal table lock
- /// to prevent deadlocks.
- /// </remarks>
- public TValue GetValue(TKey key, CreateValueCallback createValueCallback)
- {
- // key is validated by TryGetValue
-
- if (createValueCallback is null)
- {
- throw new ArgumentNullException(nameof(createValueCallback));
- }
-
- return TryGetValue(key, out TValue existingValue) ?
- existingValue :
- GetValueLocked(key, createValueCallback);
- }
-
- private TValue GetValueLocked(TKey key, CreateValueCallback createValueCallback)
- {
- // If we got here, the key was not in the table. Invoke the callback (outside the lock)
- // to generate the new value for the key.
- TValue newValue = createValueCallback(key);
-
- lock (_lock)
- {
- // Now that we've taken the lock, must recheck in case we lost a race to add the key.
- if (_container.TryGetValueWorker(key, out TValue existingValue))
- {
- return existingValue;
- }
- else
- {
- // Verified in-lock that we won the race to add the key. Add it now.
- CreateEntry(key, newValue);
- return newValue;
- }
- }
- }
-
- /// <summary>
- /// Helper method to call GetValue without passing a creation delegate. Uses Activator.CreateInstance
- /// to create new instances as needed. If TValue does not have a default constructor, this will throw.
- /// </summary>
- /// <param name="key">key of the value to find. Cannot be null.</param>
- public TValue GetOrCreateValue(TKey key) => GetValue(key, _ => Activator.CreateInstance<TValue>());
-
- public delegate TValue CreateValueCallback(TKey key);
-
- /// <summary>Gets an enumerator for the table.</summary>
- /// <remarks>
- /// The returned enumerator will not extend the lifetime of
- /// any object pairs in the table, other than the one that's Current. It will not return entries
- /// that have already been collected, nor will it return entries added after the enumerator was
- /// retrieved. It may not return all entries that were present when the enumerat was retrieved,
- /// however, such as not returning entries that were collected or removed after the enumerator
- /// was retrieved but before they were enumerated.
- /// </remarks>
- IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
- {
- lock (_lock)
- {
- Container c = _container;
- return c is null || c.FirstFreeEntry == 0 ?
- ((IEnumerable<KeyValuePair<TKey, TValue>>)Array.Empty<KeyValuePair<TKey, TValue>>()).GetEnumerator() :
- new Enumerator(this);
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<KeyValuePair<TKey, TValue>>)this).GetEnumerator();
-
- /// <summary>Provides an enumerator for the table.</summary>
- private sealed class Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>
- {
- // The enumerator would ideally hold a reference to the Container and the end index within that
- // container. However, the safety of the CWT depends on the only reference to the Container being
- // from the CWT itself; the Container then employs a two-phase finalization scheme, where the first
- // phase nulls out that parent CWT's reference, guaranteeing that the second time it's finalized there
- // can be no other existing references to it in use that would allow for concurrent usage of the
- // native handles with finalization. We would break that if we allowed this Enumerator to hold a
- // reference to the Container. Instead, the Enumerator holds a reference to the CWT rather than to
- // the Container, and it maintains the CWT._activeEnumeratorRefCount field to track whether there
- // are outstanding enumerators that have yet to be disposed/finalized. If there aren't any, the CWT
- // behaves as it normally does. If there are, certain operations are affected, in particular resizes.
- // Normally when the CWT is resized, it enumerates the contents of the table looking for indices that
- // contain entries which have been collected or removed, and it frees those up, effectively moving
- // down all subsequent entries in the container (not in the existing container, but in a replacement).
- // This, however, would cause the enumerator's understanding of indices to break. So, as long as
- // there is any outstanding enumerator, no compaction is performed.
-
- private ConditionalWeakTable<TKey, TValue>? _table; // parent table, set to null when disposed
- private readonly int _maxIndexInclusive; // last index in the container that should be enumerated
- private int _currentIndex; // the current index into the container
- private KeyValuePair<TKey, TValue> _current; // the current entry set by MoveNext and returned from Current
-
- public Enumerator(ConditionalWeakTable<TKey, TValue> table)
- {
- Debug.Assert(table != null, "Must provide a valid table");
- Debug.Assert(Monitor.IsEntered(table._lock), "Must hold the _lock lock to construct the enumerator");
- Debug.Assert(table._container != null, "Should not be used on a finalized table");
- Debug.Assert(table._container.FirstFreeEntry > 0, "Should have returned an empty enumerator instead");
-
- // Store a reference to the parent table and increase its active enumerator count.
- _table = table;
- Debug.Assert(table._activeEnumeratorRefCount >= 0, "Should never have a negative ref count before incrementing");
- table._activeEnumeratorRefCount++;
-
- // Store the max index to be enumerated.
- _maxIndexInclusive = table._container.FirstFreeEntry - 1;
- _currentIndex = -1;
- }
-
- ~Enumerator()
- {
- Dispose();
- }
-
- public void Dispose()
- {
- // Use an interlocked operation to ensure that only one thread can get access to
- // the _table for disposal and thus only decrement the ref count once.
- ConditionalWeakTable<TKey, TValue>? table = Interlocked.Exchange(ref _table, null);
- if (table != null)
- {
- // Ensure we don't keep the last current alive unnecessarily
- _current = default;
-
- // Decrement the ref count that was incremented when constructed
- lock (table._lock)
- {
- table._activeEnumeratorRefCount--;
- Debug.Assert(table._activeEnumeratorRefCount >= 0, "Should never have a negative ref count after decrementing");
- }
-
- // Finalization is purely to decrement the ref count. We can suppress it now.
- GC.SuppressFinalize(this);
- }
- }
-
- public bool MoveNext()
- {
- // Start by getting the current table. If it's already been disposed, it will be null.
- ConditionalWeakTable<TKey, TValue>? table = _table;
- if (table != null)
- {
- // Once have the table, we need to lock to synchronize with other operations on
- // the table, like adding.
- lock (table._lock)
- {
- // From the table, we have to get the current container. This could have changed
- // since we grabbed the enumerator, but the index-to-pair mapping should not have
- // due to there being at least one active enumerator. If the table (or rather its
- // container at the time) has already been finalized, this will be null.
- Container c = table._container;
- if (c != null)
- {
- // We have the container. Find the next entry to return, if there is one.
- // We need to loop as we may try to get an entry that's already been removed
- // or collected, in which case we try again.
- while (_currentIndex < _maxIndexInclusive)
- {
- _currentIndex++;
- if (c.TryGetEntry(_currentIndex, out TKey? key, out TValue value))
- {
- _current = new KeyValuePair<TKey, TValue>(key, value);
- return true;
- }
- }
- }
- }
- }
-
- // Nothing more to enumerate.
- return false;
- }
-
- public KeyValuePair<TKey, TValue> Current
- {
- get
- {
- if (_currentIndex < 0)
- {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
- return _current;
- }
- }
-
- object? IEnumerator.Current => Current;
-
- public void Reset() { }
- }
-
- /// <summary>Worker for adding a new key/value pair. Will resize the container if it is full.</summary>
- /// <param name="key"></param>
- /// <param name="value"></param>
- private void CreateEntry(TKey key, TValue value)
- {
- Debug.Assert(Monitor.IsEntered(_lock));
- Debug.Assert(key != null); // key already validated as non-null and not already in table.
-
- Container c = _container;
- if (!c.HasCapacity)
- {
- _container = c = c.Resize();
- }
- c.CreateEntryNoResize(key, value);
- }
-
- private static bool IsPowerOfTwo(int value) => (value > 0) && ((value & (value - 1)) == 0);
-
- //--------------------------------------------------------------------------------------------
- // Entry can be in one of four states:
- //
- // - Unused (stored with an index _firstFreeEntry and above)
- // depHnd.IsAllocated == false
- // hashCode == <dontcare>
- // next == <dontcare>)
- //
- // - Used with live key (linked into a bucket list where _buckets[hashCode & (_buckets.Length - 1)] points to first entry)
- // depHnd.IsAllocated == true, depHnd.GetPrimary() != null
- // hashCode == RuntimeHelpers.GetHashCode(depHnd.GetPrimary()) & int.MaxValue
- // next links to next Entry in bucket.
- //
- // - Used with dead key (linked into a bucket list where _buckets[hashCode & (_buckets.Length - 1)] points to first entry)
- // depHnd.IsAllocated == true, depHnd.GetPrimary() is null
- // hashCode == <notcare>
- // next links to next Entry in bucket.
- //
- // - Has been removed from the table (by a call to Remove)
- // depHnd.IsAllocated == true, depHnd.GetPrimary() == <notcare>
- // hashCode == -1
- // next links to next Entry in bucket.
- //
- // The only difference between "used with live key" and "used with dead key" is that
- // depHnd.GetPrimary() returns null. The transition from "used with live key" to "used with dead key"
- // happens asynchronously as a result of normal garbage collection. The dictionary itself
- // receives no notification when this happens.
- //
- // When the dictionary grows the _entries table, it scours it for expired keys and does not
- // add those to the new container.
- //--------------------------------------------------------------------------------------------
- private struct Entry
- {
- public DependentHandle depHnd; // Holds key and value using a weak reference for the key and a strong reference
- // for the value that is traversed only if the key is reachable without going through the value.
- public int HashCode; // Cached copy of key's hashcode
- public int Next; // Index of next entry, -1 if last
- }
-
- /// <summary>
- /// Container holds the actual data for the table. A given instance of Container always has the same capacity. When we need
- /// more capacity, we create a new Container, copy the old one into the new one, and discard the old one. This helps enable lock-free
- /// reads from the table, as readers never need to deal with motion of entries due to rehashing.
- /// </summary>
- private sealed class Container
- {
- private readonly ConditionalWeakTable<TKey, TValue> _parent; // the ConditionalWeakTable with which this container is associated
- private int[] _buckets; // _buckets[hashcode & (_buckets.Length - 1)] contains index of the first entry in bucket (-1 if empty)
- private Entry[] _entries; // the table entries containing the stored dependency handles
- private int _firstFreeEntry; // _firstFreeEntry < _entries.Length => table has capacity, entries grow from the bottom of the table.
- private bool _invalid; // flag detects if OOM or other background exception threw us out of the lock.
- private bool _finalized; // set to true when initially finalized
- private volatile object? _oldKeepAlive; // used to ensure the next allocated container isn't finalized until this one is GC'd
-
- internal Container(ConditionalWeakTable<TKey, TValue> parent)
- {
- Debug.Assert(parent != null);
- Debug.Assert(IsPowerOfTwo(InitialCapacity));
-
- const int Size = InitialCapacity;
- _buckets = new int[Size];
- for (int i = 0; i < _buckets.Length; i++)
- {
- _buckets[i] = -1;
- }
- _entries = new Entry[Size];
-
- // Only store the parent after all of the allocations have happened successfully.
- // Otherwise, as part of growing or clearing the container, we could end up allocating
- // a new Container that fails (OOMs) part way through construction but that gets finalized
- // and ends up clearing out some other container present in the associated CWT.
- _parent = parent;
- }
-
- private Container(ConditionalWeakTable<TKey, TValue> parent, int[] buckets, Entry[] entries, int firstFreeEntry)
- {
- Debug.Assert(parent != null);
- Debug.Assert(buckets != null);
- Debug.Assert(entries != null);
- Debug.Assert(buckets.Length == entries.Length);
- Debug.Assert(IsPowerOfTwo(buckets.Length));
-
- _parent = parent;
- _buckets = buckets;
- _entries = entries;
- _firstFreeEntry = firstFreeEntry;
- }
-
- internal bool HasCapacity => _firstFreeEntry < _entries.Length;
-
- internal int FirstFreeEntry => _firstFreeEntry;
-
- /// <summary>Worker for adding a new key/value pair. Container must NOT be full.</summary>
- internal void CreateEntryNoResize(TKey key, TValue value)
- {
- Debug.Assert(key != null); // key already validated as non-null and not already in table.
- Debug.Assert(HasCapacity);
-
- VerifyIntegrity();
- _invalid = true;
-
- int hashCode = RuntimeHelpers.GetHashCode(key) & int.MaxValue;
- int newEntry = _firstFreeEntry++;
-
- _entries[newEntry].HashCode = hashCode;
- _entries[newEntry].depHnd = new DependentHandle(key, value);
- int bucket = hashCode & (_buckets.Length - 1);
- _entries[newEntry].Next = _buckets[bucket];
-
- // This write must be volatile, as we may be racing with concurrent readers. If they see
- // the new entry, they must also see all of the writes earlier in this method.
- Volatile.Write(ref _buckets[bucket], newEntry);
-
- _invalid = false;
- }
-
- /// <summary>Worker for finding a key/value pair. Must hold _lock.</summary>
- internal bool TryGetValueWorker(TKey key, [MaybeNullWhen(false)] out TValue value)
- {
- Debug.Assert(key != null); // Key already validated as non-null
-
- int entryIndex = FindEntry(key, out object? secondary);
- value = Unsafe.As<TValue>(secondary);
- return entryIndex != -1;
- }
-
- /// <summary>
- /// Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.").
- /// Must hold _lock, or be prepared to retry the search while holding _lock.
- /// </summary>
- internal int FindEntry(TKey key, out object? value)
- {
- Debug.Assert(key != null); // Key already validated as non-null.
-
- int hashCode = RuntimeHelpers.GetHashCode(key) & int.MaxValue;
- int bucket = hashCode & (_buckets.Length - 1);
- for (int entriesIndex = Volatile.Read(ref _buckets[bucket]); entriesIndex != -1; entriesIndex = _entries[entriesIndex].Next)
- {
- if (_entries[entriesIndex].HashCode == hashCode && _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out value) == key)
- {
- GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
- return entriesIndex;
- }
- }
-
- GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
- value = null;
- return -1;
- }
-
- /// <summary>Gets the entry at the specified entry index.</summary>
- internal bool TryGetEntry(int index, [NotNullWhen(true)] out TKey? key, [MaybeNullWhen(false)] out TValue value)
- {
- if (index < _entries.Length)
- {
- object? oKey = _entries[index].depHnd.GetPrimaryAndSecondary(out object? oValue);
- GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
-
- if (oKey != null)
- {
- key = Unsafe.As<TKey>(oKey);
- value = Unsafe.As<TValue>(oValue);
- return true;
- }
- }
-
- key = default;
- value = default!;
- return false;
- }
-
- /// <summary>Removes all of the keys in the table.</summary>
- internal void RemoveAllKeys()
- {
- for (int i = 0; i < _firstFreeEntry; i++)
- {
- RemoveIndex(i);
- }
- }
-
- /// <summary>Removes the specified key from the table, if it exists.</summary>
- internal bool Remove(TKey key)
- {
- VerifyIntegrity();
-
- int entryIndex = FindEntry(key, out _);
- if (entryIndex != -1)
- {
- RemoveIndex(entryIndex);
- return true;
- }
-
- return false;
- }
-
- private void RemoveIndex(int entryIndex)
- {
- Debug.Assert(entryIndex >= 0 && entryIndex < _firstFreeEntry);
-
- ref Entry entry = ref _entries[entryIndex];
-
- // We do not free the handle here, as we may be racing with readers who already saw the hash code.
- // Instead, we simply overwrite the entry's hash code, so subsequent reads will ignore it.
- // The handle will be free'd in Container's finalizer, after the table is resized or discarded.
- Volatile.Write(ref entry.HashCode, -1);
-
- // Also, clear the key to allow GC to collect objects pointed to by the entry
- entry.depHnd.SetPrimary(null);
- }
-
- internal void UpdateValue(int entryIndex, TValue newValue)
- {
- Debug.Assert(entryIndex != -1);
-
- VerifyIntegrity();
- _invalid = true;
-
- _entries[entryIndex].depHnd.SetSecondary(newValue);
-
- _invalid = false;
- }
-
- /// <summary>Resize, and scrub expired keys off bucket lists. Must hold _lock.</summary>
- /// <remarks>
- /// _firstEntry is less than _entries.Length on exit, that is, the table has at least one free entry.
- /// </remarks>
- internal Container Resize()
- {
- Debug.Assert(!HasCapacity);
-
- bool hasExpiredEntries = false;
- int newSize = _buckets.Length;
-
- if (_parent is null || _parent._activeEnumeratorRefCount == 0)
- {
- // If any expired or removed keys exist, we won't resize.
- // If there any active enumerators, though, we don't want
- // to compact and thus have no expired entries.
- for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
- {
- ref Entry entry = ref _entries[entriesIndex];
-
- if (entry.HashCode == -1)
- {
- // the entry was removed
- hasExpiredEntries = true;
- break;
- }
-
- if (entry.depHnd.IsAllocated && entry.depHnd.GetPrimary() is null)
- {
- // the entry has expired
- hasExpiredEntries = true;
- break;
- }
- }
- }
-
- if (!hasExpiredEntries)
- {
- // Not necessary to check for overflow here, the attempt to allocate new arrays will throw
- newSize = _buckets.Length * 2;
- }
-
- return Resize(newSize);
- }
-
- internal Container Resize(int newSize)
- {
- Debug.Assert(newSize >= _buckets.Length);
- Debug.Assert(IsPowerOfTwo(newSize));
-
- // Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
- // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
- int[] newBuckets = new int[newSize];
- for (int bucketIndex = 0; bucketIndex < newBuckets.Length; bucketIndex++)
- {
- newBuckets[bucketIndex] = -1;
- }
- Entry[] newEntries = new Entry[newSize];
- int newEntriesIndex = 0;
- bool activeEnumerators = _parent != null && _parent._activeEnumeratorRefCount > 0;
-
- // Migrate existing entries to the new table.
- if (activeEnumerators)
- {
- // There's at least one active enumerator, which means we don't want to
- // remove any expired/removed entries, in order to not affect existing
- // entries indices. Copy over the entries while rebuilding the buckets list,
- // as the buckets are dependent on the buckets list length, which is changing.
- for (; newEntriesIndex < _entries.Length; newEntriesIndex++)
- {
- ref Entry oldEntry = ref _entries[newEntriesIndex];
- ref Entry newEntry = ref newEntries[newEntriesIndex];
- int hashCode = oldEntry.HashCode;
-
- newEntry.HashCode = hashCode;
- newEntry.depHnd = oldEntry.depHnd;
- int bucket = hashCode & (newBuckets.Length - 1);
- newEntry.Next = newBuckets[bucket];
- newBuckets[bucket] = newEntriesIndex;
- }
- }
- else
- {
- // There are no active enumerators, which means we want to compact by
- // removing expired/removed entries.
- for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
- {
- ref Entry oldEntry = ref _entries[entriesIndex];
- int hashCode = oldEntry.HashCode;
- DependentHandle depHnd = oldEntry.depHnd;
- if (hashCode != -1 && depHnd.IsAllocated)
- {
- if (depHnd.GetPrimary() != null)
- {
- ref Entry newEntry = ref newEntries[newEntriesIndex];
-
- // Entry is used and has not expired. Link it into the appropriate bucket list.
- newEntry.HashCode = hashCode;
- newEntry.depHnd = depHnd;
- int bucket = hashCode & (newBuckets.Length - 1);
- newEntry.Next = newBuckets[bucket];
- newBuckets[bucket] = newEntriesIndex;
- newEntriesIndex++;
- }
- else
- {
- // Pretend the item was removed, so that this container's finalizer
- // will clean up this dependent handle.
- Volatile.Write(ref oldEntry.HashCode, -1);
- }
- }
- }
- }
-
- // Create the new container. We want to transfer the responsibility of freeing the handles from
- // the old container to the new container, and also ensure that the new container isn't finalized
- // while the old container may still be in use. As such, we store a reference from the old container
- // to the new one, which will keep the new container alive as long as the old one is.
- var newContainer = new Container(_parent!, newBuckets, newEntries, newEntriesIndex);
- if (activeEnumerators)
- {
- // If there are active enumerators, both the old container and the new container may be storing
- // the same entries with -1 hash codes, which the finalizer will clean up even if the container
- // is not the active container for the table. To prevent that, we want to stop the old container
- // from being finalized, as it no longer has any responsibility for any cleanup.
- GC.SuppressFinalize(this);
- }
- _oldKeepAlive = newContainer; // once this is set, the old container's finalizer will not free transferred dependent handles
-
- GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
-
- return newContainer;
- }
-
- private void VerifyIntegrity()
- {
- if (_invalid)
- {
- throw new InvalidOperationException(SR.InvalidOperation_CollectionCorrupted);
- }
- }
-
- ~Container()
- {
- // Skip doing anything if the container is invalid, including if somehow
- // the container object was allocated but its associated table never set.
- if (_invalid || _parent is null)
- {
- return;
- }
-
- // It's possible that the ConditionalWeakTable could have been resurrected, in which case code could
- // be accessing this Container as it's being finalized. We don't support usage after finalization,
- // but we also don't want to potentially corrupt state by allowing dependency handles to be used as
- // or after they've been freed. To avoid that, if it's at all possible that another thread has a
- // reference to this container via the CWT, we remove such a reference and then re-register for
- // finalization: the next time around, we can be sure that no references remain to this and we can
- // clean up the dependency handles without fear of corruption.
- if (!_finalized)
- {
- _finalized = true;
- lock (_parent._lock)
- {
- if (_parent._container == this)
- {
- _parent._container = null!;
- }
- }
- GC.ReRegisterForFinalize(this); // next time it's finalized, we'll be sure there are no remaining refs
- return;
- }
-
- Entry[] entries = _entries;
- _invalid = true;
- _entries = null!;
- _buckets = null!;
-
- if (entries != null)
- {
- for (int entriesIndex = 0; entriesIndex < entries.Length; entriesIndex++)
- {
- // We need to free handles in two cases:
- // - If this container still owns the dependency handle (meaning ownership hasn't been transferred
- // to another container that replaced this one), then it should be freed.
- // - If this container had the entry removed, then even if in general ownership was transferred to
- // another container, removed entries are not, therefore this container must free them.
- if (_oldKeepAlive is null || entries[entriesIndex].HashCode == -1)
- {
- entries[entriesIndex].depHnd.Free();
- }
- }
- }
- }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredAsyncDisposable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredAsyncDisposable.cs
deleted file mode 100644
index aa5e882dc65..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredAsyncDisposable.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides a type that can be used to configure how awaits on an <see cref="IAsyncDisposable"/> are performed.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredAsyncDisposable
- {
- private readonly IAsyncDisposable _source;
- private readonly bool _continueOnCapturedContext;
-
- internal ConfiguredAsyncDisposable(IAsyncDisposable source, bool continueOnCapturedContext)
- {
- _source = source;
- _continueOnCapturedContext = continueOnCapturedContext;
- }
-
- public ConfiguredValueTaskAwaitable DisposeAsync() =>
- // as with other "configured" awaitable-related type in CompilerServices, we don't null check to defend against
- // misuse like `default(ConfiguredAsyncDisposable).DisposeAsync()`, which will null ref by design.
- _source.DisposeAsync().ConfigureAwait(_continueOnCapturedContext);
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredCancelableAsyncEnumerable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredCancelableAsyncEnumerable.cs
deleted file mode 100644
index 4f1bca71695..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredCancelableAsyncEnumerable.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides an awaitable async enumerable that enables cancelable iteration and configured awaits.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredCancelableAsyncEnumerable<T>
- {
- private readonly IAsyncEnumerable<T> _enumerable;
- private readonly CancellationToken _cancellationToken;
- private readonly bool _continueOnCapturedContext;
-
- internal ConfiguredCancelableAsyncEnumerable(IAsyncEnumerable<T> enumerable, bool continueOnCapturedContext, CancellationToken cancellationToken)
- {
- _enumerable = enumerable;
- _continueOnCapturedContext = continueOnCapturedContext;
- _cancellationToken = cancellationToken;
- }
-
- /// <summary>Configures how awaits on the tasks returned from an async iteration will be performed.</summary>
- /// <param name="continueOnCapturedContext">Whether to capture and marshal back to the current context.</param>
- /// <returns>The configured enumerable.</returns>
- /// <remarks>This will replace any previous value set by <see cref="ConfigureAwait(bool)"/> for this iteration.</remarks>
- public ConfiguredCancelableAsyncEnumerable<T> ConfigureAwait(bool continueOnCapturedContext) =>
- new ConfiguredCancelableAsyncEnumerable<T>(_enumerable, continueOnCapturedContext, _cancellationToken);
-
- /// <summary>Sets the <see cref="CancellationToken"/> to be passed to <see cref="IAsyncEnumerable{T}.GetAsyncEnumerator(CancellationToken)"/> when iterating.</summary>
- /// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
- /// <returns>The configured enumerable.</returns>
- /// <remarks>This will replace any previous <see cref="CancellationToken"/> set by <see cref="WithCancellation(CancellationToken)"/> for this iteration.</remarks>
- public ConfiguredCancelableAsyncEnumerable<T> WithCancellation(CancellationToken cancellationToken) =>
- new ConfiguredCancelableAsyncEnumerable<T>(_enumerable, _continueOnCapturedContext, cancellationToken);
-
- public Enumerator GetAsyncEnumerator() =>
- // as with other "configured" awaitable-related type in CompilerServices, we don't null check to defend against
- // misuse like `default(ConfiguredCancelableAsyncEnumerable<T>).GetAsyncEnumerator()`, which will null ref by design.
- new Enumerator(_enumerable.GetAsyncEnumerator(_cancellationToken), _continueOnCapturedContext);
-
- /// <summary>Provides an awaitable async enumerator that enables cancelable iteration and configured awaits.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct Enumerator
- {
- private readonly IAsyncEnumerator<T> _enumerator;
- private readonly bool _continueOnCapturedContext;
-
- internal Enumerator(IAsyncEnumerator<T> enumerator, bool continueOnCapturedContext)
- {
- _enumerator = enumerator;
- _continueOnCapturedContext = continueOnCapturedContext;
- }
-
- /// <summary>Advances the enumerator asynchronously to the next element of the collection.</summary>
- /// <returns>
- /// A <see cref="ConfiguredValueTaskAwaitable{Boolean}"/> that will complete with a result of <c>true</c>
- /// if the enumerator was successfully advanced to the next element, or <c>false</c> if the enumerator has
- /// passed the end of the collection.
- /// </returns>
- public ConfiguredValueTaskAwaitable<bool> MoveNextAsync() =>
- _enumerator.MoveNextAsync().ConfigureAwait(_continueOnCapturedContext);
-
- /// <summary>Gets the element in the collection at the current position of the enumerator.</summary>
- public T Current => _enumerator.Current;
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or
- /// resetting unmanaged resources asynchronously.
- /// </summary>
- public ConfiguredValueTaskAwaitable DisposeAsync() =>
- _enumerator.DisposeAsync().ConfigureAwait(_continueOnCapturedContext);
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
deleted file mode 100644
index 493269218df..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Threading.Tasks.Sources;
-
-#if !NETSTANDARD2_0
-using Internal.Runtime.CompilerServices;
-#endif
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides an awaitable type that enables configured awaits on a <see cref="ValueTask"/>.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredValueTaskAwaitable
- {
- /// <summary>The wrapped <see cref="Task"/>.</summary>
- private readonly ValueTask _value;
-
- /// <summary>Initializes the awaitable.</summary>
- /// <param name="value">The wrapped <see cref="ValueTask"/>.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ConfiguredValueTaskAwaitable(in ValueTask value) => _value = value;
-
- /// <summary>Returns an awaiter for this <see cref="ConfiguredValueTaskAwaitable"/> instance.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ConfiguredValueTaskAwaiter GetAwaiter() => new ConfiguredValueTaskAwaiter(in _value);
-
- /// <summary>Provides an awaiter for a <see cref="ConfiguredValueTaskAwaitable"/>.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter
- {
- /// <summary>The value being awaited.</summary>
- private readonly ValueTask _value;
-
- /// <summary>Initializes the awaiter.</summary>
- /// <param name="value">The value to be awaited.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ConfiguredValueTaskAwaiter(in ValueTask value) => _value = value;
-
- /// <summary>Gets whether the <see cref="ConfiguredValueTaskAwaitable"/> has completed.</summary>
- public bool IsCompleted
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _value.IsCompleted;
- }
-
- /// <summary>Gets the result of the ValueTask.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void GetResult() => _value.ThrowIfCompletedUnsuccessfully();
-
- /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable"/>.</summary>
- public void OnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- t.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token,
- ValueTaskSourceOnCompletedFlags.FlowExecutionContext |
- (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None));
- }
- else
- {
- ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
- }
- }
-
- /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable"/>.</summary>
- public void UnsafeOnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- t.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token,
- _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
- }
- else
- {
- ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
- }
- }
-
- void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox box)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- TaskAwaiter.UnsafeOnCompletedInternal(t, box, _value._continueOnCapturedContext);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token,
- _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
- }
- else
- {
- TaskAwaiter.UnsafeOnCompletedInternal(Task.CompletedTask, box, _value._continueOnCapturedContext);
- }
- }
- }
- }
-
- /// <summary>Provides an awaitable type that enables configured awaits on a <see cref="ValueTask{TResult}"/>.</summary>
- /// <typeparam name="TResult">The type of the result produced.</typeparam>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredValueTaskAwaitable<TResult>
- {
- /// <summary>The wrapped <see cref="ValueTask{TResult}"/>.</summary>
- private readonly ValueTask<TResult> _value;
-
- /// <summary>Initializes the awaitable.</summary>
- /// <param name="value">The wrapped <see cref="ValueTask{TResult}"/>.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ConfiguredValueTaskAwaitable(in ValueTask<TResult> value) => _value = value;
-
- /// <summary>Returns an awaiter for this <see cref="ConfiguredValueTaskAwaitable{TResult}"/> instance.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ConfiguredValueTaskAwaiter GetAwaiter() => new ConfiguredValueTaskAwaiter(in _value);
-
- /// <summary>Provides an awaiter for a <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
- [StructLayout(LayoutKind.Auto)]
- public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter
- {
- /// <summary>The value being awaited.</summary>
- private readonly ValueTask<TResult> _value;
-
- /// <summary>Initializes the awaiter.</summary>
- /// <param name="value">The value to be awaited.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ConfiguredValueTaskAwaiter(in ValueTask<TResult> value) => _value = value;
-
- /// <summary>Gets whether the <see cref="ConfiguredValueTaskAwaitable{TResult}"/> has completed.</summary>
- public bool IsCompleted
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _value.IsCompleted;
- }
-
- /// <summary>Gets the result of the ValueTask.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public TResult GetResult() => _value.Result;
-
- /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
- public void OnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- t.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token,
- ValueTaskSourceOnCompletedFlags.FlowExecutionContext |
- (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None));
- }
- else
- {
- ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
- }
- }
-
- /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
- public void UnsafeOnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- t.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token,
- _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
- }
- else
- {
- ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
- }
- }
-
- void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox box)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- TaskAwaiter.UnsafeOnCompletedInternal(t, box, _value._continueOnCapturedContext);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token,
- _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
- }
- else
- {
- TaskAwaiter.UnsafeOnCompletedInternal(Task.CompletedTask, box, _value._continueOnCapturedContext);
- }
- }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ContractHelper.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ContractHelper.cs
deleted file mode 100644
index 5adf4471e8f..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ContractHelper.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#define DEBUG // The behavior of this contract library should be consistent regardless of build type.
-
-using System.Diagnostics.Contracts;
-
-namespace System.Runtime.CompilerServices
-{
- public static class ContractHelper
- {
- /// <summary>
- /// Allows a managed application environment such as an interactive interpreter (IronPython) or a
- /// web browser host (Jolt hosting Silverlight in IE) to be notified of contract failures and
- /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the
- /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will
- /// not pop up an assert dialog box or trigger escalation policy.
- /// </summary>
- internal static event EventHandler<ContractFailedEventArgs>? InternalContractFailed;
-
- /// <summary>
- /// Rewriter will call this method on a contract failure to allow listeners to be notified.
- /// The method should not perform any failure (assert/throw) itself.
- /// This method has 3 functions:
- /// 1. Call any contract hooks (such as listeners to Contract failed events)
- /// 2. Determine if the listeners deem the failure as handled (then resultFailureMessage should be set to null)
- /// 3. Produce a localized resultFailureMessage used in advertising the failure subsequently.
- /// On exit: null if the event was handled and should not trigger a failure.
- /// Otherwise, returns the localized failure message.
- /// </summary>
- [System.Diagnostics.DebuggerNonUserCode]
- public static string? RaiseContractFailedEvent(ContractFailureKind failureKind, string? userMessage, string? conditionText, Exception? innerException)
- {
- if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume)
- throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, failureKind), nameof(failureKind));
-
- string? returnValue;
- string displayMessage = "contract failed."; // Incomplete, but in case of OOM during resource lookup...
- ContractFailedEventArgs? eventArgs = null; // In case of OOM.
-
- try
- {
- displayMessage = GetDisplayMessage(failureKind, userMessage, conditionText);
- EventHandler<ContractFailedEventArgs>? contractFailedEventLocal = InternalContractFailed;
- if (contractFailedEventLocal != null)
- {
- eventArgs = new ContractFailedEventArgs(failureKind, displayMessage, conditionText, innerException);
- foreach (EventHandler<ContractFailedEventArgs> handler in contractFailedEventLocal.GetInvocationList())
- {
- try
- {
- handler(null, eventArgs);
- }
- catch (Exception e)
- {
- eventArgs.thrownDuringHandler = e;
- eventArgs.SetUnwind();
- }
- }
- if (eventArgs.Unwind)
- {
- // unwind
- innerException ??= eventArgs.thrownDuringHandler;
- throw new ContractException(failureKind, displayMessage, userMessage, conditionText, innerException);
- }
- }
- }
- finally
- {
- if (eventArgs != null && eventArgs.Handled)
- {
- returnValue = null; // handled
- }
- else
- {
- returnValue = displayMessage;
- }
- }
-
- return returnValue;
- }
-
- /// <summary>
- /// Rewriter calls this method to get the default failure behavior.
- /// </summary>
- [System.Diagnostics.DebuggerNonUserCode]
- public static void TriggerFailure(ContractFailureKind kind, string? displayMessage, string? userMessage, string? conditionText, Exception? innerException)
- {
- if (string.IsNullOrEmpty(displayMessage))
- {
- displayMessage = GetDisplayMessage(kind, userMessage, conditionText);
- }
-
- System.Diagnostics.Debug.ContractFailure(displayMessage, string.Empty, GetFailureMessage(kind, null));
- }
-
- private static string GetFailureMessage(ContractFailureKind failureKind, string? conditionText)
- {
- bool hasConditionText = !string.IsNullOrEmpty(conditionText);
- switch (failureKind)
- {
- case ContractFailureKind.Assert:
- return hasConditionText ? SR.Format(SR.AssertionFailed_Cnd, conditionText) : SR.AssertionFailed;
-
- case ContractFailureKind.Assume:
- return hasConditionText ? SR.Format(SR.AssumptionFailed_Cnd, conditionText) : SR.AssumptionFailed;
-
- case ContractFailureKind.Precondition:
- return hasConditionText ? SR.Format(SR.PreconditionFailed_Cnd, conditionText) : SR.PreconditionFailed;
-
- case ContractFailureKind.Postcondition:
- return hasConditionText ? SR.Format(SR.PostconditionFailed_Cnd, conditionText) : SR.PostconditionFailed;
-
- case ContractFailureKind.Invariant:
- return hasConditionText ? SR.Format(SR.InvariantFailed_Cnd, conditionText) : SR.InvariantFailed;
-
- case ContractFailureKind.PostconditionOnException:
- return hasConditionText ? SR.Format(SR.PostconditionOnExceptionFailed_Cnd, conditionText) : SR.PostconditionOnExceptionFailed;
-
- default:
- Contract.Assume(false, "Unreachable code");
- return SR.AssumptionFailed;
- }
- }
-
- private static string GetDisplayMessage(ContractFailureKind failureKind, string? userMessage, string? conditionText)
- {
- string failureMessage;
- // Well-formatted English messages will take one of four forms. A sentence ending in
- // either a period or a colon, the condition string, then the message tacked
- // on to the end with two spaces in front.
- // Note that both the conditionText and userMessage may be null. Also,
- // on Silverlight we may not be able to look up a friendly string for the
- // error message. Let's leverage Silverlight's default error message there.
- if (!string.IsNullOrEmpty(conditionText))
- {
- failureMessage = GetFailureMessage(failureKind, conditionText);
- }
- else
- {
- failureMessage = "";
- }
-
- // Now add in the user message, if present.
- if (!string.IsNullOrEmpty(userMessage))
- {
- return failureMessage + " " + userMessage;
- }
- else
- {
- return failureMessage;
- }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CustomConstantAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CustomConstantAttribute.cs
deleted file mode 100644
index f3db0a276b5..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/CustomConstantAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
- public abstract class CustomConstantAttribute : Attribute
- {
- public abstract object? Value { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
deleted file mode 100644
index 315e9e3b938..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
- public sealed class DateTimeConstantAttribute : CustomConstantAttribute
- {
- private readonly DateTime _date;
-
- public DateTimeConstantAttribute(long ticks)
- {
- _date = new DateTime(ticks);
- }
-
-#pragma warning disable CS8608
- public override object Value => _date;
-#pragma warning restore CS8608
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DecimalConstantAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
deleted file mode 100644
index 7aea9e6cc78..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// Note: If you add a new ctor overloads you need to update ParameterInfo.RawDefaultValue
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
- public sealed class DecimalConstantAttribute : Attribute
- {
- private readonly decimal _dec;
-
- [CLSCompliant(false)]
- public DecimalConstantAttribute(
- byte scale,
- byte sign,
- uint hi,
- uint mid,
- uint low
- )
- {
- _dec = new decimal((int)low, (int)mid, (int)hi, sign != 0, scale);
- }
-
- public DecimalConstantAttribute(
- byte scale,
- byte sign,
- int hi,
- int mid,
- int low
- )
- {
- _dec = new decimal(low, mid, hi, sign != 0, scale);
- }
-
- public decimal Value => _dec;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs
deleted file mode 100644
index 31abdcbb3ec..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly)]
- public sealed class DefaultDependencyAttribute : Attribute
- {
- public DefaultDependencyAttribute(LoadHint loadHintArgument)
- {
- LoadHint = loadHintArgument;
- }
-
- public LoadHint LoadHint { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs
deleted file mode 100644
index 5b589fbde82..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
- public sealed class DependencyAttribute : Attribute
- {
- public DependencyAttribute(string dependentAssemblyArgument, LoadHint loadHintArgument)
- {
- DependentAssembly = dependentAssemblyArgument;
- LoadHint = loadHintArgument;
- }
-
- public string DependentAssembly { get; }
- public LoadHint LoadHint { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
deleted file mode 100644
index dfe4a98a949..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
- public sealed class DisablePrivateReflectionAttribute : Attribute
- {
- public DisablePrivateReflectionAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs
deleted file mode 100644
index 4a860b15878..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // Custom attribute to indicating a TypeDef is a discardable attribute.
- [AttributeUsage(AttributeTargets.All)]
- public class DiscardableAttribute : Attribute
- {
- public DiscardableAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs
deleted file mode 100644
index d971d633ef3..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Indicates that a method is an extension method, or that a class or assembly contains extension methods.
- /// </summary>
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
- public sealed class ExtensionAttribute : Attribute { }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
deleted file mode 100644
index 1810340f545..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field)]
- public sealed class FixedAddressValueTypeAttribute : Attribute
- {
- public FixedAddressValueTypeAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs
deleted file mode 100644
index 2215606c19d..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-** Purpose: Used by a compiler for generating value types
-** in-place within other value types containing a certain
-** number of elements of the given (primitive) type. Somewhat
-** similar to P/Invoke's ByValTStr attribute.
-** Used by C# with this syntax: "fixed int buffer[10];"
-**
-===========================================================*/
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field, Inherited = false)]
- public sealed class FixedBufferAttribute : Attribute
- {
- public FixedBufferAttribute(Type elementType, int length)
- {
- ElementType = elementType;
- Length = length;
- }
-
- public Type ElementType { get; }
- public int Length { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs
deleted file mode 100644
index c08ebaee061..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-** Purpose: implementation of the FormattableStringFactory
-** class.
-**
-===========================================================*/
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// A factory type used by compilers to create instances of the type <see cref="FormattableString"/>.
- /// </summary>
- public static class FormattableStringFactory
- {
- /// <summary>
- /// Create a <see cref="FormattableString"/> from a composite format string and object
- /// array containing zero or more objects to format.
- /// </summary>
- public static FormattableString Create(string format, params object?[] arguments)
- {
- if (format == null)
- {
- throw new ArgumentNullException(nameof(format));
- }
-
- if (arguments == null)
- {
- throw new ArgumentNullException(nameof(arguments));
- }
-
- return new ConcreteFormattableString(format, arguments);
- }
-
- private sealed class ConcreteFormattableString : FormattableString
- {
- private readonly string _format;
- private readonly object?[] _arguments;
-
- internal ConcreteFormattableString(string format, object?[] arguments)
- {
- _format = format;
- _arguments = arguments;
- }
-
- public override string Format => _format;
- public override object?[] GetArguments() { return _arguments; }
- public override int ArgumentCount => _arguments.Length;
- public override object? GetArgument(int index) { return _arguments[index]; }
- public override string ToString(IFormatProvider? formatProvider) { return string.Format(formatProvider, _format, _arguments); }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs
deleted file mode 100644
index 7fb7ea53952..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// Represents state machines generated for asynchronous methods.
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Represents state machines generated for asynchronous methods.
- /// This type is intended for compiler use only.
- /// </summary>
- public interface IAsyncStateMachine
- {
- /// <summary>Moves the state machine to its next state.</summary>
- void MoveNext();
- /// <summary>Configures the state machine with a heap-allocated replica.</summary>
- /// <param name="stateMachine">The heap-allocated replica.</param>
- void SetStateMachine(IAsyncStateMachine stateMachine);
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachineBox.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachineBox.cs
deleted file mode 100644
index bb09d35dd7d..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IAsyncStateMachineBox.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// An interface implemented by all <see cref="AsyncTaskMethodBuilder{TResult}.AsyncStateMachineBox{TStateMachine}"/> instances, regardless of generics.
- /// </summary>
- internal interface IAsyncStateMachineBox
- {
- /// <summary>Move the state machine forward.</summary>
- void MoveNext();
-
- /// <summary>
- /// Gets an action for moving forward the contained state machine.
- /// This will lazily-allocate the delegate as needed.
- /// </summary>
- Action MoveNextAction { get; }
-
- /// <summary>Gets the state machine as a boxed object. This should only be used for debugging purposes.</summary>
- IAsyncStateMachine GetStateMachineObject();
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ICastable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ICastable.cs
deleted file mode 100644
index 7320c2d0840..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ICastable.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics.CodeAnalysis;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Support for dynamic interface casting. Specifically implementing this interface on a type will allow the
- /// type to support interfaces (for the purposes of casting and interface dispatch) that do not appear in its
- /// interface map.
- /// </summary>
- public interface ICastable
- {
- // This is called if casting this object to the given interface type would otherwise fail. Casting
- // here means the IL isinst and castclass instructions in the case where they are given an interface
- // type as the target type.
- //
- // A return value of true indicates the cast is valid.
- //
- // If false is returned when this is called as part of a castclass then the usual InvalidCastException
- // will be thrown unless an alternate exception is assigned to the castError output parameter. This
- // parameter is ignored on successful casts or during the evaluation of an isinst (which returns null
- // rather than throwing on error).
- //
- // No exception should be thrown from this method (it will cause unpredictable effects, including the
- // possibility of an immediate failfast).
- //
- // The results of this call are not cached, so it is advisable to provide a performant implementation.
- //
- // The results of this call should be invariant for the same class, interface type pair. That is
- // because this is the only guard placed before an interface invocation at runtime. If a type decides
- // it no longer wants to implement a given interface it has no way to synchronize with callers that
- // have already cached this relationship and can invoke directly via the interface pointer.
- bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, [NotNullWhen(true)] out Exception? castError);
-
- // This is called as part of the interface dispatch mechanism when the dispatcher logic cannot find
- // the given interface type in the interface map of this object.
- //
- // It allows the implementor to return an alternate class type which does implement the interface. The
- // interface lookup shall be performed again on this type (failure to find the interface this time
- // resulting in a fail fast) and the corresponding implemented method on that class called instead.
- //
- // Naturally, since the call is dispatched to a method on a class which does not match the type of the
- // this pointer, extreme care must be taken in the implementation of the interface methods of this
- // surrogate type.
- //
- // No exception should be thrown from this method (it will cause unpredictable effects, including the
- // possibility of an immediate failfast).
- //
- // There is no error path defined here. By construction all interface dispatches will already have
- // been verified via the castclass/isinst mechanism (and thus a call to IsInstanceOfInterface above)
- // so this method is expected to succeed in all cases. The contract for interface dispatch does not
- // include any errors from the infrastructure, of which this is a part.
- //
- // The results of this lookup are cached so computation of the result is not as perf-sensitive as
- // IsInstanceOfInterface.
- RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType);
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs
deleted file mode 100644
index 24f4f45cbea..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
-//
-//
-//
-// Interfaces used to represent instances that notify listeners of their completion via continuations.
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Represents an operation that will schedule continuations when the operation completes.
- /// </summary>
- public interface INotifyCompletion
- {
- /// <summary>Schedules the continuation action to be invoked when the instance completes.</summary>
- /// <param name="continuation">The action to invoke when the operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- void OnCompleted(Action continuation);
- }
-
- /// <summary>
- /// Represents an awaiter used to schedule continuations when an await operation completes.
- /// </summary>
- public interface ICriticalNotifyCompletion : INotifyCompletion
- {
- /// <summary>Schedules the continuation action to be invoked when the instance completes.</summary>
- /// <param name="continuation">The action to invoke when the operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <remarks>Unlike OnCompleted, UnsafeOnCompleted need not propagate ExecutionContext information.</remarks>
- void UnsafeOnCompleted(Action continuation);
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ITuple.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ITuple.cs
deleted file mode 100644
index 55b948b3e37..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ITuple.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// This interface is required for types that want to be indexed into by dynamic patterns.
- /// </summary>
- public interface ITuple
- {
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int Length { get; }
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object? this[int index] { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs
deleted file mode 100644
index bc76250adc8..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Property, Inherited = true)]
- public sealed class IndexerNameAttribute : Attribute
- {
- public IndexerNameAttribute(string indexerName)
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
deleted file mode 100644
index 0967b96c1b2..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
- public sealed class InternalsVisibleToAttribute : Attribute
- {
- public InternalsVisibleToAttribute(string assemblyName)
- {
- AssemblyName = assemblyName;
- }
-
- public string AssemblyName { get; }
- public bool AllInternalsVisible { get; set; } = true;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs
deleted file mode 100644
index 6bdd91d8448..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // Calls to methods or references to fields marked with this attribute may be replaced at
- // some call sites with jit intrinsic expansions.
- // Types marked with this attribute may be specially treated by the runtime/compiler.
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
- internal sealed class IntrinsicAttribute : Attribute
- {
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsByRefLikeAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsByRefLikeAttribute.cs
deleted file mode 100644
index 90e49d2a425..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsByRefLikeAttribute.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.ComponentModel;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Reserved to be used by the compiler for tracking metadata.
- /// This attribute should not be used by developers in source code.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- [AttributeUsage(AttributeTargets.Struct)]
- public sealed class IsByRefLikeAttribute : Attribute
- {
- public IsByRefLikeAttribute()
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsConst.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsConst.cs
deleted file mode 100644
index 7f948b608a1..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsConst.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- public static partial class IsConst
- {
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsReadOnlyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsReadOnlyAttribute.cs
deleted file mode 100644
index 657df43957f..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsReadOnlyAttribute.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.ComponentModel;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Reserved to be used by the compiler for tracking metadata.
- /// This attribute should not be used by developers in source code.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- [AttributeUsage(AttributeTargets.All, Inherited = false)]
- public sealed class IsReadOnlyAttribute : Attribute
- {
- public IsReadOnlyAttribute()
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsVolatile.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsVolatile.cs
deleted file mode 100644
index 58aaebc8d1a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IsVolatile.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- public static class IsVolatile
- {
- // no instantiation, please!
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
deleted file mode 100644
index 53afc956643..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public sealed class IteratorStateMachineAttribute : StateMachineAttribute
- {
- public IteratorStateMachineAttribute(Type stateMachineType)
- : base(stateMachineType)
- {
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/LoadHint.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/LoadHint.cs
deleted file mode 100644
index fa490c2c9bb..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/LoadHint.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- public enum LoadHint
- {
- Default = 0x0000, // No preference specified
- Always = 0x0001, // Dependency is always loaded
- Sometimes = 0x0002, // Dependency is sometimes loaded
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodCodeType.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodCodeType.cs
deleted file mode 100644
index 841b6661989..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodCodeType.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Reflection;
-
-namespace System.Runtime.CompilerServices
-{
- public enum MethodCodeType
- {
- IL = MethodImplAttributes.IL,
- Native = MethodImplAttributes.Native,
- OPTIL = MethodImplAttributes.OPTIL,
- Runtime = MethodImplAttributes.Runtime
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplAttribute.cs
deleted file mode 100644
index 18900b37bea..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplAttribute.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // Custom attribute to specify additional method properties.
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
- public sealed class MethodImplAttribute : Attribute
- {
- public MethodCodeType MethodCodeType;
-
- public MethodImplAttribute(MethodImplOptions methodImplOptions)
- {
- Value = methodImplOptions;
- }
-
- public MethodImplAttribute(short value)
- {
- Value = (MethodImplOptions)value;
- }
-
- public MethodImplAttribute()
- {
- }
-
- public MethodImplOptions Value { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs
deleted file mode 100644
index 27757683511..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // This Enum matchs the miImpl flags defined in corhdr.h. It is used to specify
- // certain method properties.
- [Flags]
- public enum MethodImplOptions
- {
- Unmanaged = 0x0004,
- NoInlining = 0x0008,
- ForwardRef = 0x0010,
- Synchronized = 0x0020,
- NoOptimization = 0x0040,
- PreserveSig = 0x0080,
- AggressiveInlining = 0x0100,
- AggressiveOptimization = 0x0200,
- InternalCall = 0x1000
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/PreserveDependencyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/PreserveDependencyAttribute.cs
deleted file mode 100644
index de14ff35e04..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/PreserveDependencyAttribute.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-#nullable enable
-
-// TODO https://github.com/dotnet/corefx/issues/41201: Design and expose this publicly.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>States a dependency that one member has on another.</summary>
- /// <remarks>
- /// This can be used to inform tooling of a dependency that is otherwise not evident purely from
- /// metadata and IL, for example a member relied on via reflection.
- /// </remarks>
- [AttributeUsage(
- AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field /* AttributeTargets.Class | AttributeTargets.Struct */, // TODO: https://github.com/mono/linker/issues/797
- AllowMultiple = true, Inherited = false)]
- internal sealed class PreserveDependencyAttribute : Attribute
- {
- /// <summary>Initializes the attribute.</summary>
- /// <param name="memberSignature">The signature of the member depended.</param>
- public PreserveDependencyAttribute(string memberSignature)
- {
- MemberSignature = memberSignature;
- }
-
- /// <summary>Initializes the attribute.</summary>
- /// <param name="memberSignature">The signature of the member depended on.</param>
- /// <param name="typeName">The full name of the type containing <paramref name="memberSignature"/>.</param>
- public PreserveDependencyAttribute(string memberSignature, string typeName)
- {
- MemberSignature = memberSignature;
- TypeName = typeName;
- }
-
- /// <summary>Initializes the attribute.</summary>
- /// <param name="memberSignature">The signature of the member depended on.</param>
- /// <param name="typeName">The full name of the type containing <paramref name="memberSignature"/>.</param>
- /// <param name="assemblyName">The name of the assembly containing <paramref name="typeName"/>.</param>
- public PreserveDependencyAttribute(string memberSignature, string typeName, string assemblyName)
- {
- MemberSignature = memberSignature;
- TypeName = typeName;
- AssemblyName = assemblyName;
- }
-
- /// <summary>Gets the signature of the member depended on.</summary>
- public string MemberSignature { get; }
-
- /// <summary>Gets the full name of the type containing the specified member.</summary>
- /// <remarks>If no type name is specified, the type of the consumer is assumed.</remarks>
- public string? TypeName { get; }
-
- /// <summary>Gets the assembly name of the specified type.</summary>
- /// <remarks>If no assembly name is specified, the assembly of the consumer is assumed.</remarks>
- public string? AssemblyName { get; }
-
- /// <summary>Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG".</summary>
- public string? Condition { get; set; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
deleted file mode 100644
index e2c7cb47b4f..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Attribute: ReferenceAssemblyAttribute
-**
-** Purpose: Identifies an assembly as being a "reference
-** assembly", meaning it contains public surface area but
-** no usable implementation. Reference assemblies
-** should be loadable for introspection, but not execution.
-**
-============================================================*/
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
- public sealed class ReferenceAssemblyAttribute : Attribute
- {
- public ReferenceAssemblyAttribute()
- {
- }
-
- public ReferenceAssemblyAttribute(string? description)
- {
- Description = description;
- }
-
- public string? Description { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
deleted file mode 100644
index 609c5603300..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Mark up the program to indicate various legacy or new opt-in behaviors.
-**
-**
-=============================================================================*/
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
- public sealed class RuntimeCompatibilityAttribute : Attribute
- {
- public RuntimeCompatibilityAttribute()
- {
- // legacy behavior is the default, and WrapNonExceptionThrows is implicitly
- // false thanks to the CLR's guarantee of zeroed memory.
- }
-
- // If a non-CLSCompliant exception (i.e. one that doesn't derive from System.Exception) is
- // thrown, should it be wrapped up in a System.Runtime.CompilerServices.RuntimeWrappedException
- // instance when presented to catch handlers?
- public bool WrapNonExceptionThrows { get; set; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs
deleted file mode 100644
index b0cd9ddce26..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- public static partial class RuntimeFeature
- {
- /// <summary>
- /// Name of the Portable PDB feature.
- /// </summary>
- public const string PortablePdb = nameof(PortablePdb);
-
-#if FEATURE_DEFAULT_INTERFACES
- /// <summary>
- /// Indicates that this version of runtime supports default interface method implementations.
- /// </summary>
- public const string DefaultImplementationsOfInterfaces = nameof(DefaultImplementationsOfInterfaces);
-#endif
-
- /// <summary>
- /// Checks whether a certain feature is supported by the Runtime.
- /// </summary>
- public static bool IsSupported(string feature)
- {
- switch (feature)
- {
- case PortablePdb:
-#if FEATURE_DEFAULT_INTERFACES
- case DefaultImplementationsOfInterfaces:
-#endif
- return true;
- case nameof(IsDynamicCodeSupported):
- return IsDynamicCodeSupported;
- case nameof(IsDynamicCodeCompiled):
- return IsDynamicCodeCompiled;
- }
-
- return false;
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs
deleted file mode 100644
index cd2971f0350..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.Serialization;
-using System.Reflection;
-using Internal.Runtime.CompilerServices;
-
-namespace System.Runtime.CompilerServices
-{
- public static partial class RuntimeHelpers
- {
- public delegate void TryCode(object? userData);
-
- public delegate void CleanupCode(object? userData, bool exceptionThrown);
-
- /// <summary>
- /// Slices the specified array using the specified range.
- /// </summary>
- public static T[] GetSubArray<T>(T[] array, Range range)
- {
- if (array == null)
- {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
- }
-
- (int offset, int length) = range.GetOffsetAndLength(array.Length);
-
- if (default(T)! != null || typeof(T[]) == array.GetType()) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- // We know the type of the array to be exactly T[].
-
- if (length == 0)
- {
- return Array.Empty<T>();
- }
-
- var dest = new T[length];
- Buffer.Memmove(
- ref Unsafe.As<byte, T>(ref dest.GetRawSzArrayData()),
- ref Unsafe.Add(ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData()), offset),
- (uint)length);
- return dest;
- }
- else
- {
- // The array is actually a U[] where U:T.
- T[] dest = (T[])Array.CreateInstance(array.GetType().GetElementType()!, length);
- Array.Copy(array, offset, dest, 0, length);
- return dest;
- }
- }
-
- public static object GetUninitializedObject(Type type)
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type), SR.ArgumentNull_Type);
- }
-
- if (!type.IsRuntimeImplemented())
- {
- throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type.ToString()));
- }
-
- return GetUninitializedObjectInternal(type);
- }
-
- public static void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, object? userData)
- {
- if (code == null)
- throw new ArgumentNullException(nameof(code));
- if (backoutCode == null)
- throw new ArgumentNullException(nameof(backoutCode));
-
- bool exceptionThrown = true;
-
- try
- {
- code(userData);
- exceptionThrown = false;
- }
- finally
- {
- backoutCode(userData, exceptionThrown);
- }
- }
-
- public static void PrepareContractedDelegate(Delegate d)
- {
- }
-
- public static void ProbeForSufficientStack()
- {
- }
-
- public static void PrepareConstrainedRegions()
- {
- }
-
- public static void PrepareConstrainedRegionsNoOP()
- {
- }
-
- internal static bool IsPrimitiveType(this CorElementType et)
- // COR_ELEMENT_TYPE_I1,I2,I4,I8,U1,U2,U4,U8,R4,R8,I,U,CHAR,BOOLEAN
- => ((1 << (int)et) & 0b_0011_0000_0000_0011_1111_1111_1100) != 0;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs
deleted file mode 100644
index 65fd6d24e64..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.Serialization;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Exception used to wrap all non-CLS compliant exceptions.
- /// </summary>
- [Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public sealed class RuntimeWrappedException : Exception
- {
- private object _wrappedException; // EE expects this name
-
- // Not an api but has to be public as System.Linq.Expression invokes this through Reflection when an expression
- // throws an object that doesn't derive from Exception.
- public RuntimeWrappedException(object thrownObject)
- : base(SR.RuntimeWrappedException)
- {
- HResult = HResults.COR_E_RUNTIMEWRAPPED;
- _wrappedException = thrownObject;
- }
-
- private RuntimeWrappedException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- _wrappedException = info.GetValue("WrappedException", typeof(object))!;
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("WrappedException", _wrappedException, typeof(object));
- }
-
- public object WrappedException => _wrappedException;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs
deleted file mode 100644
index 4cd78621cb5..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Struct)]
- public sealed class SpecialNameAttribute : Attribute
- {
- public SpecialNameAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs
deleted file mode 100644
index d3522f5c470..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public class StateMachineAttribute : Attribute
- {
- public StateMachineAttribute(Type stateMachineType)
- {
- StateMachineType = stateMachineType;
- }
-
- public Type StateMachineType { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs
deleted file mode 100644
index 9d73197de42..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- // Custom attribute to indicate that strings should be frozen.
-
- [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
- public sealed class StringFreezingAttribute : Attribute
- {
- public StringFreezingAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StrongBox.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StrongBox.cs
deleted file mode 100644
index bdee5189b3c..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/StrongBox.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics.CodeAnalysis;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Holds a reference to a value.
- /// </summary>
- /// <typeparam name="T">The type of the value that the <see cref = "StrongBox{T}"></see> references.</typeparam>
- public class StrongBox<T> : IStrongBox
- {
- /// <summary>
- /// Gets the strongly typed value associated with the <see cref = "StrongBox{T}"></see>
- /// <remarks>This is explicitly exposed as a field instead of a property to enable loading the address of the field.</remarks>
- /// </summary>
- [MaybeNull] public T Value = default!;
-
- /// <summary>
- /// Initializes a new StrongBox which can receive a value when used in a reference call.
- /// </summary>
- public StrongBox()
- {
- }
-
- /// <summary>
- /// Initializes a new <see cref = "StrongBox{T}"></see> with the specified value.
- /// </summary>
- /// <param name="value">A value that the <see cref = "StrongBox{T}"></see> will reference.</param>
- public StrongBox(T value)
- {
- Value = value;
- }
-
- object? IStrongBox.Value
- {
- get => Value;
- set => Value = (T)value!;
- }
- }
-
- /// <summary>
- /// Defines a property for accessing the value that an object references.
- /// </summary>
- public interface IStrongBox
- {
- /// <summary>
- /// Gets or sets the value the object references.
- /// </summary>
- object? Value { get; set; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
deleted file mode 100644
index e9abf134be9..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module)]
- public sealed class SuppressIldasmAttribute : Attribute
- {
- public SuppressIldasmAttribute() { }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs
deleted file mode 100644
index f1c5b07071a..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TaskAwaiter.cs
+++ /dev/null
@@ -1,556 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// Types for awaiting Task and Task<T>. These types are emitted from Task{<T>}.GetAwaiter
-// and Task{<T>}.ConfigureAwait. They are meant to be used only by the compiler, e.g.
-//
-// await nonGenericTask;
-// =====================
-// var $awaiter = nonGenericTask.GetAwaiter();
-// if (!$awaiter.IsCompleted)
-// {
-// SPILL:
-// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
-// return;
-// Label:
-// UNSPILL;
-// }
-// $awaiter.GetResult();
-//
-// result += await genericTask.ConfigureAwait(false);
-// ===================================================================================
-// var $awaiter = genericTask.ConfigureAwait(false).GetAwaiter();
-// if (!$awaiter.IsCompleted)
-// {
-// SPILL;
-// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
-// return;
-// Label:
-// UNSPILL;
-// }
-// result += $awaiter.GetResult();
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Diagnostics.Tracing;
-using System.Runtime.ExceptionServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-// NOTE: For performance reasons, initialization is not verified. If a developer
-// incorrectly initializes a task awaiter, which should only be done by the compiler,
-// NullReferenceExceptions may be generated (the alternative would be for us to detect
-// this case and then throw a different exception instead). This is the same tradeoff
-// that's made with other compiler-focused value types like List<T>.Enumerator.
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct TaskAwaiter : ICriticalNotifyCompletion, ITaskAwaiter
- {
- // WARNING: Unsafe.As is used to access the generic TaskAwaiter<> as TaskAwaiter.
- // Its layout must remain the same.
-
- /// <summary>The task being awaited.</summary>
- internal readonly Task m_task;
-
- /// <summary>Initializes the <see cref="TaskAwaiter"/>.</summary>
- /// <param name="task">The <see cref="System.Threading.Tasks.Task"/> to be awaited.</param>
- internal TaskAwaiter(Task task)
- {
- Debug.Assert(task != null, "Constructing an awaiter requires a task to await.");
- m_task = task;
- }
-
- /// <summary>Gets whether the task being awaited is completed.</summary>
- /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted => m_task.IsCompleted;
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void OnCompleted(Action continuation)
- {
- OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void UnsafeOnCompleted(Action continuation)
- {
- OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
- }
-
- /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
- /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
- [StackTraceHidden]
- public void GetResult()
- {
- ValidateEnd(m_task);
- }
-
- /// <summary>
- /// Fast checks for the end of an await operation to determine whether more needs to be done
- /// prior to completing the await.
- /// </summary>
- /// <param name="task">The awaited task.</param>
- [StackTraceHidden]
- internal static void ValidateEnd(Task task)
- {
- // Fast checks that can be inlined.
- if (task.IsWaitNotificationEnabledOrNotRanToCompletion)
- {
- // If either the end await bit is set or we're not completed successfully,
- // fall back to the slower path.
- HandleNonSuccessAndDebuggerNotification(task);
- }
- }
-
- /// <summary>
- /// Ensures the task is completed, triggers any necessary debugger breakpoints for completing
- /// the await on the task, and throws an exception if the task did not complete successfully.
- /// </summary>
- /// <param name="task">The awaited task.</param>
- [StackTraceHidden]
- private static void HandleNonSuccessAndDebuggerNotification(Task task)
- {
- // NOTE: The JIT refuses to inline ValidateEnd when it contains the contents
- // of HandleNonSuccessAndDebuggerNotification, hence the separation.
-
- // Synchronously wait for the task to complete. When used by the compiler,
- // the task will already be complete. This code exists only for direct GetResult use,
- // for cases where the same exception propagation semantics used by "await" are desired,
- // but where for one reason or another synchronous rather than asynchronous waiting is needed.
- if (!task.IsCompleted)
- {
- bool taskCompleted = task.InternalWait(Timeout.Infinite, default);
- Debug.Assert(taskCompleted, "With an infinite timeout, the task should have always completed.");
- }
-
- // Now that we're done, alert the debugger if so requested
- task.NotifyDebuggerOfWaitCompletionIfNecessary();
-
- // And throw an exception if the task is faulted or canceled.
- if (!task.IsCompletedSuccessfully) ThrowForNonSuccess(task);
- }
-
- /// <summary>Throws an exception to handle a task that completed in a state other than RanToCompletion.</summary>
- [StackTraceHidden]
- private static void ThrowForNonSuccess(Task task)
- {
- Debug.Assert(task.IsCompleted, "Task must have been completed by now.");
- Debug.Assert(task.Status != TaskStatus.RanToCompletion, "Task should not be completed successfully.");
-
- // Handle whether the task has been canceled or faulted
- switch (task.Status)
- {
- // If the task completed in a canceled state, throw an OperationCanceledException.
- // This will either be the OCE that actually caused the task to cancel, or it will be a new
- // TaskCanceledException. TCE derives from OCE, and by throwing it we automatically pick up the
- // completed task's CancellationToken if it has one, including that CT in the OCE.
- case TaskStatus.Canceled:
- ExceptionDispatchInfo? oceEdi = task.GetCancellationExceptionDispatchInfo();
- if (oceEdi != null)
- {
- oceEdi.Throw();
- Debug.Fail("Throw() should have thrown");
- }
- throw new TaskCanceledException(task);
-
- // If the task faulted, throw its first exception,
- // even if it contained more than one.
- case TaskStatus.Faulted:
- ReadOnlyCollection<ExceptionDispatchInfo> edis = task.GetExceptionDispatchInfos();
- if (edis.Count > 0)
- {
- edis[0].Throw();
- Debug.Fail("Throw() should have thrown");
- break; // Necessary to compile: non-reachable, but compiler can't determine that
- }
- else
- {
- Debug.Fail("There should be exceptions if we're Faulted.");
- throw task.Exception!;
- }
- }
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="task">The task being awaited.</param>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <param name="continueOnCapturedContext">Whether to capture and marshal back to the current context.</param>
- /// <param name="flowExecutionContext">Whether to flow ExecutionContext across the await.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
- {
- if (continuation == null) throw new ArgumentNullException(nameof(continuation));
-
- // If TaskWait* ETW events are enabled, trace a beginning event for this await
- // and set up an ending event to be traced when the asynchronous await completes.
- if (TplEventSource.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
- {
- continuation = OutputWaitEtwEvents(task, continuation);
- }
-
- // Set the continuation onto the awaited task.
- task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext);
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="task">The task being awaited.</param>
- /// <param name="stateMachineBox">The box to invoke when the await operation completes.</param>
- /// <param name="continueOnCapturedContext">Whether to capture and marshal back to the current context.</param>
- internal static void UnsafeOnCompletedInternal(Task task, IAsyncStateMachineBox stateMachineBox, bool continueOnCapturedContext)
- {
- Debug.Assert(stateMachineBox != null);
-
- // If TaskWait* ETW events are enabled, trace a beginning event for this await
- // and set up an ending event to be traced when the asynchronous await completes.
- if (TplEventSource.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
- {
- task.SetContinuationForAwait(OutputWaitEtwEvents(task, stateMachineBox.MoveNextAction), continueOnCapturedContext, flowExecutionContext: false);
- }
- else
- {
- task.UnsafeSetContinuationForAwait(stateMachineBox, continueOnCapturedContext);
- }
- }
-
- /// <summary>
- /// Outputs a WaitBegin ETW event, and augments the continuation action to output a WaitEnd ETW event.
- /// </summary>
- /// <param name="task">The task being awaited.</param>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <returns>The action to use as the actual continuation.</returns>
- private static Action OutputWaitEtwEvents(Task task, Action continuation)
- {
- Debug.Assert(task != null, "Need a task to wait on");
- Debug.Assert(continuation != null, "Need a continuation to invoke when the wait completes");
-
- if (Task.s_asyncDebuggingEnabled)
- {
- Task.AddToActiveTasks(task);
- }
-
- TplEventSource log = TplEventSource.Log;
-
- if (log.IsEnabled())
- {
- // ETW event for Task Wait Begin
- Task? currentTaskAtBegin = Task.InternalCurrent;
-
- // If this task's continuation is another task, get it.
- Task? continuationTask = AsyncMethodBuilderCore.TryGetContinuationTask(continuation);
- log.TaskWaitBegin(
- currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler!.Id : TaskScheduler.Default.Id,
- currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0,
- task.Id, TplEventSource.TaskWaitBehavior.Asynchronous,
- continuationTask != null ? continuationTask.Id : 0);
- }
-
- // Create a continuation action that outputs the end event and then invokes the user
- // provided delegate. This incurs the allocations for the closure/delegate, but only if the event
- // is enabled, and in doing so it allows us to pass the awaited task's information into the end event
- // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter
- // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred).
- return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (innerContinuation, innerTask) =>
- {
- if (Task.s_asyncDebuggingEnabled)
- {
- Task.RemoveFromActiveTasks(innerTask);
- }
-
- TplEventSource innerEtwLog = TplEventSource.Log;
-
- // ETW event for Task Wait End.
- Guid prevActivityId = default;
- bool bEtwLogEnabled = innerEtwLog.IsEnabled();
- if (bEtwLogEnabled)
- {
- Task? currentTaskAtEnd = Task.InternalCurrent;
- innerEtwLog.TaskWaitEnd(
- currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler!.Id : TaskScheduler.Default.Id,
- currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0,
- innerTask.Id);
-
- // Ensure the continuation runs under the activity ID of the task that completed for the
- // case the antecedent is a promise (in the other cases this is already the case).
- if (innerEtwLog.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
- EventSource.SetCurrentThreadActivityId(TplEventSource.CreateGuidForTaskID(innerTask.Id), out prevActivityId);
- }
-
- // Invoke the original continuation provided to OnCompleted.
- innerContinuation();
-
- if (bEtwLogEnabled)
- {
- innerEtwLog.TaskWaitContinuationComplete(innerTask.Id);
- if (innerEtwLog.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
- EventSource.SetCurrentThreadActivityId(prevActivityId);
- }
- }, task);
- }
- }
-
- /// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct TaskAwaiter<TResult> : ICriticalNotifyCompletion, ITaskAwaiter
- {
- // WARNING: Unsafe.As is used to access TaskAwaiter<> as the non-generic TaskAwaiter.
- // Its layout must remain the same.
-
- /// <summary>The task being awaited.</summary>
- private readonly Task<TResult> m_task;
-
- /// <summary>Initializes the <see cref="TaskAwaiter{TResult}"/>.</summary>
- /// <param name="task">The <see cref="System.Threading.Tasks.Task{TResult}"/> to be awaited.</param>
- internal TaskAwaiter(Task<TResult> task)
- {
- Debug.Assert(task != null, "Constructing an awaiter requires a task to await.");
- m_task = task;
- }
-
- /// <summary>Gets whether the task being awaited is completed.</summary>
- /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted => m_task.IsCompleted;
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void OnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void UnsafeOnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
- }
-
- /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
- /// <returns>The result of the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</returns>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
- /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
- [StackTraceHidden]
- public TResult GetResult()
- {
- TaskAwaiter.ValidateEnd(m_task);
- return m_task.ResultOnSuccess;
- }
- }
-
- /// <summary>
- /// Marker interface used to know whether a particular awaiter is either a
- /// TaskAwaiter or a TaskAwaiter`1. It must not be implemented by any other
- /// awaiters.
- /// </summary>
- internal interface ITaskAwaiter { }
-
- /// <summary>
- /// Marker interface used to know whether a particular awaiter is either a
- /// CTA.ConfiguredTaskAwaiter or a CTA`1.ConfiguredTaskAwaiter. It must not
- /// be implemented by any other awaiters.
- /// </summary>
- internal interface IConfiguredTaskAwaiter { }
-
- /// <summary>Provides an awaitable object that allows for configured awaits on <see cref="System.Threading.Tasks.Task"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct ConfiguredTaskAwaitable
- {
- /// <summary>The task being awaited.</summary>
- private readonly ConfiguredTaskAwaitable.ConfiguredTaskAwaiter m_configuredTaskAwaiter;
-
- /// <summary>Initializes the <see cref="ConfiguredTaskAwaitable"/>.</summary>
- /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task"/>.</param>
- /// <param name="continueOnCapturedContext">
- /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
- /// </param>
- internal ConfiguredTaskAwaitable(Task task, bool continueOnCapturedContext)
- {
- Debug.Assert(task != null, "Constructing an awaitable requires a task to await.");
- m_configuredTaskAwaiter = new ConfiguredTaskAwaitable.ConfiguredTaskAwaiter(task, continueOnCapturedContext);
- }
-
- /// <summary>Gets an awaiter for this awaitable.</summary>
- /// <returns>The awaiter.</returns>
- public ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter()
- {
- return m_configuredTaskAwaiter;
- }
-
- /// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion, IConfiguredTaskAwaiter
- {
- // WARNING: Unsafe.As is used to access the generic ConfiguredTaskAwaiter as this.
- // Its layout must remain the same.
-
- /// <summary>The task being awaited.</summary>
- internal readonly Task m_task;
- /// <summary>Whether to attempt marshaling back to the original context.</summary>
- internal readonly bool m_continueOnCapturedContext;
-
- /// <summary>Initializes the <see cref="ConfiguredTaskAwaiter"/>.</summary>
- /// <param name="task">The <see cref="System.Threading.Tasks.Task"/> to await.</param>
- /// <param name="continueOnCapturedContext">
- /// true to attempt to marshal the continuation back to the original context captured
- /// when BeginAwait is called; otherwise, false.
- /// </param>
- internal ConfiguredTaskAwaiter(Task task, bool continueOnCapturedContext)
- {
- Debug.Assert(task != null, "Constructing an awaiter requires a task to await.");
- m_task = task;
- m_continueOnCapturedContext = continueOnCapturedContext;
- }
-
- /// <summary>Gets whether the task being awaited is completed.</summary>
- /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted => m_task.IsCompleted;
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void OnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: true);
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void UnsafeOnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: false);
- }
-
- /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
- /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
- [StackTraceHidden]
- public void GetResult()
- {
- TaskAwaiter.ValidateEnd(m_task);
- }
- }
- }
-
- /// <summary>Provides an awaitable object that allows for configured awaits on <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct ConfiguredTaskAwaitable<TResult>
- {
- /// <summary>The underlying awaitable on whose logic this awaitable relies.</summary>
- private readonly ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter m_configuredTaskAwaiter;
-
- /// <summary>Initializes the <see cref="ConfiguredTaskAwaitable{TResult}"/>.</summary>
- /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task{TResult}"/>.</param>
- /// <param name="continueOnCapturedContext">
- /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
- /// </param>
- internal ConfiguredTaskAwaitable(Task<TResult> task, bool continueOnCapturedContext)
- {
- m_configuredTaskAwaiter = new ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter(task, continueOnCapturedContext);
- }
-
- /// <summary>Gets an awaiter for this awaitable.</summary>
- /// <returns>The awaiter.</returns>
- public ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter GetAwaiter()
- {
- return m_configuredTaskAwaiter;
- }
-
- /// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable{TResult}"/>.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion, IConfiguredTaskAwaiter
- {
- // WARNING: Unsafe.As is used to access this as the non-generic ConfiguredTaskAwaiter.
- // Its layout must remain the same.
-
- /// <summary>The task being awaited.</summary>
- private readonly Task<TResult> m_task;
- /// <summary>Whether to attempt marshaling back to the original context.</summary>
- private readonly bool m_continueOnCapturedContext;
-
- /// <summary>Initializes the <see cref="ConfiguredTaskAwaiter"/>.</summary>
- /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task{TResult}"/>.</param>
- /// <param name="continueOnCapturedContext">
- /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
- /// </param>
- internal ConfiguredTaskAwaiter(Task<TResult> task, bool continueOnCapturedContext)
- {
- Debug.Assert(task != null, "Constructing an awaiter requires a task to await.");
- m_task = task;
- m_continueOnCapturedContext = continueOnCapturedContext;
- }
-
- /// <summary>Gets whether the task being awaited is completed.</summary>
- /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted => m_task.IsCompleted;
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void OnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: true);
- }
-
- /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
- /// <param name="continuation">The action to invoke when the await operation completes.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public void UnsafeOnCompleted(Action continuation)
- {
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: false);
- }
-
- /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
- /// <returns>The result of the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</returns>
- /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
- /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
- [StackTraceHidden]
- public TResult GetResult()
- {
- TaskAwaiter.ValidateEnd(m_task);
- return m_task.ResultOnSuccess;
- }
- }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
deleted file mode 100644
index d4bdcd1fa7f..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Indicates that the use of <see cref="System.ValueTuple"/> on a member is meant to be treated as a tuple with element names.
- /// </summary>
- [CLSCompliant(false)]
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)]
- public sealed class TupleElementNamesAttribute : Attribute
- {
- private readonly string?[] _transformNames;
-
- /// <summary>
- /// Initializes a new instance of the <see
- /// cref="TupleElementNamesAttribute"/> class.
- /// </summary>
- /// <param name="transformNames">
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which <see cref="System.ValueType"/> occurrences are
- /// meant to carry element names.
- /// </param>
- /// <remarks>
- /// This constructor is meant to be used on types that contain an
- /// instantiation of <see cref="System.ValueType"/> that contains
- /// element names. For instance, if <c>C</c> is a generic type with
- /// two type parameters, then a use of the constructed type <c>C{<see
- /// cref="System.ValueTuple{T1, T2}"/>, <see
- /// cref="System.ValueTuple{T1, T2, T3}"/></c> might be intended to
- /// treat the first type argument as a tuple with element names and the
- /// second as a tuple without element names. In which case, the
- /// appropriate attribute specification should use a
- /// <c>transformNames</c> value of <c>{ "name1", "name2", null, null,
- /// null }</c>.
- /// </remarks>
- public TupleElementNamesAttribute(string?[] transformNames)
- {
- if (transformNames == null)
- {
- throw new ArgumentNullException(nameof(transformNames));
- }
-
- _transformNames = transformNames;
- }
-
- /// <summary>
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which <see cref="System.ValueTuple"/> elements are
- /// meant to carry element names.
- /// </summary>
- public IList<string?> TransformNames => _transformNames;
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
deleted file mode 100644
index 27dd6457557..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
- public sealed class TypeForwardedFromAttribute : Attribute
- {
- public TypeForwardedFromAttribute(string assemblyFullName)
- {
- if (string.IsNullOrEmpty(assemblyFullName))
- throw new ArgumentNullException(nameof(assemblyFullName));
-
- AssemblyFullName = assemblyFullName;
- }
-
- public string AssemblyFullName { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
deleted file mode 100644
index 85d5c030c19..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
- public sealed class TypeForwardedToAttribute : Attribute
- {
- public TypeForwardedToAttribute(Type destination)
- {
- Destination = destination;
- }
-
- public Type Destination { get; }
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
deleted file mode 100644
index b1f274367e8..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Struct)]
- public sealed class UnsafeValueTypeAttribute : Attribute
- {
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
deleted file mode 100644
index b3817d33904..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Threading.Tasks.Sources;
-
-#if !NETSTANDARD2_0
-using Internal.Runtime.CompilerServices;
-#endif
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>Provides an awaiter for a <see cref="ValueTask"/>.</summary>
- public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter
- {
- /// <summary>Shim used to invoke an <see cref="Action"/> passed as the state argument to a <see cref="Action{Object}"/>.</summary>
- internal static readonly Action<object?> s_invokeActionDelegate = state =>
- {
- if (!(state is Action action))
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.state);
- return;
- }
-
- action();
- };
- /// <summary>The value being awaited.</summary>
- private readonly ValueTask _value;
-
- /// <summary>Initializes the awaiter.</summary>
- /// <param name="value">The value to be awaited.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ValueTaskAwaiter(in ValueTask value) => _value = value;
-
- /// <summary>Gets whether the <see cref="ValueTask"/> has completed.</summary>
- public bool IsCompleted
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _value.IsCompleted;
- }
-
- /// <summary>Gets the result of the ValueTask.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void GetResult() => _value.ThrowIfCompletedUnsuccessfully();
-
- /// <summary>Schedules the continuation action for this ValueTask.</summary>
- public void OnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- t.GetAwaiter().OnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext);
- }
- else
- {
- ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation);
- }
- }
-
- /// <summary>Schedules the continuation action for this ValueTask.</summary>
- public void UnsafeOnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- t.GetAwaiter().UnsafeOnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
- }
- else
- {
- ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation);
- }
- }
-
- void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox box)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource);
-
- if (obj is Task t)
- {
- TaskAwaiter.UnsafeOnCompletedInternal(t, box, continueOnCapturedContext: true);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
- }
- else
- {
- TaskAwaiter.UnsafeOnCompletedInternal(Task.CompletedTask, box, continueOnCapturedContext: true);
- }
- }
- }
-
- /// <summary>Provides an awaiter for a <see cref="ValueTask{TResult}"/>.</summary>
- public readonly struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter
- {
- /// <summary>The value being awaited.</summary>
- private readonly ValueTask<TResult> _value;
-
- /// <summary>Initializes the awaiter.</summary>
- /// <param name="value">The value to be awaited.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ValueTaskAwaiter(in ValueTask<TResult> value) => _value = value;
-
- /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> has completed.</summary>
- public bool IsCompleted
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _value.IsCompleted;
- }
-
- /// <summary>Gets the result of the ValueTask.</summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public TResult GetResult() => _value.Result;
-
- /// <summary>Schedules the continuation action for this ValueTask.</summary>
- public void OnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- t.GetAwaiter().OnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext);
- }
- else
- {
- ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation);
- }
- }
-
- /// <summary>Schedules the continuation action for this ValueTask.</summary>
- public void UnsafeOnCompleted(Action continuation)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- t.GetAwaiter().UnsafeOnCompleted(continuation);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
- }
- else
- {
- ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation);
- }
- }
-
- void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox box)
- {
- object? obj = _value._obj;
- Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>);
-
- if (obj is Task<TResult> t)
- {
- TaskAwaiter.UnsafeOnCompletedInternal(t, box, continueOnCapturedContext: true);
- }
- else if (obj != null)
- {
- Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
- }
- else
- {
- TaskAwaiter.UnsafeOnCompletedInternal(Task.CompletedTask, box, continueOnCapturedContext: true);
- }
- }
- }
-
- /// <summary>Internal interface used to enable optimizations from <see cref="AsyncTaskMethodBuilder"/>.</summary>>
- internal interface IStateMachineBoxAwareAwaiter
- {
- /// <summary>Invoked to set <see cref="ITaskCompletionAction.Invoke"/> of the <paramref name="box"/> as the awaiter's continuation.</summary>
- /// <param name="box">The box object.</param>
- void AwaitUnsafeOnCompleted(IAsyncStateMachineBox box);
- }
-}
diff --git a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/YieldAwaitable.cs b/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/YieldAwaitable.cs
deleted file mode 100644
index cda89738f3e..00000000000
--- a/netcore/System.Private.CoreLib/shared/System/Runtime/CompilerServices/YieldAwaitable.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// Compiler-targeted type for switching back into the current execution context, e.g.
-//
-// await Task.Yield();
-// =====================
-// var $awaiter = Task.Yield().GetAwaiter();
-// if (!$awaiter.IsCompleted)
-// {
-// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
-// return;
-// Label:
-// }
-// $awaiter.GetResult();
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System.Diagnostics;
-using System.Diagnostics.Tracing;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
- // NOTE: YieldAwaitable currently has no state; while developers are encouraged to use Task.Yield() to produce one,
- // no validation is performed to ensure that the developer isn't doing "await new YieldAwaitable()". Such validation
- // would require additional, useless state to be stored, and as this is a type in the CompilerServices namespace, and
- // as the above example isn't harmful, we take the cheaper approach of not validating anything.
-
- /// <summary>Provides an awaitable context for switching into a target environment.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct YieldAwaitable
- {
- /// <summary>Gets an awaiter for this <see cref="YieldAwaitable"/>.</summary>
- /// <returns>An awaiter for this awaitable.</returns>
- /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- public YieldAwaiter GetAwaiter() { return default; }
-
- /// <summary>Provides an awaiter that switches into a target environment.</summary>
- /// <remarks>This type is intended for compiler use only.</remarks>
- public readonly struct YieldAwaiter : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter
- {
- /// <summary>Gets whether a yield is not required.</summary>
- /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
- public bool IsCompleted => false; // yielding is always required for YieldAwaiter, hence false
-
- /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
- /// <param name="continuation">The action to invoke asynchronously.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- public void OnCompleted(Action continuation)
- {
- QueueContinuation(continuation, flowContext: true);
- }
-
- /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
- /// <param name="continuation">The action to invoke asynchronously.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- public void UnsafeOnCompleted(Action continuation)
- {
- QueueContinuation(continuation, flowContext: false);
- }
-
- /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
- /// <param name="continuation">The action to invoke asynchronously.</param>
- /// <param name="flowContext">true to flow ExecutionContext; false if flowing is not required.</param>
- /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- private static void QueueContinuation(Action continuation, bool flowContext)
- {
- // Validate arguments
- if (continuation == null) throw new ArgumentNullException(nameof(continuation));
-
- if (TplEventSource.Log.IsEnabled())
- {
- continuation = OutputCorrelationEtwEvent(continuation);
- }
- // Get the current SynchronizationContext, and if there is one,
- // post the continuation to it. However, treat the base type
- // as if there wasn't a SynchronizationContext, since that's what it
- // logically represents.
- SynchronizationContext? syncCtx = SynchronizationContext.Current;
- if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
- {
- syncCtx.Post(s_sendOrPostCallbackRunAction, continuation);
- }
- else
- {
- // If we're targeting the default scheduler, queue to the thread pool, so that we go into the global
- // queue. As we're going into the global queue, we might as well use QUWI, which for the global queue is
- // just a tad faster than task, due to a smaller object getting allocated and less work on the execution path.
- TaskScheduler scheduler = TaskScheduler.Current;
- if (scheduler == TaskScheduler.Default)
- {
- if (flowContext)
- {
- ThreadPool.QueueUserWorkItem(s_waitCallbackRunAction, continuation);
- }
- else
- {
- ThreadPool.UnsafeQueueUserWorkItem(s_waitCallbackRunAction, continuation);
- }
- }
- // We're targeting a custom scheduler, so queue a task.
- else
- {
- Task.Factory.StartNew(continuation, default, TaskCreationOptions.PreferFairness, scheduler);
- }
- }
- }
-
- void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox box)
- {
- Debug.Assert(box != null);
-
- // If tracing is enabled, delegate the Action-based implementation.
- if (TplEventSource.Log.IsEnabled())
- {
- QueueContinuation(box.MoveNextAction, flowContext: false);
- return;
- }
-
- // Otherwise, this is the same logic as in QueueContinuation, except using
- // an IAsyncStateMachineBox instead of an Action, and only for flowContext:false.
-
- SynchronizationContext? syncCtx = SynchronizationContext.Current;
- if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
- {
- syncCtx.Post(s => ((IAsyncStateMachineBox)s!).MoveNext(), box);
- }
- else
- {
- TaskScheduler scheduler = TaskScheduler.Current;
- if (scheduler == TaskScheduler.Default)
- {
- ThreadPool.UnsafeQueueUserWorkItemInternal(box, preferLocal: false);
- }
- else
- {
- Task.Factory.StartNew(s => ((IAsyncStateMachineBox)s!).MoveNext(), box, default, TaskCreationOptions.PreferFairness, scheduler);
- }
- }
- }
-
- private static Action OutputCorrelationEtwEvent(Action continuation)
- {
-#if CORERT
- // TODO
- return continuation;
-#else
- int continuationId = Task.NewId();
- Task? currentTask = Task.InternalCurrent;
- // fire the correlation ETW event
- TplEventSource.Log.AwaitTaskContinuationScheduled(TaskScheduler.Current.Id, (currentTask != null) ? currentTask.Id : 0, continuationId);
-
- return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (innerContinuation, continuationIdTask) =>
- {
- TplEventSource log = TplEventSource.Log;
- log.TaskWaitContinuationStarted(((Task<int>)continuationIdTask).Result);
-
- // ETW event for Task Wait End.
- Guid prevActivityId = default;
- // Ensure the continuation runs under the correlated activity ID generated above
- if (log.TasksSetActivityIds)
- EventSource.SetCurrentThreadActivityId(TplEventSource.CreateGuidForTaskID(((Task<int>)continuationIdTask).Result), out prevActivityId);
-
- // Invoke the original continuation provided to OnCompleted.
- innerContinuation();
- // Restore activity ID
-
- if (log.TasksSetActivityIds)
- EventSource.SetCurrentThreadActivityId(prevActivityId);
-
- log.TaskWaitContinuationComplete(((Task<int>)continuationIdTask).Result);
- }, Task.FromResult(continuationId)); // pass the ID in a task to avoid a closure\
-#endif
- }
-
- /// <summary>WaitCallback that invokes the Action supplied as object state.</summary>
- private static readonly WaitCallback s_waitCallbackRunAction = RunAction;
- /// <summary>SendOrPostCallback that invokes the Action supplied as object state.</summary>
- private static readonly SendOrPostCallback s_sendOrPostCallbackRunAction = RunAction;
- /// <summary>Runs an Action delegate provided as state.</summary>
- /// <param name="state">The Action delegate to invoke.</param>
- private static void RunAction(object? state) { ((Action)state!)(); }
-
- /// <summary>Ends the await operation.</summary>
- public void GetResult() { } // Nop. It exists purely because the compiler pattern demands it.
- }
- }
-}