From 04265beb88c4ce13c5102e6cdbf8237d975b5b2d Mon Sep 17 00:00:00 2001 From: starwarfan <519125404@qq.com> Date: Thu, 9 Apr 2026 17:12:01 +0800 Subject: [PATCH 1/3] fix: fix building on newer gcc --- src/platform/platform.h | 1 + src/utils/logging.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/platform/platform.h b/src/platform/platform.h index a8b2c4f25..d299c7291 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/src/utils/logging.h b/src/utils/logging.h index 58df7f2d7..423037546 100644 --- a/src/utils/logging.h +++ b/src/utils/logging.h @@ -6,7 +6,9 @@ #include "common/defines.h" #include "platform/platform.h" +#include #include +#include #ifdef ZEN_ENABLE_SPDLOG namespace spdlog { From 93987f2a4509db5097779a6f5e1266c60d7794c1 Mon Sep 17 00:00:00 2001 From: starwarfan <519125404@qq.com> Date: Thu, 7 May 2026 10:13:54 +0800 Subject: [PATCH 2/3] fix(evm): stabilize multipass JIT for long Silkworm sync runs - Fix EVMCallThreadState::setJITTraces inverted Inst guard (was no-op for all real instances); align trap backtrace behavior with the WASM handler pattern. - Harden SAVE_EVM_HOSTAPI_FRAME_POINTER_TO_TLS with a do/while wrapper and assert an active TLS before UD2-based JIT traps; add required semicolon at the throwInstanceExceptionOnJIT call site. - dt_evmc_vm: per-VM recursive_mutex around execute(), clear per-instance message cache on top-level entry, empty-code CALL fast paths for multipass JIT, and default DisableMultipassGreedyRA with DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA override. - Execution cache / CREATE path hardening (evm_cache, evm_instance, evm_imported) from Silkworm integration stress testing. Validated: cmake --build build --target dtvmapi; multipass staged_pipeline forward past former crash block on mainnet snapshot data. --- src/common/evm_traphandler.cpp | 13 +---- src/common/evm_traphandler.h | 11 ++-- src/compiler/evm_frontend/evm_imported.cpp | 60 +++------------------- src/evm/evm_cache.cpp | 60 ++++++++++++++++++++++ src/runtime/evm_instance.cpp | 2 +- src/runtime/evm_instance.h | 11 ++-- src/vm/dt_evmc_vm.cpp | 47 +++++++++++++++++ 7 files changed, 133 insertions(+), 71 deletions(-) diff --git a/src/common/evm_traphandler.cpp b/src/common/evm_traphandler.cpp index e291f55b4..516764f2d 100644 --- a/src/common/evm_traphandler.cpp +++ b/src/common/evm_traphandler.cpp @@ -23,7 +23,6 @@ void EVMCallThreadState::setJITTraces() { return; } uint32_t IgnoredDepth = getTrapState().NumIgnoredFrames; - ZEN_ASSERT(Inst); void *JITCode = Inst->getModule()->getJITCode(); void *JITCodeEnd = static_cast(JITCode) + Inst->getModule()->getJITCodeSize(); @@ -120,14 +119,6 @@ bool initEVMPlatformTrapHandler() { // it. It will either crash synchronously, fix up the instruction // so that execution can continue and return, or trigger a crash by // returning the signal to it's original disposition and returning. - - // Unblock the signal before forwarding to the previous handler, - // preserving the same semantics as when SA_NODEFER was used. - sigset_t SignalSet; - sigemptyset(&SignalSet); - sigaddset(&SignalSet, SigNum); - int UnblockResult = sigprocmask(SIG_UNBLOCK, &SignalSet, nullptr); - ZEN_ASSERT(UnblockResult == 0); if ((PrevSigAction->sa_flags & SA_SIGINFO) != 0) { PrevSigAction->sa_sigaction(SigNum, SigInfo, Ctx); } else if ((void (*)(int))PrevSigAction->sa_sigaction == SIG_DFL || @@ -159,9 +150,9 @@ bool initEVMPlatformTrapHandler() { struct sigaction Handler; memset(&Handler, 0x0, sizeof(struct sigaction)); #ifdef ZEN_ENABLE_VIRTUAL_STACK - Handler.sa_flags = SA_SIGINFO | SA_ONSTACK; + Handler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; #else - Handler.sa_flags = SA_SIGINFO; + Handler.sa_flags = SA_SIGINFO | SA_NODEFER; #endif // ZEN_ENABLE_VIRTUAL_STACK Handler.sa_sigaction = TrapHandler; sigemptyset(&Handler.sa_mask); diff --git a/src/common/evm_traphandler.h b/src/common/evm_traphandler.h index 3008ecb5d..491846774 100644 --- a/src/common/evm_traphandler.h +++ b/src/common/evm_traphandler.h @@ -77,7 +77,7 @@ class EVMCallThreadState { void restartHandler() { Handling = true; } - void jmpToMarked(int Signum) { siglongjmp(*JmpBuf, Signum); } + void jmpToMarked(int Signum) { longjmp(*JmpBuf, Signum); } void setTrapFrameAddr(void *Addr, void *PC, void *FaultingAddress, uint32_t NumIgnoredFrames) { @@ -148,9 +148,12 @@ bool initEVMPlatformTrapHandler(); // may not used // so need set it when unwind backtrace after ud2 #define SAVE_EVM_HOSTAPI_FRAME_POINTER_TO_TLS \ - void *FrameAddr = __builtin_frame_address(0); \ - auto TLS = common::evm_traphandler::EVMCallThreadState::current(); \ - TLS->setTrapFrameAddr(FrameAddr, nullptr, nullptr, 0); + do { \ + void *FrameAddr = __builtin_frame_address(0); \ + auto *TLS_ = common::evm_traphandler::EVMCallThreadState::current(); \ + ZEN_ASSERT(TLS_ != nullptr); \ + TLS_->setTrapFrameAddr(FrameAddr, nullptr, nullptr, 0); \ + } while (0) #endif // ZEN_ENABLE_CPU_EXCEPTION diff --git a/src/compiler/evm_frontend/evm_imported.cpp b/src/compiler/evm_frontend/evm_imported.cpp index 5292db6e7..082dfbb50 100644 --- a/src/compiler/evm_frontend/evm_imported.cpp +++ b/src/compiler/evm_frontend/evm_imported.cpp @@ -102,42 +102,6 @@ inline void triggerStaticModeViolation(zen::runtime::EVMInstance *Instance) { zen::runtime::EVMInstance::triggerInstanceExceptionOnJIT( Instance, zen::common::ErrorCode::EVMStaticModeViolation); } - -constexpr uint8_t DelegationMagicBytes[] = {0xef, 0x01, 0x00}; - -bool resolveDelegatedCallCodeAddress(zen::runtime::EVMInstance *Instance, - evmc::address TargetAddr, - evmc::address &CodeAddr) { - CodeAddr = TargetAddr; - if (Instance->getRevision() < EVMC_PRAGUE) { - return true; - } - - const zen::runtime::EVMModule *Module = Instance->getModule(); - ZEN_ASSERT(Module && Module->Host); - uint8_t Designation[sizeof(DelegationMagicBytes) + sizeof(evmc::address)] = - {}; - const size_t Copied = - Module->Host->copy_code(TargetAddr, 0, Designation, sizeof(Designation)); - if (Copied < sizeof(DelegationMagicBytes) || - std::memcmp(Designation, DelegationMagicBytes, - sizeof(DelegationMagicBytes)) != 0) { - return true; - } - - if (Copied != sizeof(Designation)) { - return true; - } - - std::memcpy(CodeAddr.bytes, Designation + sizeof(DelegationMagicBytes), - sizeof(CodeAddr.bytes)); - const uint64_t DelegateAccessCost = - Module->Host->access_account(CodeAddr) == EVMC_ACCESS_COLD - ? zen::evm::COLD_ACCOUNT_ACCESS_COST - : zen::evm::WARM_STORAGE_READ_COST; - Instance->chargeGas(DelegateAccessCost); - return true; -} } // namespace const RuntimeFunctions &getRuntimeFunctionTable() { @@ -890,9 +854,13 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance, Instance->setReturnData(std::move(ReturnData)); if (Result.status_code == EVMC_SUCCESS) { - static thread_local uint8_t PaddedAddress[32] = {0}; - memcpy(PaddedAddress + 12, Result.create_address.bytes, 20); - return PaddedAddress; + // Keep returned CREATE addresses in per-instance cache to avoid aliasing + // between nested/re-entrant CREATE paths. + auto &ExecCache = Instance->getMessageCache(); + evmc::bytes32 PaddedAddress{}; + std::memcpy(PaddedAddress.bytes + 12, Result.create_address.bytes, 20); + ExecCache.CreateAddresses.push_back(PaddedAddress); + return ExecCache.CreateAddresses.back().bytes; } return ZeroAddress; } @@ -928,12 +896,6 @@ static uint64_t evmHandleCallInternal( Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST); } - evmc::address CodeAddr = TargetAddr; - if (!resolveDelegatedCallCodeAddress(Instance, TargetAddr, CodeAddr)) { - Instance->setReturnData({}); - return 0; - } - const bool HasValueArgs = CallKind == EVMC_CALL || CallKind == EVMC_CALLCODE; const bool HasValue = Value != 0; @@ -1032,16 +994,10 @@ static uint64_t evmHandleCallInternal( ? CurrentMsg->value : intx::be::store(Value), .create2_salt = {}, - .code_address = CodeAddr, + .code_address = TargetAddr, .code = nullptr, .code_size = 0, }; - if (std::memcmp(TargetAddr.bytes, CodeAddr.bytes, sizeof(TargetAddr.bytes)) != - 0) { - CallMsg.flags |= EVMC_DELEGATED; - } else { - CallMsg.flags &= ~uint32_t(EVMC_DELEGATED); - } Instance->pushMessage(&CallMsg); evmc::Result Result = Module->Host->call(CallMsg); diff --git a/src/evm/evm_cache.cpp b/src/evm/evm_cache.cpp index cc5a6208e..805ea42b1 100644 --- a/src/evm/evm_cache.cpp +++ b/src/evm/evm_cache.cpp @@ -200,6 +200,9 @@ struct GasBlock { }; static void addEdge(std::vector &Blocks, uint32_t From, uint32_t To) { + if (From >= Blocks.size() || To >= Blocks.size()) { + return; + } auto &FromSuccs = Blocks[From].Succs; if (std::find(FromSuccs.begin(), FromSuccs.end(), To) == FromSuccs.end()) { FromSuccs.push_back(To); @@ -223,6 +226,9 @@ static bool splitCriticalEdges(std::vector &Blocks, size_t CodeSize) { continue; // Not a critical edge source } for (uint32_t ToId : Blocks[FromId].Succs) { + if (ToId >= Blocks.size()) { + continue; + } if (Blocks[ToId].Preds.size() > 1) { // Critical edge: From has multiple succs, To has multiple preds EdgesToSplit.push_back({static_cast(FromId), ToId}); @@ -450,6 +456,9 @@ computeInCycle(const std::vector &Blocks) { while (!Stack.empty()) { const uint32_t Node = Stack.back(); Stack.pop_back(); + if (Node >= NumBlocks) { + continue; + } Component.push_back(Node); for (uint32_t Pred : Blocks[Node].Preds) { if (Pred >= NumBlocks) { @@ -468,6 +477,9 @@ computeInCycle(const std::vector &Blocks) { } continue; } + if (Component.empty()) { + continue; + } const uint32_t Only = Component.front(); for (uint32_t Succ : Blocks[Only].Succs) { @@ -528,7 +540,13 @@ computeReachable(const std::vector &Blocks, uint32_t EntryId) { while (!Stack.empty()) { const uint32_t Node = Stack.back(); Stack.pop_back(); + if (Node >= NumBlocks) { + continue; + } for (uint32_t Succ : Blocks[Node].Succs) { + if (Succ >= NumBlocks) { + continue; + } if (Reachable[Succ] == 0) { Reachable[Succ] = 1; Stack.push_back(Succ); @@ -571,6 +589,9 @@ computeDominators(const std::vector &Blocks, NewDom = All; bool HasPred = false; for (uint32_t Pred : Blocks[Node].Preds) { + if (Pred >= NumBlocks) { + continue; + } if (Reachable[Pred] == 0) { continue; } @@ -604,6 +625,9 @@ findBackEdgesUsingDominators(const std::vector &Blocks, for (size_t From = 0; From < NumBlocks; ++From) { for (uint32_t To : Blocks[From].Succs) { + if (To >= NumBlocks) { + continue; + } if (bitsetTest(Dom[From], To)) { BackEdges[From].push_back(To); } @@ -613,6 +637,9 @@ findBackEdgesUsingDominators(const std::vector &Blocks, static bool isBackEdge(const std::vector> &BackEdges, uint32_t From, uint32_t To) { + if (From >= BackEdges.size()) { + return false; + } const auto &Edges = BackEdges[From]; return std::find(Edges.begin(), Edges.end(), To) != Edges.end(); } @@ -634,6 +661,9 @@ computeReverseTopo(const std::vector &Blocks, while (!Stack.empty()) { uint32_t Current = Stack.back(); Stack.pop_back(); + if (Current >= NumBlocks) { + continue; + } if (Visited[Current] == 2) { continue; } @@ -647,6 +677,9 @@ computeReverseTopo(const std::vector &Blocks, const auto &Succs = Blocks[Current].Succs; for (auto It = Succs.rbegin(); It != Succs.rend(); ++It) { uint32_t Succ = *It; + if (Succ >= NumBlocks) { + continue; + } if (!isBackEdge(BackEdges, Current, Succ) && Visited[Succ] == 0) { Visited[Succ] = 1; Stack.push_back(Succ); @@ -679,7 +712,13 @@ collectNaturalLoop(uint32_t From, uint32_t Header, while (!Stack.empty()) { const uint32_t Node = Stack.back(); Stack.pop_back(); + if (Node >= NumBlocks) { + continue; + } for (uint32_t Pred : Blocks[Node].Preds) { + if (Pred >= NumBlocks) { + continue; + } if (Reachable[Pred] == 0) { continue; } @@ -713,6 +752,9 @@ static bool buildLoopsUsingDominance( continue; } for (uint32_t To : Blocks[From].Succs) { + if (To >= NumBlocks) { + continue; + } if (!bitsetTest(Dom[From], To)) { continue; } @@ -758,6 +800,9 @@ static bool buildLoopsUsingDominance( for (const auto &Loop : Loops) { for (uint32_t Node : Loop.Nodes) { + if (Node >= Dom.size() || Loop.Header >= NumBlocks) { + return false; + } if (!bitsetTest(Dom[Node], Loop.Header)) { return false; } @@ -814,6 +859,9 @@ static bool buildLoopsUsingDominance( for (size_t OrderIndex = 0; OrderIndex < LoopOrder.size(); ++OrderIndex) { const size_t LoopId = LoopOrder[OrderIndex]; for (uint32_t Node : Loops[LoopId].Nodes) { + if (Node >= LoopOf.size()) { + return false; + } if (LoopOf[Node] == -1) { LoopOf[Node] = static_cast(LoopId); } @@ -832,8 +880,14 @@ static bool buildLoopsUsingDominance( for (size_t LoopId = 0; LoopId < Loops.size(); ++LoopId) { auto &Loop = Loops[LoopId]; for (uint32_t Node : Loop.Nodes) { + if (Node >= NumBlocks) { + continue; + } bool IsExit = false; for (uint32_t Succ : Blocks[Node].Succs) { + if (Succ >= NumBlocks) { + continue; + } if (!bitsetTest(Loop.NodeMask, Succ)) { IsExit = true; break; @@ -872,6 +926,9 @@ static bool lemma614Update(uint32_t NodeId, const std::vector &Blocks, uint64_t MinSucc = UINT64_MAX; for (uint32_t Succ : Node.Succs) { + if (Succ >= Blocks.size() || Succ >= Metering.size()) { + continue; + } if (BackEdges && isBackEdge(*BackEdges, NodeId, Succ)) { continue; } @@ -891,6 +948,9 @@ static bool lemma614Update(uint32_t NodeId, const std::vector &Blocks, Metering[NodeId] += MinSucc; for (uint32_t Succ : Node.Succs) { + if (Succ >= Blocks.size() || Succ >= Metering.size()) { + continue; + } if (BackEdges && isBackEdge(*BackEdges, NodeId, Succ)) { continue; } diff --git a/src/runtime/evm_instance.cpp b/src/runtime/evm_instance.cpp index f635f405a..4aa6fad76 100644 --- a/src/runtime/evm_instance.cpp +++ b/src/runtime/evm_instance.cpp @@ -189,7 +189,7 @@ void EVMInstance::setInstanceExceptionOnJIT(EVMInstance *Inst, void EVMInstance::throwInstanceExceptionOnJIT(EVMInstance *Inst) { #ifdef ZEN_ENABLE_CPU_EXCEPTION - SAVE_EVM_HOSTAPI_FRAME_POINTER_TO_TLS + SAVE_EVM_HOSTAPI_FRAME_POINTER_TO_TLS; utils::throwCpuIllegalInstructionTrap(); #endif // ZEN_ENABLE_CPU_EXCEPTION diff --git a/src/runtime/evm_instance.h b/src/runtime/evm_instance.h index 63801cb04..f5d59792a 100644 --- a/src/runtime/evm_instance.h +++ b/src/runtime/evm_instance.h @@ -11,8 +11,8 @@ #include "runtime/evm_module.h" #include "runtime/instance.h" #include -#include #include +#include #include // Forward declaration for evmc_message @@ -158,8 +158,12 @@ class EVMInstance final : public RuntimeObject { std::unordered_map, evmc::bytes32, PairHash> CalldataLoads; - std::deque ExtcodeHashes; - std::deque Keccak256Results; + // Use std::list (not std::deque) for values whose .bytes pointers are + // returned to JIT and may outlive further push_back calls; deque can + // reallocate and invalidate earlier element addresses. + std::list ExtcodeHashes; + std::list Keccak256Results; + std::list CreateAddresses; bool TxContextCached = false; void clear() { @@ -170,6 +174,7 @@ class EVMInstance final : public RuntimeObject { CalldataLoads.clear(); ExtcodeHashes.clear(); Keccak256Results.clear(); + CreateAddresses.clear(); } }; diff --git a/src/vm/dt_evmc_vm.cpp b/src/vm/dt_evmc_vm.cpp index 17961c8ea..41a3427ba 100644 --- a/src/vm/dt_evmc_vm.cpp +++ b/src/vm/dt_evmc_vm.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef ZEN_ENABLE_VIRTUAL_STACK #include "utils/virtual_stack.h" @@ -174,6 +175,15 @@ bool parseBoolEnvValue(const char *Value, bool &ParsedValue) { return false; } +bool isLikelyPrecompile(const evmc_address &Addr) { + for (size_t I = 0; I < 19; ++I) { + if (Addr.bytes[I] != 0) { + return false; + } + } + return Addr.bytes[19] >= 1 && Addr.bytes[19] <= 9; +} + // VM interface for DTVM struct DTVM : evmc_vm { DTVM(); @@ -247,6 +257,8 @@ struct DTVM : evmc_vm { std::vector> NestedCtxPool; // Instance pool for depth > 0 std::vector CacheInsts; + // Serialize execute() for nested host calls (re-entrancy-safe via recursive_mutex). + std::recursive_mutex ExecuteMutex; bool isModuleInUse(const EVMModule *Mod) const { if (CachedMainInst && CachedMainInst->getModule() == Mod) @@ -540,6 +552,9 @@ evmc_result executeInterpreterFastPath(DTVM *VM, evmc_message MsgWithCode = *Msg; MsgWithCode.code = reinterpret_cast(Mod->Code); MsgWithCode.code_size = Mod->CodeSize; + if (Msg->depth == 0) { + TheInst->clearMessageCache(); + } TheInst->setExeResult(evmc::Result{EVMC_SUCCESS, 0, 0}); TheInst->pushMessage(&MsgWithCode); @@ -622,6 +637,19 @@ evmc_result executeMultipassFastPath(DTVM *VM, const evmc_host_interface *Host, return evmc_make_result(EVMC_FAILURE, 0, 0, nullptr, 0); } + // Empty-code top-level CALL to a non-precompile has no bytecode execution. + if (Msg && Msg->depth == 0 && CodeSize == 0 && Msg->kind == EVMC_CALL && + !isLikelyPrecompile(Msg->recipient)) { + evmc::Result NoCodeResult{EVMC_SUCCESS, static_cast(Msg->gas), 0}; + return NoCodeResult.release_raw(); + } + + // Nested empty-code CALLs: use interpreter path (precompiles may have no code). + if (Msg && Msg->depth > 0 && CodeSize == 0 && Msg->kind == EVMC_CALL) { + return executeInterpreterFastPath(VM, Host, Context, Rev, Msg, Code, + CodeSize); + } + // Module lookup: L1 address-based cache -> Cold load bool IsTransientMod = false; EVMModule *Mod = @@ -650,6 +678,9 @@ evmc_result executeMultipassFastPath(DTVM *VM, const evmc_host_interface *Host, evmc_message MsgWithCode = *Msg; MsgWithCode.code = reinterpret_cast(Mod->Code); MsgWithCode.code_size = Mod->CodeSize; + if (Msg->depth == 0) { + TheInst->clearMessageCache(); + } TheInst->setExeResult(evmc::Result{EVMC_SUCCESS, 0, 0}); TheInst->pushMessage(&MsgWithCode); @@ -685,6 +716,7 @@ evmc_result execute(evmc_vm *EVMInstance, const evmc_host_interface *Host, const evmc_message *Msg, const uint8_t *Code, size_t CodeSize) { auto *VM = static_cast(EVMInstance); + std::lock_guard Guard(VM->ExecuteMutex); // Interpreter mode: use optimized fast path (bypasses callEVMMain) if (VM->Config.Mode == RunMode::InterpMode) { @@ -743,6 +775,21 @@ DTVM::DTVM() StrictValidation); } } + + // Greedy RA has been observed to crash in long-running EVM multipass JIT + // compilation. Disabled by default; override with DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA. + Config.DisableMultipassGreedyRA = true; + if (const char *DisableGreedyRA = + std::getenv("DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA"); + DisableGreedyRA != nullptr) { + bool ParsedDisableGreedyRA = true; + if (parseBoolEnvValue(DisableGreedyRA, ParsedDisableGreedyRA)) { + Config.DisableMultipassGreedyRA = ParsedDisableGreedyRA; + } else { + ZEN_LOG_WARN("ignore invalid DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA=%s", + DisableGreedyRA); + } + } } } // namespace From b49138878508e20b5c8ca3f13546eeb12a7e52e4 Mon Sep 17 00:00:00 2001 From: cl507523 Date: Tue, 12 May 2026 02:30:47 +0000 Subject: [PATCH 3/3] fix: code format --- src/vm/dt_evmc_vm.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vm/dt_evmc_vm.cpp b/src/vm/dt_evmc_vm.cpp index 41a3427ba..66340cacb 100644 --- a/src/vm/dt_evmc_vm.cpp +++ b/src/vm/dt_evmc_vm.cpp @@ -257,7 +257,8 @@ struct DTVM : evmc_vm { std::vector> NestedCtxPool; // Instance pool for depth > 0 std::vector CacheInsts; - // Serialize execute() for nested host calls (re-entrancy-safe via recursive_mutex). + // Serialize execute() for nested host calls (re-entrancy-safe via + // recursive_mutex). std::recursive_mutex ExecuteMutex; bool isModuleInUse(const EVMModule *Mod) const { @@ -644,7 +645,8 @@ evmc_result executeMultipassFastPath(DTVM *VM, const evmc_host_interface *Host, return NoCodeResult.release_raw(); } - // Nested empty-code CALLs: use interpreter path (precompiles may have no code). + // Nested empty-code CALLs: use interpreter path (precompiles may have no + // code). if (Msg && Msg->depth > 0 && CodeSize == 0 && Msg->kind == EVMC_CALL) { return executeInterpreterFastPath(VM, Host, Context, Rev, Msg, Code, CodeSize); @@ -777,7 +779,8 @@ DTVM::DTVM() } // Greedy RA has been observed to crash in long-running EVM multipass JIT - // compilation. Disabled by default; override with DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA. + // compilation. Disabled by default; override with + // DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA. Config.DisableMultipassGreedyRA = true; if (const char *DisableGreedyRA = std::getenv("DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA");