Skip to content

Commit

Permalink
Merge branch 'main' into darc-main-19369168-1f4a-490d-90eb-b9e754971a1a
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 authored Dec 4, 2024
2 parents 500ac44 + 48e3f13 commit ece3176
Show file tree
Hide file tree
Showing 38 changed files with 414 additions and 278 deletions.
2 changes: 1 addition & 1 deletion docs/design/features/y2038.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Normally, ABI breaks like this are not a problem for the Linux ecosystem because

### .NET builds

.NET official builds are produced by building the product on a [dedicated set of build images](https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/linux-instructions.md). The images run Azure Linux 3.0 with an up-to-date cross-compilation toolchain, and also include a root filesystem of an old Linux distribution that provides an old version of glibc (or musl libc), which determines the libc compatibility of our builds.
.NET official builds are produced by building the product on a [dedicated set of build images](https://github.com/dotnet/runtime/blob/main/docs/workflow/using-docker.md#the-official-runtime-docker-images). The images run Azure Linux 3.0 with an up-to-date cross-compilation toolchain, and also include a root filesystem of an old Linux distribution that provides an old version of glibc (or musl libc), which determines the libc compatibility of our builds.

In .NET 8, we [support](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md#libc-compatibility) glibc 2.23 and musl 1.2.2, by building the product with a root filesystem from Ubuntu 16.04 and Alpine 3.13, respectively.

Expand Down
21 changes: 18 additions & 3 deletions docs/design/specs/runtime-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ These are proposed modifications to the ECMA-335 specification for runtime-async

### I.8.4.5 Sync and Async Methods

Methods may be either 'sync' or 'async'. Async method definitions are methods with a return type of `System.Threading.Task`, `System.Threading.ValueTask`, `System.Threading.Task<T>`, or `System.Threading.ValueTask<T>` attributed with `[System.Runtime.CompilerServices.RuntimeAsyncMethodAttribute]`. Async method definitions are only valid inside async-capable assemblies. An async-capable assembly is one which references a corlib containing an `abstract sealed class RuntimeFeature` with a `public const string` field member named `Async`, or a corelib meeting these requirements. The `RuntimeAsyncMethodAttribute` should only be applied to methods, and may be defined in any assembly. Inside async method bodies, certain methods are also invokable by a special signature encoding, described in [### I.8.6.1.5 Method signatures].
Methods may be either 'sync' or 'async'. Async method definitions are methods attributed with `[MethodImpl(MethodImplOptions.Async)]`. Inside async method bodies, certain methods are also invokable by a special signature encoding, described in [### I.8.6.1.5 Method signatures].

Applicability of `MethodImplOptions.Async`:
* The `[MethodImpl(MethodImplOptions.Async)]` only has effect when applied to method definitions that return generic or nongeneric variants of Task or ValueTask.
* The `[MethodImpl(MethodImplOptions.Async)]` only has effect when applied to method definitions with CIL implementation.
* Async method definitions are only valid inside async-capable assemblies. An async-capable assembly is one which references a corlib containing an `abstract sealed class RuntimeFeature` with a `public const string` field member named `Async`.
* Combining `MethodImplOptions.Async` with `MethodImplOptions.Synchronized` is invalid.
* Applying `MethodImplOptions.Async` to methods with `byref` or `ref-like` parameters is invalid.
* Applying `MethodImplOptions.Async` to vararg methods is invalid.

Sync methods are all other methods.

Expand All @@ -28,9 +36,9 @@ Async methods support the following suspension points:
{
public static class RuntimeHelpers
{
[RuntimeAsyncMethod]
[MethodImpl(MethodImplOptions.Async)]
public static Task AwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { ... }
[RuntimeAsyncMethod]
[MethodImpl(MethodImplOptions.Async)]
public static Task UnsafeAwaitAwaiterFromRuntimeAsync<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion
}
}
Expand All @@ -55,6 +63,13 @@ All async methods effectively have two entry points, or signatures. The first si

Callers may retrieve a Task/ValueTask return type from an async method via calling its primary, definitional signature. This functionality is available in both sync and async methods.

### II.23.1.11 Flags for methods [MethodImplAttributes]

| Flag | Value | Description |
| ------------- | ------------- | ------------- |
| . . . | . . . | . . . |
|Async |0x0400 |Method is an Async Method.|

### I.8.6.1.5 Method signatures

The list of relevant components is augmented to include sync vs. async method types. Async methods have some additions to normal signature compatibility.
Expand Down
2 changes: 1 addition & 1 deletion docs/workflow/building/coreclr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- [The Basics](#the-basics)
- [Build Results](#build-results)
- [What to do with the Build](#what-to-do-with-the-build)
- [The Core_Root for Testing Your Build](#the-core-root-for-testing-your-build)
- [The Core_Root for Testing Your Build](#the-core\_root-for-testing-your-build)
- [The Dev Shipping Packs](#the-dev-shipping-packs)
- [Cross Compilation](#cross-compilation)
- [Other Features](#other-features)
Expand Down
2 changes: 1 addition & 1 deletion docs/workflow/building/coreclr/cross-building.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ When it comes to building, Docker offers the most flexibility when it comes to t

### Cross-Compiling for ARM32 and ARM64 with Docker

As mentioned in the [Linux Cross-Building section](#linux-cross-building), the `ROOTFS_DIR` environment variable has to be set to the _crossrootfs_ location. The prereqs Docker images already have _crossrootfs_ built, so you only need to specify it when creating the Docker container by means of the `-e` flag. These locations are specified in the [Docker Images table](/docs/workflow/building/coreclr/linux-instructions.md#docker-images).
As mentioned in the [Linux Cross-Building section](#linux-cross-building), the `ROOTFS_DIR` environment variable has to be set to the _crossrootfs_ location. The prereqs Docker images already have _crossrootfs_ built, so you only need to specify it when creating the Docker container by means of the `-e` flag. These locations are specified in the [Docker Images table](/docs/workflow/using-docker.md#the-official-runtime-docker-images).

In addition, you also have to specify the `--cross` flag with the target architecture. For example, the following command would create a container to build CoreCLR for Linux ARM64:

Expand Down
4 changes: 2 additions & 2 deletions docs/workflow/requirements/linux-requirements.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Requirements to Set Up the Build Environment on Linux

- [Using your Linux Environment](#using-your-linux-environment)
- [Debian/Ubuntu](#debian/ubuntu)
- [Debian and Ubuntu](#debian-and-ubuntu)
- [CMake on Older Versions of Ubuntu and Debian](#cmake-on-older-versions-of-ubuntu-and-debian)
- [Clang for WASM](#clang-for-wasm)
- [Additional Tools for Cross Building](#additional-tools-for-cross-building)
Expand All @@ -28,7 +28,7 @@ eng/common/native/install-dependencies.sh

Note that it is always a good idea to manually double check that all the dependencies were installed correctly if you opt to use the script.

### Debian/Ubuntu
### Debian and Ubuntu

These instructions are written assuming the current *Ubuntu LTS*.

Expand Down
9 changes: 4 additions & 5 deletions docs/workflow/testing/coreclr/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ This guide will walk you through building and running the CoreCLR tests. These a

## Requirements

In order to build CoreCLR tests, you will need to have built the runtime and the libraries (that is, _clr_ and _libs_ subsets). You can find more detailed instructions per platform in their dedicated docs:
In order to build CoreCLR tests, you will need to have built the runtime and the libraries (that is, _clr_ and _libs_ subsets). You can find detailed instructions on how to do it on their respective README's:

* [Windows](/docs/workflow/building/coreclr/windows-instructions.md)
* [macOS](/docs/workflow/building/coreclr/macos-instructions.md)
* [Linux](/docs/workflow/building/coreclr/linux-instructions.md)
* [CoreCLR](/docs/workflow/building/coreclr/README.md)
* [Libraries](/docs/workflow/building/libraries/README.md)

For CoreCLR testing purposes, it is more than enough to simply build the _libs_ subset, as far as it concerns the libraries. If you want to know more in-depth about them, they have their own [libraries dedicated docs section](/docs/workflow/building/libraries/README.md).
For CoreCLR testing purposes, it is more than enough to simply build the _libs_ subset, as far as it concerns the libraries. If you want to know more in-depth about them, they have their own [libraries dedicated docs section](/docs/workflow/building/libraries/).

## Overview

Expand Down
2 changes: 1 addition & 1 deletion docs/workflow/testing/coreclr/unix-test-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CoreCLR tests

## Building

Build CoreCLR on [Unix](../../building/coreclr/linux-instructions.md).
Build CoreCLR following the instructions in its [main doc](/docs/workflow/building/coreclr/README.md).

## Building the Tests

Expand Down
3 changes: 1 addition & 2 deletions docs/workflow/testing/libraries/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ cd src\libraries\System.Collections.Immutable\tests
dotnet build /t:Test
```

**NOTE**: if your environment doesn't have the required SDK installed (e.g. inside [Docker container](/docs/workflow/building/coreclr/linux-instructions.md#build-using-docker)),
use `./dotnet.sh`/`.\dotnet.cmd` instead of `dotnet`.
**NOTE**: if your environment doesn't have the required SDK installed (e.g. inside [a Docker container](/docs/workflow/using-docker.md)), use `./dotnet.sh`/`.\dotnet.cmd` instead of `dotnet`.

### Running only certain tests

Expand Down
17 changes: 2 additions & 15 deletions src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,23 +434,10 @@ private bool BindToMethodInfo(object? target, IRuntimeMethodInfo method, Runtime

private static MulticastDelegate InternalAlloc(RuntimeType type)
{
MulticastDelegate? d = null;
InternalAlloc(new QCallTypeHandle(ref type), ObjectHandleOnStack.Create(ref d));
return d!;
Debug.Assert(type.IsAssignableTo(typeof(MulticastDelegate)));
return Unsafe.As<MulticastDelegate>(RuntimeTypeHandle.InternalAlloc(type));
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_InternalAlloc")]
private static partial void InternalAlloc(QCallTypeHandle type, ObjectHandleOnStack d);

internal static MulticastDelegate InternalAllocLike(MulticastDelegate d)
{
InternalAllocLike(ObjectHandleOnStack.Create(ref d));
return d;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_InternalAllocLike")]
private static partial void InternalAllocLike(ObjectHandleOnStack d);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe bool InternalEqualTypes(object a, object b)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ private static bool TrySetSlot(object?[] a, int index, object o)
private MulticastDelegate NewMulticastDelegate(object[] invocationList, int invocationCount, bool thisIsMultiCastAlready)
{
// First, allocate a new multicast delegate just like this one, i.e. same type as the this object
MulticastDelegate result = InternalAllocLike(this);
MulticastDelegate result = Unsafe.As<MulticastDelegate>(RuntimeTypeHandle.InternalAllocNoChecks((RuntimeType)GetType()));

// Performance optimization - if this already points to a true multicast delegate,
// copy _methodPtr and _methodPtrAux fields rather than calling into the EE to get them
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,32 @@ internal static void Unbox_Nullable(ref byte destPtr, MethodTable* typeMT, objec
}
}

[DebuggerHidden]
internal static object? ReboxFromNullable(MethodTable* srcMT, object src)
{
Debug.Assert(srcMT->IsNullable);

ref byte nullableData = ref src.GetRawData();

// If 'hasValue' is false, return null.
if (!Unsafe.As<byte, bool>(ref nullableData))
return null;

// Allocate a new instance of the T in Nullable<T>.
MethodTable* dstMT = srcMT->InstantiationArg0();
object dst = RuntimeTypeHandle.InternalAlloc(dstMT);

// Copy data from the Nullable<T>.
ref byte srcData = ref Unsafe.Add(ref nullableData, srcMT->NullableValueAddrOffset);
ref byte dstData = ref RuntimeHelpers.GetRawData(dst);
if (dstMT->ContainsGCPointers)
Buffer.BulkMoveWithWriteBarrier(ref dstData, ref srcData, dstMT->GetNumInstanceFieldBytesIfContainsGCPointers());
else
SpanHelpers.Memmove(ref dstData, ref srcData, dstMT->GetNumInstanceFieldBytes());

return dst;
}

[DebuggerHidden]
[MethodImpl(MethodImplOptions.NoInlining)]
private static ref byte Unbox_Helper(MethodTable* pMT1, object obj)
Expand Down
87 changes: 81 additions & 6 deletions src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,36 @@ private static partial void CreateInstanceForAnotherGenericParameter(
int cTypeHandles,
ObjectHandleOnStack instantiatedObject);

internal static unsafe object InternalAlloc(MethodTable* pMT)
{
object? result = null;
InternalAlloc(pMT, ObjectHandleOnStack.Create(ref result));
return result!;
}

internal static object InternalAlloc(RuntimeType type)
{
Debug.Assert(!type.GetNativeTypeHandle().IsTypeDesc);
object result = InternalAlloc(type.GetNativeTypeHandle().AsMethodTable());
GC.KeepAlive(type);
return result;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_InternalAlloc")]
private static unsafe partial void InternalAlloc(MethodTable* pMT, ObjectHandleOnStack result);

internal static object InternalAllocNoChecks(RuntimeType type)
{
Debug.Assert(!type.GetNativeTypeHandle().IsTypeDesc);
object? result = null;
InternalAllocNoChecks(type.GetNativeTypeHandle().AsMethodTable(), ObjectHandleOnStack.Create(ref result));
GC.KeepAlive(type);
return result!;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_InternalAllocNoChecks")]
private static unsafe partial void InternalAllocNoChecks(MethodTable* pMT, ObjectHandleOnStack result);

/// <summary>
/// Given a RuntimeType, returns information about how to activate it via calli
/// semantics. This method will ensure the type object is fully initialized within
Expand Down Expand Up @@ -1026,14 +1056,59 @@ internal static MdUtf8String GetUtf8Name(RuntimeMethodHandleInternal method)

[DebuggerStepThrough]
[DebuggerHidden]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object? InvokeMethod(object? target, void** arguments, Signature sig, bool isConstructor);
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_InvokeMethod")]
private static partial void InvokeMethod(ObjectHandleOnStack target, void** arguments, ObjectHandleOnStack sig, Interop.BOOL isConstructor, ObjectHandleOnStack result);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object? ReboxFromNullable(object? src);
[DebuggerStepThrough]
[DebuggerHidden]
internal static object? InvokeMethod(object? target, void** arguments, Signature sig, bool isConstructor)
{
object? result = null;
InvokeMethod(
ObjectHandleOnStack.Create(ref target),
arguments,
ObjectHandleOnStack.Create(ref sig),
isConstructor ? Interop.BOOL.TRUE : Interop.BOOL.FALSE,
ObjectHandleOnStack.Create(ref result));
return result;
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object ReboxToNullable(object? src, RuntimeType destNullableType);
/// <summary>
/// For a true boxed Nullable{T}, re-box to a boxed {T} or null, otherwise just return the input.
/// </summary>
internal static object? ReboxFromNullable(object? src)
{
// If src is null or not NullableOfT, just return that state.
if (src is null)
{
return null;
}

MethodTable* pMT = RuntimeHelpers.GetMethodTable(src);
if (!pMT->IsNullable)
{
return src;
}

return CastHelpers.ReboxFromNullable(pMT, src);
}

/// <summary>
/// Convert a boxed value of {T} (which is either {T} or null) to a true boxed Nullable{T}.
/// </summary>
internal static object ReboxToNullable(object? src, RuntimeType destNullableType)
{
Debug.Assert(destNullableType.IsNullableOfT);
MethodTable* pMT = destNullableType.GetNativeTypeHandle().AsMethodTable();
object obj = RuntimeTypeHandle.InternalAlloc(pMT);
GC.KeepAlive(destNullableType); // The obj instance will keep the type alive.

CastHelpers.Unbox_Nullable(
ref obj.GetRawData(),
pMT,
src);
return obj;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodInstantiation")]
private static partial void GetMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack types, Interop.BOOL fAsRuntimeTypeArray);
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6233,7 +6233,8 @@ class Compiler
#endif // DEBUG

weight_t GetCost(BasicBlock* block, BasicBlock* next);
bool TrySwappingPartitions(unsigned s1Start, unsigned s2Start, unsigned s3Start, unsigned s3End, unsigned s4End);
weight_t GetPartitionCostDelta(unsigned s1Start, unsigned s2Start, unsigned s3Start, unsigned s3End, unsigned s4End);
void SwapPartitions(unsigned s1Start, unsigned s2Start, unsigned s3Start, unsigned s3End, unsigned s4End);

void ConsiderEdge(FlowEdge* edge);
void AddNonFallthroughSuccs(unsigned blockPos);
Expand Down
Loading

0 comments on commit ece3176

Please sign in to comment.