提交 80f2edbc 编写于 作者: R Rikki Gibson 提交者: GitHub

Revert "Use new Span/Memory APIs on System.Collections.Immutable (#38809)"

This reverts commit 6880a46e.
上级 c350cf34
......@@ -181,7 +181,7 @@
<SourceBrowserVersion>1.0.21</SourceBrowserVersion>
<StreamJsonRpcVersion>2.1.55</StreamJsonRpcVersion>
<SystemBuffersVersion>4.5.0</SystemBuffersVersion>
<SystemCollectionsImmutableVersion>1.6.0</SystemCollectionsImmutableVersion>
<SystemCollectionsImmutableVersion>1.5.0</SystemCollectionsImmutableVersion>
<SystemCommandLineExperimentalVersion>0.1.0-alpha-63729-01</SystemCommandLineExperimentalVersion>
<SystemCommandLineRenderingVersion>0.1.0-alpha-63729-01</SystemCommandLineRenderingVersion>
<SystemDrawingCommonVersion>4.5.0</SystemDrawingCommonVersion>
......
......@@ -9,7 +9,6 @@
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Threading;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
......@@ -839,8 +838,8 @@ private static void CompareAssemblies(string sourceTemplate, string change1, str
AssertEx.NotEqual(image1, image2, message: $"Expecting difference for includePrivateMembers={includePrivateMembers} case, but they matched.");
}
var mvid1 = BuildTasks.MvidReader.ReadAssemblyMvidOrEmpty(new ImmutableMemoryStream(image1));
var mvid2 = BuildTasks.MvidReader.ReadAssemblyMvidOrEmpty(new ImmutableMemoryStream(image2));
var mvid1 = BuildTasks.MvidReader.ReadAssemblyMvidOrEmpty(new MemoryStream(image1.DangerousGetUnderlyingArray()));
var mvid2 = BuildTasks.MvidReader.ReadAssemblyMvidOrEmpty(new MemoryStream(image2.DangerousGetUnderlyingArray()));
if (!includePrivateMembers)
{
......
......@@ -376,6 +376,17 @@ public void SelectAsArrayWithPredicate()
Assert.Empty(array.SelectAsArray<int, int>(item => item < 0, item => throw null));
}
[Fact]
public void DangerousCreateFromUnderlyingArray()
{
var array = new[] { 1, 2, 3, 4 };
var copy = array;
var immutable = ImmutableArrayExtensions.DangerousCreateFromUnderlyingArray(ref copy);
Assert.Null(copy);
AssertEx.Equal(array, immutable);
Assert.Same(array, ImmutableArrayExtensions.DangerousGetUnderlyingArray(immutable));
}
[Fact]
public void ZipAsArray()
{
......
......@@ -20,22 +20,17 @@ public void CreateInitialBaseline_Errors()
var peReader = peModule.Module.PEReaderOpt;
var mdBytes = peReader.GetMetadata().GetContent();
unsafe
{
fixed (byte* ptr = mdBytes.AsSpan())
{
var mdModule = ModuleMetadata.CreateFromMetadata((IntPtr)ptr, mdBytes.Length);
var mdBytesHandle = GCHandle.Alloc(mdBytes.DangerousGetUnderlyingArray(), GCHandleType.Pinned);
var mdModule = ModuleMetadata.CreateFromMetadata(mdBytesHandle.AddrOfPinnedObject(), mdBytes.Length);
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, debugInfoProvider));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null));
Assert.Throws<ArgumentException>(() => EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, debugInfoProvider));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null));
Assert.Throws<ArgumentException>(() => EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, debugInfoProvider, localSigProvider, true));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null, localSigProvider, true));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider, null, true));
Assert.NotNull(EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider, localSigProvider, true));
}
}
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, debugInfoProvider, localSigProvider, true));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null, localSigProvider, true));
Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider, null, true));
Assert.NotNull(EmitBaseline.CreateInitialBaseline(mdModule, debugInfoProvider, localSigProvider, true));
}
}
}
......@@ -6,7 +6,9 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis
......@@ -525,6 +527,27 @@ public static int Count<T>(this ImmutableArray<T> items, Func<T, bool> predicate
return count;
}
[StructLayout(LayoutKind.Sequential)]
private struct ImmutableArrayProxy<T>
{
internal T[] MutableArray;
}
// TODO(https://github.com/dotnet/corefx/issues/34126): Remove when System.Collections.Immutable
// provides a Span API
internal static T[] DangerousGetUnderlyingArray<T>(this ImmutableArray<T> array)
=> Unsafe.As<ImmutableArray<T>, ImmutableArrayProxy<T>>(ref array).MutableArray;
internal static ReadOnlySpan<T> AsSpan<T>(this ImmutableArray<T> array)
=> array.DangerousGetUnderlyingArray();
internal static ImmutableArray<T> DangerousCreateFromUnderlyingArray<T>(ref T[] array)
{
var proxy = new ImmutableArrayProxy<T> { MutableArray = array };
array = null;
return Unsafe.As<ImmutableArrayProxy<T>, ImmutableArray<T>>(ref proxy);
}
internal static Dictionary<K, ImmutableArray<T>> ToDictionary<K, T>(this ImmutableArray<T> items, Func<T, K> keySelector, IEqualityComparer<K> comparer = null)
{
if (items.Length == 1)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Buffers;
using System.Collections.Immutable;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
......@@ -11,28 +10,25 @@ namespace Roslyn.Test.Utilities
{
internal class PinnedBlob : IDisposable
{
private MemoryHandle _handle;
public unsafe IntPtr Pointer => (IntPtr)_handle.Pointer;
private GCHandle _bytes; // non-readonly as Free() mutates to prevent double-free.
public readonly IntPtr Pointer;
public readonly int Size;
public PinnedBlob(ReadOnlyMemory<byte> blob)
public PinnedBlob(ImmutableArray<byte> blob)
: this(blob.DangerousGetUnderlyingArray())
{
_handle = blob.Pin();
Size = blob.Length;
}
public PinnedBlob(ImmutableArray<byte> blob)
: this(blob.AsMemory())
{ }
public PinnedBlob(byte[] blob)
: this(blob.AsMemory())
{ }
public unsafe PinnedBlob(byte[] blob)
{
_bytes = GCHandle.Alloc(blob, GCHandleType.Pinned);
Pointer = _bytes.AddrOfPinnedObject();
Size = blob.Length;
}
public void Dispose()
{
_handle.Dispose();
_bytes.Free();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Buffers;
using System.Collections.Immutable;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
using Roslyn.Utilities;
namespace Roslyn.Test.Utilities
{
internal class PinnedMetadata : IDisposable
{
private MemoryHandle _handle;
public unsafe IntPtr Pointer => (IntPtr)_handle.Pointer;
private GCHandle _bytes; // non-readonly as Free() mutates to prevent double-free.
public readonly MetadataReader Reader;
public readonly IntPtr Pointer;
public readonly int Size;
public unsafe PinnedMetadata(ImmutableArray<byte> metadata)
{
_handle = metadata.AsMemory().Pin();
_bytes = GCHandle.Alloc(metadata.DangerousGetUnderlyingArray(), GCHandleType.Pinned);
this.Pointer = _bytes.AddrOfPinnedObject();
this.Size = metadata.Length;
this.Reader = new MetadataReader((byte*)_handle.Pointer, Size, MetadataReaderOptions.None, null);
this.Reader = new MetadataReader((byte*)this.Pointer, this.Size, MetadataReaderOptions.None, null);
}
public void Dispose()
{
_handle.Dispose();
_bytes.Free();
}
}
}
......@@ -5,27 +5,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
namespace Roslyn.Utilities
{
internal static class ImmutableArrayExtensions
{
[StructLayout(LayoutKind.Sequential)]
private struct ImmutableArrayProxy<T>
{
internal T[]? MutableArray;
}
internal static ImmutableArray<T> DangerousCreateFromUnderlyingArray<T>(ref T[]? array)
{
var proxy = new ImmutableArrayProxy<T> { MutableArray = array };
array = null;
return Unsafe.As<ImmutableArrayProxy<T>, ImmutableArray<T>>(ref proxy);
}
internal static bool Contains<T>(this ImmutableArray<T> items, T item, IEqualityComparer<T>? equalityComparer)
=> items.IndexOf(item, 0, equalityComparer) >= 0;
......
......@@ -239,7 +239,7 @@ public byte[] ToArray()
public ImmutableArray<byte> ToImmutableArray()
{
var array = ToArray();
return Roslyn.Utilities.ImmutableArrayExtensions.DangerousCreateFromUnderlyingArray(ref array);
return ImmutableArrayExtensions.DangerousCreateFromUnderlyingArray(ref array);
}
protected int CurrentChunkIndex { get { return GetChunkIndex(this.position); } }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册