diff --git a/lib/executor/instantiate/function.cpp b/lib/executor/instantiate/function.cpp index 43e7b86d22a6..af86a1044605 100644 --- a/lib/executor/instantiate/function.cpp +++ b/lib/executor/instantiate/function.cpp @@ -18,13 +18,24 @@ Expect Executor::instantiate(Runtime::Instance::ModuleInstance &ModInst, auto TypeIdxs = FuncSec.getContent(); auto CodeSegs = CodeSec.getContent(); - // Iterate through the code segments to instantiate function instances. - for (uint32_t I = 0; I < CodeSegs.size(); ++I) { - // Create and add the function instance into the module instance. - auto *FuncType = *ModInst.getFuncType(TypeIdxs[I]); - if (auto Symbol = CodeSegs[I].getSymbol()) { + if (CodeSegs.size() == 0) { + return {}; + } + // The module will always choose the `for` loop in `else` case under + // interpreter mode. Instead, if we do branch in the `for` loop which might + // cause meaningless branch misses. Therefore we should check the first item + // and dispatch it into different cases to reduce branch misses. + if (CodeSegs[0].getSymbol() != false) { + for (uint32_t I = 0; I < CodeSegs.size(); ++I) { + auto *FuncType = *ModInst.getFuncType(TypeIdxs[I]); + auto Symbol = CodeSegs[I].getSymbol(); ModInst.addFunc(&ModInst, *FuncType, std::move(Symbol)); - } else { + } + } else { + // Iterate through the code segments to instantiate function instances. + for (uint32_t I = 0; I < CodeSegs.size(); ++I) { + // Create and add the function instance into the module instance. + auto *FuncType = *ModInst.getFuncType(TypeIdxs[I]); ModInst.addFunc(&ModInst, *FuncType, CodeSegs[I].getLocals(), CodeSegs[I].getExpr().getInstrs()); }