Skip to content
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: 2 additions & 0 deletions EVMOneUnitTestsRunList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ multi_vm/evm.eip2929_sload_cold/external_vm
multi_vm/evm.eip2929_sload_two_slots/external_vm
multi_vm/evm.eip2929_sload_warm/external_vm
multi_vm/evm.eip2929_delegatecall_cold/external_vm
multi_vm/evm.evmone_block_gas_cost_overflow_create/external_vm
multi_vm/evm.evmone_block_stack_req_overflow/external_vm
multi_vm/evm.basefee_nominal_case/external_vm
multi_vm/evm.push0/external_vm
multi_vm/evm.push0_return_empty/external_vm
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ class Runtime final {

const RuntimeConfig &getConfig() const { return Config; }

void setConfig(const RuntimeConfig &NewConfig) { Config = NewConfig; }

utils::Statistics &getStatistics() { return Stats; }

void startCPUTracing();
Expand Down
26 changes: 26 additions & 0 deletions src/vm/dt_evmc_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ namespace {
using namespace zen::runtime;
using namespace zen::common;

// JIT compilation limits (95% < 10KB)
const size_t MAX_JIT_BYTECODE_SIZE = 0x6000;

// RAII helper for temporarily changing runtime configuration
class ScopedConfig {
public:
ScopedConfig(Runtime *Runtime, const RuntimeConfig &NewConfig)
: RT(Runtime), PreviousConfig(Runtime->getConfig()) {
RT->setConfig(NewConfig);
}

~ScopedConfig() { RT->setConfig(PreviousConfig); }

private:
Runtime *RT;
RuntimeConfig PreviousConfig;
};

// CRC32 checksum
uint32_t crc32(const uint8_t *Data, size_t Size) {
static uint32_t Table[256];
Expand Down Expand Up @@ -126,6 +144,14 @@ evmc_result execute(evmc_vm *EVMInstance, const evmc_host_interface *Host,
if (!VM->RT) {
VM->RT = Runtime::newEVMRuntime(VM->Config, VM->ExecHost.get());
}
// Use interpreter mode for large bytecode
std::unique_ptr<ScopedConfig> TempConfig;
if (VM->Config.Mode == RunMode::MultipassMode &&
CodeSize > MAX_JIT_BYTECODE_SIZE) {
RuntimeConfig NewConfig = VM->Config;
NewConfig.Mode = RunMode::InterpMode;
TempConfig = std::make_unique<ScopedConfig>(VM->RT.get(), NewConfig);
}

uint32_t CheckSum = crc32(Code, CodeSize);
auto ModRet = VM->RT->loadEVMModule(std::to_string(CheckSum), Code, CodeSize);
Expand Down