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

IL-EVM: Increase test coverage for JIT equivalence tests. #7970

Merged
merged 6 commits into from
Dec 24, 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 src/Nethermind/Nethermind.Benchmark.Runner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public static void RunEvmBenchmarks(Options options)
else
{
string bytecode = options.ByteCode;
if(Path.Exists(bytecode))
if (Path.Exists(bytecode))
{
bytecode = File.ReadAllText(bytecode);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public void Run()
Span<byte> stack = _evmState.DataStack;
EvmStack<TIsTracing> _stack = new(in _evmState.DataStackHead, _txTracer, stack);
_methodInfo(_evmState, ref _stack, long.MaxValue, _spec);

}

public void Reset()
Expand Down
420 changes: 409 additions & 11 deletions src/Nethermind/Nethermind.Evm.Test/CodeAnalysis/IlEvmTests.cs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ protected T ExecuteBlock<T>(T tracer, byte[] code, ForkActivation? forkActivatio
return tracer;
}

protected T Execute<T>(T tracer, byte[] code, ForkActivation? forkActivation = null, long gasLimit = 100000) where T : ITxTracer
protected T Execute<T>(T tracer, byte[] code, ForkActivation? forkActivation = null, long gasLimit = 100000, byte[][]? blobVersionedHashes = null) where T : ITxTracer
{
(Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, gasLimit, code);
(Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, gasLimit, code, blobVersionedHashes: blobVersionedHashes);
_processor.Execute(transaction, block.Header, tracer);
return tracer;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Nethermind.Evm.CodeAnalysis
{
public class CodeInfo : IThreadPoolWorkItem
{
public Address? Address { get; init; }
public Address? Address { get; init; }
public ReadOnlyMemory<byte> MachineCode { get; }
public IPrecompile? Precompile { get; set; }

Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/ILCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private static int[] EmitSegmentBody(Emit<ExecuteSegment> method, ContractMetada
{
currentSegment = segmentMetadata.SubSegments[i];
}
// if tracing mode is off,
// if tracing mode is off,
if (!bakeInTracerCalls)
{
// we skip compiling unreachable code
Expand Down Expand Up @@ -268,7 +268,7 @@ private static int[] EmitSegmentBody(Emit<ExecuteSegment> method, ContractMetada
// if tracing is off, we check the stackHeadRef requirement of the full jumpless segment at once
if (!bakeInTracerCalls)
{
// we check if stackHeadRef underflow can occur
// we check if stackHeadRef underflow can occur
if (currentSegment.RequiredStack != 0)
{
method.LoadLocal(stackHeadIdx);
Expand Down
12 changes: 7 additions & 5 deletions src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/ILExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ public static void EmitIsOneCheck<T>(this Emit<T> il, Local? word = null)
{
MethodInfo methodInfo = typeof(Word).GetProperty(nameof(Word.IsOneLittleEndian)).GetMethod;
il.Call(methodInfo);
} else
}
else
{
MethodInfo methodInfo = typeof(Word).GetProperty(nameof(Word.IsOneBigEndian)).GetMethod;
il.Call(methodInfo);
Expand Down Expand Up @@ -166,7 +167,7 @@ public static void EmitIsMinusOneCheck<T>(this Emit<T> il, Local? word = null)

public static void EmitIsZeroOrOneCheck<T>(this Emit<T> il, Local? word = null)
{
if(word is not null)
if (word is not null)
{
il.LoadLocalAddress(word);
}
Expand Down Expand Up @@ -273,7 +274,7 @@ public unsafe static Span<TResult> ReinterpretCast<TOriginal, TResult>(Span<TOri
/// </summary>
static class EmitExtensions
{

public static MethodInfo ConvertionImplicit<TFrom, TTo>() => ConvertionImplicit(typeof(TFrom), typeof(TTo));
public static MethodInfo ConvertionImplicit(Type tfrom, Type tto) => tfrom.GetMethod("op_Implicit", new[] { tto });
public static MethodInfo ConvertionExplicit<TFrom, TTo>() => ConvertionExplicit(typeof(TFrom), typeof(TTo));
Expand Down Expand Up @@ -329,7 +330,7 @@ public static void PrintString<T>(this Emit<T> il, string msg)
il.StoreLocal(local);
il.Print(local);
}


public static MethodInfo MethodInfo<T>(string name, Type returnType, Type[] argTypes, BindingFlags flags = BindingFlags.Public)
{
Expand Down Expand Up @@ -499,7 +500,8 @@ public static void FakeBranch<T>(this Emit<T> il, Sigil.Label label)

public static Sigil.Label AddExceptionLabel<T>(this Emit<T> il, Dictionary<EvmExceptionType, Sigil.Label> dict, EvmExceptionType evmExceptionType)
{
if(!dict.ContainsKey(evmExceptionType)) {
if (!dict.ContainsKey(evmExceptionType))
{
dict[evmExceptionType] = il.DefineLabel();
}
return dict[evmExceptionType];
Expand Down
13 changes: 7 additions & 6 deletions src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/IlAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
using static Nethermind.Evm.CodeAnalysis.IL.ILCompiler;
using IlevmMode = int;

[assembly : InternalsVisibleTo("Nethermind.Evm.Tests")]
[assembly : InternalsVisibleTo("Nethermind.Evm.Benchmarks")]
[assembly: InternalsVisibleTo("Nethermind.Evm.Tests")]
[assembly: InternalsVisibleTo("Nethermind.Evm.Benchmarks")]
namespace Nethermind.Evm.CodeAnalysis.IL;

/// <summary>
Expand All @@ -33,7 +33,7 @@ public class AnalysisWork(CodeInfo codeInfo, IlevmMode mode)
public static void Enqueue(CodeInfo codeInfo, IlevmMode mode, IVMConfig config, ILogger logger)
{
_queue.Enqueue(new AnalysisWork(codeInfo, mode));
if(config.AnalysisQueueMaxSize <= _queue.Count)
if (config.AnalysisQueueMaxSize <= _queue.Count)
{
Task.Run(() => AnalyzeQueue(config, logger));
}
Expand Down Expand Up @@ -207,7 +207,7 @@ internal static void SegmentCode(CodeInfo codeInfo, (OpcodeInfo[], byte[][]) cod
}
}

if(startSegment < codeData.Item1.Length)
if (startSegment < codeData.Item1.Length)
{
segments.Add(AnalyzeSegment(codeData.Item1, startSegment..));
}
Expand Down Expand Up @@ -326,7 +326,7 @@ internal static SegmentMetadata AnalyzeSegment(OpcodeInfo[] fullcode, Range segm
subSegment.LeftOutStack = currentStackSize;
if (op.IsTerminating || op.IsJump || op.Operation is Instruction.GAS)
{
if(op.Operation is not Instruction.GAS)
if (op.Operation is not Instruction.GAS)
{
subSegment.Start = subsegmentStart;
subSegment.RequiredStack = -subSegment.RequiredStack;
Expand All @@ -345,7 +345,8 @@ internal static SegmentMetadata AnalyzeSegment(OpcodeInfo[] fullcode, Range segm
hasInvalidOpcode = false;
costStart = pc + 1; // start with the next again
coststack = 0;
} else
}
else
{
subSegment.StaticGasSubSegmentes[costStart] = coststack; // remember the stackHeadRef chain of opcodes
costStart = pc + 1; // start with the next again
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ internal class D01P04EQ : IPatternChunk
{
public string Name => nameof(D01P04EQ);
public byte[] Pattern => [(byte)Instruction.DUP1, (byte)Instruction.PUSH4, (byte)Instruction.EQ];


public long GasCost(EvmState vmState, IReleaseSpec spec)
{
Expand Down
14 changes: 7 additions & 7 deletions src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/Word.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ internal struct Word

public bool IsZero => (_ulong0 | _ulong1 | _ulong2 | _ulong3) == 0;
public bool IsOneLittleEndian => (_ulong1 | _ulong2 | _ulong3) == 0 && _ulong0 == 1;
public bool IsOneBigEndian => (_ulong1 | _ulong2 | _ulong0 ) == 0 && _ulong3 == (1ul << 63);
public bool IsOneBigEndian => (_ulong1 | _ulong2 | _ulong0) == 0 && _ulong3 == (1ul << 63);
public bool IsMinusOne => _ulong1 == ulong.MaxValue || _ulong2 == ulong.MaxValue || _ulong3 == ulong.MaxValue && _ulong0 == ulong.MaxValue;
public bool IsP255LittleEndian => (_ulong0 | _ulong1 | _ulong2) == 0 && (_ulong3 == (1ul << 63));
public bool IsP255BigEndian => (_ulong0 | _ulong1 | _ulong2) == 0 && (_ulong0 == 1);
Expand All @@ -87,12 +87,12 @@ public void Negate()

}
ulong carry = 0;
if(AddWithCarry(_ulong0, 1, ref carry, out _ulong0))
if(AddWithCarry(_ulong1, carry, ref carry, out _ulong1))
if(AddWithCarry(_ulong2, carry, ref carry, out _ulong2))
AddWithCarry(_ulong3, carry, ref carry, out _ulong3);
if (AddWithCarry(_ulong0, 1, ref carry, out _ulong0))
if (AddWithCarry(_ulong1, carry, ref carry, out _ulong1))
if (AddWithCarry(_ulong2, carry, ref carry, out _ulong2))
AddWithCarry(_ulong3, carry, ref carry, out _ulong3);

if(BitConverter.IsLittleEndian)
if (BitConverter.IsLittleEndian)
{
_ulong0 = BinaryPrimitives.ReverseEndianness(_ulong0);
_ulong1 = BinaryPrimitives.ReverseEndianness(_ulong1);
Expand Down Expand Up @@ -309,7 +309,7 @@ public unsafe long LeadingZeros
}
}

public bool IsUint16 => _ulong1 == 0 && _ulong2 == 0 && _ulong3 == 0 && (BitConverter.IsLittleEndian ? (BinaryPrimitives.ReverseEndianness(_ulong0) <= ushort.MaxValue) : (_ulong0 <= ushort.MaxValue ));
public bool IsUint16 => _ulong1 == 0 && _ulong2 == 0 && _ulong3 == 0 && (BitConverter.IsLittleEndian ? (BinaryPrimitives.ReverseEndianness(_ulong0) <= ushort.MaxValue) : (_ulong0 <= ushort.MaxValue));
public bool IsUint32 => _ulong1 == 0 && _ulong2 == 0 && _ulong3 == 0 && (BitConverter.IsLittleEndian ? (BinaryPrimitives.ReverseEndianness(_ulong0) <= uint.MaxValue) : (_ulong0 <= uint.MaxValue));
public bool IsUint64 => _ulong1 == 0 && _ulong2 == 0 && _ulong3 == 0;

Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Evm/Config/IVMConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public interface IVMConfig : IConfig
public bool BakeInTracingInPartialAotMode { get; set; }

[ConfigItem(
Description = "Sets Analysis Queue Max Size",
Description = "Sets Analysis Queue Max Size",
DefaultValue = "8")]
public int AnalysisQueueMaxSize { get; set; }

Expand Down
10 changes: 5 additions & 5 deletions src/Nethermind/Nethermind.Evm/VirtualMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -718,13 +718,13 @@ private CallResult ExecuteCall<TTracingInstructions>(EvmState vmState, ReadOnlyM
if (!_txTracer.IsTracingRefunds)
{
return _txTracer.IsTracingOpLevelStorage
? ExecuteCode<TTracingInstructions, NotTracing, IsTracing>(vmState, ref stack, gasAvailable, spec)
? ExecuteCode<TTracingInstructions, NotTracing, IsTracing>(vmState, ref stack, gasAvailable, spec)
: ExecuteCode<TTracingInstructions, NotTracing, NotTracing>(vmState, ref stack, gasAvailable, spec);
}
else
{
return _txTracer.IsTracingOpLevelStorage
? ExecuteCode<TTracingInstructions, IsTracing, IsTracing>(vmState, ref stack, gasAvailable, spec)
return _txTracer.IsTracingOpLevelStorage
? ExecuteCode<TTracingInstructions, IsTracing, IsTracing>(vmState, ref stack, gasAvailable, spec)
: ExecuteCode<TTracingInstructions, IsTracing, NotTracing>(vmState, ref stack, gasAvailable, spec);
}
Empty:
Expand Down Expand Up @@ -770,7 +770,7 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
while ((uint)programCounter < codeLength)
{

if(typeof(TOptimizing) == typeof(IsOptimizing))
if (typeof(TOptimizing) == typeof(IsOptimizing))
{
var chunkExecutionResult = new ILChunkExecutionState(ref _returnDataBuffer);
while (ilInfo is not null && (ilInfo.TryExecute(_logger,
Expand Down Expand Up @@ -826,7 +826,7 @@ private CallResult ExecuteCode<TTracingInstructions, TTracingRefunds, TTracingSt
#if DEBUGDEBUG
debugger?.TryWait(ref vmState, ref programCounter, ref gasAvailable, ref stack.Head);
#endif

Instruction instruction = (Instruction)code[programCounter];

if (isCancelable && _txTracer.IsCancelled)
Expand Down