Skip to content

Commit

Permalink
Nullability changes
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams committed Aug 31, 2020
1 parent 7753168 commit 0d53ed8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 43 deletions.
15 changes: 11 additions & 4 deletions src/Compilers/Core/Portable/CodeGen/TokenMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Microsoft.Cci;

Expand All @@ -28,9 +29,7 @@ internal sealed class TokenMap
private object[] _items = Array.Empty<object>();
private int _count = 0;

internal TokenMap()
{
}
internal TokenMap() { }

public uint GetOrAddTokenFor(IReference item, out bool referenceAdded)
{
Expand Down Expand Up @@ -95,18 +94,26 @@ private uint AddItem(IReferenceOrISignatureEquivalent item, out bool referenceAd

public object GetItem(uint token)
{
// If a token has been handed out, then it should be always within _count of the
// current array and a lock is not required.
Debug.Assert(token < (uint)_count && _count <= _items.Length);

return _items[(int)token];
}

//TODO: why is this is called twice during emit?
// should probably return ROA instead of IE and cache that in Module. (and no need to return count)
public ReadOnlySpan<object> GetAllItems()
{
// Read _count before _items reference, to match inverse of the writes in AddItem.
// So _items is guaranteed to have at least count items; and a lock is not required.

// Read the count prior to getting the array
int count = Volatile.Read(ref _count);
// Read the array reference
object[] items = Volatile.Read(ref _items);

// Return a right sized copy of the array
// Return a right sized view of the array based on read count and reference.
return new ReadOnlySpan<object>(items, 0, count);
}
}
Expand Down
56 changes: 17 additions & 39 deletions src/Compilers/Core/Portable/IReferenceOrISignature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,30 @@ namespace Microsoft.CodeAnalysis
/// </summary>
internal readonly struct IReferenceOrISignatureEquivalent : IEquatable<IReferenceOrISignatureEquivalent>
{
private readonly object? _item;
private readonly object _item;

public IReferenceOrISignatureEquivalent(IReference item)
{
_item = item;
}
public IReferenceOrISignatureEquivalent(IReference item) => _item = item;

public IReferenceOrISignatureEquivalent(ISignature item)
{
_item = item;
}
public IReferenceOrISignatureEquivalent(ISignature item) => _item = item;

// Needed to resolve ambiguity for types that implement both IReference and ISignature
public IReferenceOrISignatureEquivalent(IMethodReference item)
{
_item = item;
}
public IReferenceOrISignatureEquivalent(IMethodReference item) => _item = item;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(IReferenceOrISignatureEquivalent other)
{
// Fast inlinable ReferenceEquals
object? x = _item;
object? y = other._item;
if (x is null)
{
return y is null;
}
else if (ReferenceEquals(x, y))
var x = _item;
var y = other._item;
if (ReferenceEquals(x, y))
{
return true;
}

return EqualsSlow(x, y);
}

private static bool EqualsSlow(object x, object? y)
private static bool EqualsSlow(object x, object y)
{
if (x is ISymbolInternal sx && y is ISymbolInternal sy)
{
Expand All @@ -75,35 +62,26 @@ private static bool EqualsSlow(object x, object? y)

public override bool Equals(object? obj) => false;

public override int GetHashCode() => _item?.GetHashCode() ?? 0;
public override int GetHashCode() => _item.GetHashCode();

public override string ToString() => _item?.ToString() ?? "null";
public override string ToString() => _item.ToString() ?? "null";

internal object AsObject() => _item!;
internal object AsObject() => _item;
}

/// <summary>
/// Used to devirtualize ConcurrentDictionary for EqualityComparer{T}.Default and ReferenceEquals
/// </summary>
internal readonly struct IReferenceOrISignature : IEquatable<IReferenceOrISignature>
{
private readonly object? _item;
private readonly object _item;

public IReferenceOrISignature(IReference item)
{
_item = item;
}
public IReferenceOrISignature(IReference item) => _item = item;

public IReferenceOrISignature(ISignature item)
{
_item = item;
}
public IReferenceOrISignature(ISignature item) => _item = item;

// Used by implicit conversion
private IReferenceOrISignature(object? item)
{
_item = item;
}
private IReferenceOrISignature(object item) => _item = item;

public static implicit operator IReferenceOrISignature(IReferenceOrISignatureEquivalent item)
=> new IReferenceOrISignature(item.AsObject());
Expand All @@ -112,8 +90,8 @@ public static implicit operator IReferenceOrISignature(IReferenceOrISignatureEqu

public override bool Equals(object? obj) => false;

public override int GetHashCode() => _item?.GetHashCode() ?? 0;
public override int GetHashCode() => _item.GetHashCode();

public override string ToString() => _item?.ToString() ?? "null";
public override string ToString() => _item.ToString() ?? "null";
}
}

0 comments on commit 0d53ed8

Please sign in to comment.