From 858d47b74ac2de4b76a23a0545e4c3a9396ae573 Mon Sep 17 00:00:00 2001 From: LNTUyhy <1261137940@qq.com> Date: Sat, 27 Jun 2026 16:03:37 +0800 Subject: [PATCH 1/3] perf(evm): skip zero-size calldata and code copies Return early from JIT codegen when CALLDATACOPY or CODECOPY has a compile-time zero size. Avoid unnecessary runtime calls, gas-register sync, and memory-size reload work for copy opcodes that do not access memory. --- src/compiler/evm_frontend/evm_mir_compiler.cpp | 8 ++++++++ tests/evm_asm/calldatacopy_zero_size.easm | 11 +++++++++++ tests/evm_asm/calldatacopy_zero_size.evm.hex | 1 + tests/evm_asm/calldatacopy_zero_size.expected | 8 ++++++++ 4 files changed, 28 insertions(+) create mode 100644 tests/evm_asm/calldatacopy_zero_size.easm create mode 100644 tests/evm_asm/calldatacopy_zero_size.evm.hex create mode 100644 tests/evm_asm/calldatacopy_zero_size.expected diff --git a/src/compiler/evm_frontend/evm_mir_compiler.cpp b/src/compiler/evm_frontend/evm_mir_compiler.cpp index 660b8b87..1b4083c9 100644 --- a/src/compiler/evm_frontend/evm_mir_compiler.cpp +++ b/src/compiler/evm_frontend/evm_mir_compiler.cpp @@ -4552,6 +4552,10 @@ typename EVMMirBuilder::Operand EVMMirBuilder::handleCodeSize() { void EVMMirBuilder::handleCodeCopy(Operand DestOffsetComponents, Operand OffsetComponents, Operand SizeComponents) { + if (SizeComponents.isConstU64() && SizeComponents.getConstValue()[0] == 0) { + return; + } + const auto &RuntimeFunctions = getRuntimeFunctionTable(); normalizeOffsetWithSize(DestOffsetComponents, SizeComponents); uint64_t Non64Value = std::numeric_limits::max(); @@ -6715,6 +6719,10 @@ MInstruction *EVMMirBuilder::getCurrentInstancePointer() { void EVMMirBuilder::handleCallDataCopy(Operand DestOffsetComponents, Operand OffsetComponents, Operand SizeComponents) { + if (SizeComponents.isConstU64() && SizeComponents.getConstValue()[0] == 0) { + return; + } + const auto &RuntimeFunctions = getRuntimeFunctionTable(); uint64_t Non64Value = std::numeric_limits::max(); normalizeOperandU64(DestOffsetComponents, &Non64Value); diff --git a/tests/evm_asm/calldatacopy_zero_size.easm b/tests/evm_asm/calldatacopy_zero_size.easm new file mode 100644 index 00000000..4a566da2 --- /dev/null +++ b/tests/evm_asm/calldatacopy_zero_size.easm @@ -0,0 +1,11 @@ +// CALLDATACOPY with size 0 must not access or expand memory +PUSH1 0x2a +PUSH1 0x00 +MSTORE +PUSH1 0x00 +PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +CALLDATACOPY +PUSH1 0x20 +PUSH1 0x00 +RETURN diff --git a/tests/evm_asm/calldatacopy_zero_size.evm.hex b/tests/evm_asm/calldatacopy_zero_size.evm.hex new file mode 100644 index 00000000..b2629f59 --- /dev/null +++ b/tests/evm_asm/calldatacopy_zero_size.evm.hex @@ -0,0 +1 @@ +602A60005260007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3760206000F3 diff --git a/tests/evm_asm/calldatacopy_zero_size.expected b/tests/evm_asm/calldatacopy_zero_size.expected new file mode 100644 index 00000000..b307f162 --- /dev/null +++ b/tests/evm_asm/calldatacopy_zero_size.expected @@ -0,0 +1,8 @@ +status: success +error_code: 0 +stack: [] +memory: '000000000000000000000000000000000000000000000000000000000000002a' +storage: {} +transient_storage: {} +return: '000000000000000000000000000000000000000000000000000000000000002a' +events: [] From bd743b3086ca615498014ca2bd81479649b793d6 Mon Sep 17 00:00:00 2001 From: LNTUyhy <1261137940@qq.com> Date: Sat, 27 Jun 2026 19:01:16 +0800 Subject: [PATCH 2/3] test(evm): fix zero-size calldata copy fixture --- tests/evm_asm/calldatacopy_zero_size.easm | 2 +- tests/evm_asm/calldatacopy_zero_size.evm.hex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/evm_asm/calldatacopy_zero_size.easm b/tests/evm_asm/calldatacopy_zero_size.easm index 4a566da2..4628d5dd 100644 --- a/tests/evm_asm/calldatacopy_zero_size.easm +++ b/tests/evm_asm/calldatacopy_zero_size.easm @@ -4,7 +4,7 @@ PUSH1 0x00 MSTORE PUSH1 0x00 PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +PUSH1 0x00 CALLDATACOPY PUSH1 0x20 PUSH1 0x00 diff --git a/tests/evm_asm/calldatacopy_zero_size.evm.hex b/tests/evm_asm/calldatacopy_zero_size.evm.hex index b2629f59..b85fb582 100644 --- a/tests/evm_asm/calldatacopy_zero_size.evm.hex +++ b/tests/evm_asm/calldatacopy_zero_size.evm.hex @@ -1 +1 @@ -602A60005260007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3760206000F3 +602A60005260007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60003760206000F3 From 7e5b1ca11b5fa5a147b18798eca87e4534fbba48 Mon Sep 17 00:00:00 2001 From: LNTUyhy <1261137940@qq.com> Date: Sat, 27 Jun 2026 19:20:54 +0800 Subject: [PATCH 3/3] test(evm): fix zero-size calldata expected output --- tests/evm_asm/calldatacopy_zero_size.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/evm_asm/calldatacopy_zero_size.expected b/tests/evm_asm/calldatacopy_zero_size.expected index b307f162..d7ed191d 100644 --- a/tests/evm_asm/calldatacopy_zero_size.expected +++ b/tests/evm_asm/calldatacopy_zero_size.expected @@ -1,8 +1,8 @@ status: success error_code: 0 stack: [] -memory: '000000000000000000000000000000000000000000000000000000000000002a' +memory: '000000000000000000000000000000000000000000000000000000000000002A' storage: {} transient_storage: {} -return: '000000000000000000000000000000000000000000000000000000000000002a' +return: '000000000000000000000000000000000000000000000000000000000000002A' events: []