Skip to content

Commit

Permalink
Only need single stack for stacks (#7375)
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams authored Sep 2, 2024
1 parent 29f2a20 commit 76d5fd6
Showing 1 changed file with 18 additions and 33 deletions.
51 changes: 18 additions & 33 deletions src/Nethermind/Nethermind.Evm/EvmState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,21 @@ public class EvmState : IDisposable // TODO: rename to CallState
private class StackPool
{
private readonly int _maxCallStackDepth;
private readonly struct StackItem(byte[] dataStack, int[] returnStack)
{
public readonly byte[] DataStack = dataStack;
public readonly int[] ReturnStack = returnStack;
}

// TODO: we have wrong call depth calculation somewhere
public StackPool(int maxCallStackDepth = VirtualMachine.MaxCallDepth * 2)
{
_maxCallStackDepth = maxCallStackDepth;
}

private readonly Stack<byte[]> _dataStackPool = new(32);
private readonly Stack<int[]> _returnStackPool = new(32);
private readonly Stack<StackItem> _stackPool = new(32);

private int _dataStackPoolDepth;
private int _returnStackPoolDepth;
private int _stackPoolDepth;

/// <summary>
/// The word 'return' acts here once as a verb 'to return stack to the pool' and once as a part of the
Expand All @@ -44,45 +47,27 @@ public StackPool(int maxCallStackDepth = VirtualMachine.MaxCallDepth * 2)
/// <param name="returnStack"></param>
public void ReturnStacks(byte[] dataStack, int[] returnStack)
{
_dataStackPool.Push(dataStack);
_returnStackPool.Push(returnStack);
_stackPool.Push(new(dataStack, returnStack));
}

private byte[] RentDataStack()
{
if (_dataStackPool.TryPop(out byte[] result))
{
return result;
}

_dataStackPoolDepth++;
if (_dataStackPoolDepth > _maxCallStackDepth)
{
EvmStack.ThrowEvmStackOverflowException();
}

return new byte[(EvmStack.MaxStackSize + EvmStack.RegisterLength) * 32];
}

private int[] RentReturnStack()
public (byte[], int[]) RentStacks()
{
if (_returnStackPool.TryPop(out int[] result))
if (_stackPool.TryPop(out StackItem result))
{
return result;
return (result.DataStack, result.ReturnStack);
}

_returnStackPoolDepth++;
if (_returnStackPoolDepth > _maxCallStackDepth)
_stackPoolDepth++;
if (_stackPoolDepth > _maxCallStackDepth)
{
EvmStack.ThrowEvmStackOverflowException();
}

return new int[EvmStack.ReturnStackSize];
}

public (byte[], int[]) RentStacks()
{
return (RentDataStack(), RentReturnStack());
return
(
new byte[(EvmStack.MaxStackSize + EvmStack.RegisterLength) * 32],
new int[EvmStack.ReturnStackSize]
);
}
}
private static readonly ThreadLocal<StackPool> _stackPool = new(() => new StackPool());
Expand Down

0 comments on commit 76d5fd6

Please sign in to comment.