Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move ReferenceCounter to an interface #3524

Merged
merged 6 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/Neo.VM.Benchmarks/TestArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public TestArray(IEnumerable<StackItem>? items = null)
/// </summary>
/// <param name="referenceCounter">The <see cref="ReferenceCounter"/> to be used by this array.</param>
/// <param name="items">The items to be included in the array.</param>
public TestArray(ReferenceCounter? referenceCounter, IEnumerable<StackItem>? items = null)
public TestArray(IReferenceCounter? referenceCounter, IEnumerable<StackItem>? items = null)
: base(referenceCounter)
{
_array = items switch
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Neo.VM.Benchmarks/TestStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public TestStruct(IEnumerable<StackItem>? fields = null)
/// </summary>
/// <param name="referenceCounter">The <see cref="ReferenceCounter"/> to be used by this structure.</param>
/// <param name="fields">The fields to be included in the structure.</param>
public TestStruct(ReferenceCounter? referenceCounter, IEnumerable<StackItem>? fields = null)
public TestStruct(IReferenceCounter? referenceCounter, IEnumerable<StackItem>? fields = null)
: base(referenceCounter, fields)
{
}
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
_ = root.DeepCopy();
}

private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1, ReferenceCounter? referenceCounter = null)
private static void CreateNestedArray(Array? rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter? referenceCounter = null)
{
if (depth < 0)
{
Expand All @@ -95,7 +95,7 @@
}
}

private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1, ReferenceCounter referenceCounter = null)
private static void CreateNestedTestArray(TestArray rootArray, int depth, int elementsPerLevel = 1, IReferenceCounter referenceCounter = null)

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test-Everything

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test-Everything

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in benchmarks/Neo.VM.Benchmarks/VMTypes/Benchmarks_DeepCopy.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Cannot convert null literal to non-nullable reference type.
{
if (depth < 0)
{
Expand Down
8 changes: 4 additions & 4 deletions src/Neo.VM/EvaluationStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace Neo.VM
/// </summary>
public sealed class EvaluationStack : IReadOnlyList<StackItem>
{
private readonly List<StackItem> innerList = new();
private readonly ReferenceCounter referenceCounter;
private readonly List<StackItem> innerList = [];
private readonly IReferenceCounter referenceCounter;

internal ReferenceCounter ReferenceCounter => referenceCounter;
internal IReferenceCounter ReferenceCounter => referenceCounter;

internal EvaluationStack(ReferenceCounter referenceCounter)
internal EvaluationStack(IReferenceCounter referenceCounter)
{
this.referenceCounter = referenceCounter;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/ExecutionContext.SharedStates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private class SharedStates
public Slot? StaticFields;
public readonly Dictionary<Type, object> States;

public SharedStates(Script script, ReferenceCounter referenceCounter)
public SharedStates(Script script, IReferenceCounter referenceCounter)
{
Script = script;
EvaluationStack = new EvaluationStack(referenceCounter);
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public Instruction? NextInstruction
}
}

internal ExecutionContext(Script script, int rvcount, ReferenceCounter referenceCounter)
internal ExecutionContext(Script script, int rvcount, IReferenceCounter referenceCounter)
: this(new SharedStates(script, referenceCounter), rvcount, 0)
{
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/ExecutionEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class ExecutionEngine : IDisposable
/// <summary>
/// Used for reference counting of objects in the VM.
/// </summary>
public ReferenceCounter ReferenceCounter { get; }
public IReferenceCounter ReferenceCounter { get; }

/// <summary>
/// The invocation stack of the VM.
Expand Down
91 changes: 91 additions & 0 deletions src/Neo.VM/IReferenceCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// IReferenceCounter.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.VM.Types;

namespace Neo.VM
{
/// <summary>
/// Used for reference counting of objects in the VM.
/// </summary>
public interface IReferenceCounter
{
/// <summary>
/// Gets the count of references.
/// </summary>
int Count { get; }

/// <summary>
/// Adds an item to the zero-referred list.
///
/// This method is used when an item has no remaining references.
/// It adds the item to the zero-referred list to be checked for cleanup later.
///
/// Use this method when you detect that an item has zero references and may need to be cleaned up.
/// </summary>
/// <param name="item">The item to add.</param>
void AddZeroReferred(StackItem item);

/// <summary>
/// Adds a reference to a specified item with a parent compound type.
///
/// This method is used when an item gains a new reference through a parent compound type.
/// It increments the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to add a reference from a compound type to a stack item.
/// </summary>
/// <param name="item">The item to add a reference to.</param>
/// <param name="parent">The parent compound type.</param>
void AddReference(StackItem item, CompoundType parent);

/// <summary>
/// Adds a stack reference to a specified item with a count.
///
/// This method is used when an item gains a new stack reference, usually due to being pushed onto the evaluation stack.
/// It increments the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to add one or more stack references to a stack item.
/// </summary>
/// <param name="item">The item to add a stack reference to.</param>
/// <param name="count">The number of references to add.</param>
void AddStackReference(StackItem item, int count = 1);

/// <summary>
/// Removes a reference from a specified item with a parent compound type.
///
/// This method is used when an item loses a reference from a parent compound type.
/// It decrements the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to remove a reference from a compound type to a stack item.
/// </summary>
/// <param name="item">The item to remove a reference from.</param>
/// <param name="parent">The parent compound type.</param>
void RemoveReference(StackItem item, CompoundType parent);

/// <summary>
/// Removes a stack reference from a specified item.
///
/// This method is used when an item loses a stack reference, usually due to being popped off the evaluation stack.
/// It decrements the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to remove one or more stack references from a stack item.
/// </summary>
/// <param name="item">The item to remove a stack reference from.</param>
void RemoveStackReference(StackItem item);

/// <summary>
/// Checks and processes items that have zero references.
/// This method is used to check items in the zero-referred list and clean up those that are no longer needed.
/// </summary>
/// <returns>The current reference count.</returns>
int CheckZeroReferred();
}
}
72 changes: 13 additions & 59 deletions src/Neo.VM/ReferenceCounter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Neo.VM
/// <summary>
/// Used for reference counting of objects in the VM.
/// </summary>
public sealed class ReferenceCounter
public sealed class ReferenceCounter : IReferenceCounter
{
// If set to true, all items will be tracked regardless of their type.
private const bool TrackAllItems = false;
Expand All @@ -38,9 +38,7 @@ public sealed class ReferenceCounter
// Keeps the total count of references.
private int _referencesCount = 0;

/// <summary>
/// Gets the count of references.
/// </summary>
/// <inheritdoc/>
public int Count => _referencesCount;

/// <summary>
Expand All @@ -61,17 +59,8 @@ private static bool NeedTrack(StackItem item)
return false;
}

/// <summary>
/// Adds a reference to a specified item with a parent compound type.
///
/// This method is used when an item gains a new reference through a parent compound type.
/// It increments the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to add a reference from a compound type to a stack item.
/// </summary>
/// <param name="item">The item to add a reference to.</param>
/// <param name="parent">The parent compound type.</param>
internal void AddReference(StackItem item, CompoundType parent)
/// <inheritdoc/>
public void AddReference(StackItem item, CompoundType parent)
{
// Increment the reference count.
_referencesCount++;
Expand All @@ -98,17 +87,8 @@ internal void AddReference(StackItem item, CompoundType parent)
pEntry.References++;
}

/// <summary>
/// Adds a stack reference to a specified item with a count.
///
/// This method is used when an item gains a new stack reference, usually due to being pushed onto the evaluation stack.
/// It increments the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to add one or more stack references to a stack item.
/// </summary>
/// <param name="item">The item to add a stack reference to.</param>
/// <param name="count">The number of references to add.</param>
internal void AddStackReference(StackItem item, int count = 1)
/// <inheritdoc/>
public void AddStackReference(StackItem item, int count = 1)
{
// Increment the reference count by the specified count.
_referencesCount += count;
Expand All @@ -127,16 +107,8 @@ internal void AddStackReference(StackItem item, int count = 1)
_zeroReferred.Remove(item);
}

/// <summary>
/// Adds an item to the zero-referred list.
///
/// This method is used when an item has no remaining references.
/// It adds the item to the zero-referred list to be checked for cleanup later.
///
/// Use this method when you detect that an item has zero references and may need to be cleaned up.
/// </summary>
/// <param name="item">The item to add.</param>
internal void AddZeroReferred(StackItem item)
/// <inheritdoc/>
public void AddZeroReferred(StackItem item)
{
// Add the item to the _zeroReferred set.
_zeroReferred.Add(item);
Expand All @@ -158,7 +130,7 @@ internal void AddZeroReferred(StackItem item)
/// Use this method periodically to clean up items with zero references and free up memory.
/// </summary>
/// <returns>The current reference count.</returns>
internal int CheckZeroReferred()
public int CheckZeroReferred()
{
// If there are items with zero references, process them.
if (_zeroReferred.Count > 0)
Expand Down Expand Up @@ -241,18 +213,8 @@ internal int CheckZeroReferred()
return _referencesCount;
}


/// <summary>
/// Removes a reference from a specified item with a parent compound type.
///
/// This method is used when an item loses a reference from a parent compound type.
/// It decrements the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to remove a reference from a compound type to a stack item.
/// </summary>
/// <param name="item">The item to remove a reference from.</param>
/// <param name="parent">The parent compound type.</param>
internal void RemoveReference(StackItem item, CompoundType parent)
/// <inheritdoc/>
public void RemoveReference(StackItem item, CompoundType parent)
{
// Decrement the reference count.
_referencesCount--;
Expand All @@ -271,16 +233,8 @@ internal void RemoveReference(StackItem item, CompoundType parent)
_zeroReferred.Add(item);
}

/// <summary>
/// Removes a stack reference from a specified item.
///
/// This method is used when an item loses a stack reference, usually due to being popped off the evaluation stack.
/// It decrements the reference count and updates the tracking structures if necessary.
///
/// Use this method when you need to remove one or more stack references from a stack item.
/// </summary>
/// <param name="item">The item to remove a stack reference from.</param>
internal void RemoveStackReference(StackItem item)
/// <inheritdoc/>
public void RemoveStackReference(StackItem item)
{
// Decrement the reference count.
_referencesCount--;
Expand Down
6 changes: 3 additions & 3 deletions src/Neo.VM/Slot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Neo.VM
/// </summary>
public class Slot : IReadOnlyList<StackItem>
{
private readonly ReferenceCounter referenceCounter;
private readonly IReferenceCounter referenceCounter;
private readonly StackItem[] items;

/// <summary>
Expand Down Expand Up @@ -53,7 +53,7 @@ internal set
/// </summary>
/// <param name="items">The items to be contained.</param>
/// <param name="referenceCounter">The reference counter to be used.</param>
public Slot(StackItem[] items, ReferenceCounter referenceCounter)
public Slot(StackItem[] items, IReferenceCounter referenceCounter)
{
this.referenceCounter = referenceCounter;
this.items = items;
Expand All @@ -66,7 +66,7 @@ public Slot(StackItem[] items, ReferenceCounter referenceCounter)
/// </summary>
/// <param name="count">Indicates the number of items contained in the slot.</param>
/// <param name="referenceCounter">The reference counter to be used.</param>
public Slot(int count, ReferenceCounter referenceCounter)
public Slot(int count, IReferenceCounter referenceCounter)
{
this.referenceCounter = referenceCounter;
items = new StackItem[count];
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/Types/Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public Array(IEnumerable<StackItem>? items = null)
/// </summary>
/// <param name="referenceCounter">The <see cref="ReferenceCounter"/> to be used by this array.</param>
/// <param name="items">The items to be included in the array.</param>
public Array(ReferenceCounter? referenceCounter, IEnumerable<StackItem>? items = null)
public Array(IReferenceCounter? referenceCounter, IEnumerable<StackItem>? items = null)
: base(referenceCounter)
{
_array = items switch
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.VM/Types/CompoundType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public abstract class CompoundType : StackItem
/// <summary>
/// The reference counter used to count the items in the VM object.
/// </summary>
protected internal readonly ReferenceCounter? ReferenceCounter;
protected internal readonly IReferenceCounter? ReferenceCounter;

/// <summary>
/// Create a new <see cref="CompoundType"/> with the specified reference counter.
/// </summary>
/// <param name="referenceCounter">The reference counter to be used.</param>
protected CompoundType(ReferenceCounter? referenceCounter)
protected CompoundType(IReferenceCounter? referenceCounter)
{
ReferenceCounter = referenceCounter;
referenceCounter?.AddZeroReferred(this);
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/Types/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public StackItem this[PrimitiveType key]
/// Create a new map with the specified reference counter.
/// </summary>
/// <param name="referenceCounter">The reference counter to be used.</param>
public Map(ReferenceCounter? referenceCounter = null)
public Map(IReferenceCounter? referenceCounter = null)
: base(referenceCounter)
{
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.VM/Types/Struct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public Struct(IEnumerable<StackItem>? fields = null)
/// </summary>
/// <param name="referenceCounter">The <see cref="ReferenceCounter"/> to be used by this structure.</param>
/// <param name="fields">The fields to be included in the structure.</param>
public Struct(ReferenceCounter? referenceCounter, IEnumerable<StackItem>? fields = null)
public Struct(IReferenceCounter? referenceCounter, IEnumerable<StackItem>? fields = null)
: base(referenceCounter, fields)
{
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override JObject ToJson()
return json;
}

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
public override StackItem ToStackItem(IReferenceCounter referenceCounter)
{
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public override JObject ToJson()
return json;
}

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
public override StackItem ToStackItem(IReferenceCounter referenceCounter)
{
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Expression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public override JObject ToJson()
return json;
}

public override StackItem ToStackItem(ReferenceCounter referenceCounter)
public override StackItem ToStackItem(IReferenceCounter referenceCounter)
{
var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
result.Add(Hash.ToArray());
Expand Down
Loading
Loading