From d14a7a820afd7979f5bf176ab2c3aa2df6a822df Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 05:24:46 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[performance=20improvement]?= =?UTF-8?q?=20Remove=20redundant=20function=20lookup=20in=20VM=20loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- .jules/bolt.md | 1 + runtime/vm/src/executor.rs | 44 ++++++-------------------------------- 2 files changed, 7 insertions(+), 38 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 1592fa94..7e8ee7bc 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,4 @@ ## 2026-08-19 - Removed redundant instruction array lookup in VM loop **Learning:** The inner loop of the VM interpreter (`execute_loop`) had an expensive, redundant deep indexing operation to fetch `inst_operands` which was already available on the `inst` reference. Re-fetching it via `self.module.functions[...].chunk.instructions[...].operands` adds unnecessary bounds checks and pointer chasing in the hottest part of the VM. **Action:** Always prefer using existing local references over redundant deep lookups, especially in tight loops like an interpreter fetch-decode-execute loop. +## 2026-08-19 - Reused local frame and func references in VM opcodes\n**Learning:** The VM executor repeatedly looked up the current frame via `self.frames.last()` and current function via `self.module.functions[...]` in several opcodes (LoadConst, FieldLoad, StoreLocal, etc.). This adds unnecessary bounds checking and pointer dereferencing on the hottest path since `frame` and `func` are already computed at the start of the while loop iteration.\n**Action:** Always reuse existing local references in tight loop opcodes rather than repeatedly querying collections or stacks when the target element is already known and borrowed. diff --git a/runtime/vm/src/executor.rs b/runtime/vm/src/executor.rs index 8b3400ec..226c2fc9 100644 --- a/runtime/vm/src/executor.rs +++ b/runtime/vm/src/executor.rs @@ -35,14 +35,8 @@ impl VM { self.profiler.record_stack_height(self.stack.len()); if self.debugger.is_enabled() { - let current_func = &self.module.functions[self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .function_idx - as usize]; self.debugger.trace_instruction( - current_func, + func, ip, inst_op, inst_operands, @@ -55,13 +49,7 @@ impl VM { Opcode::LoadConst => { if let Some(Operand::ConstantIndex(c_idx)) = inst_operands.first() { - let current_func = &self.module.functions[self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .function_idx - as usize]; - let lit = current_func + let lit = func .chunk .constants .get(*c_idx) @@ -81,11 +69,7 @@ impl VM { Opcode::LoadLocal => { if let Some(Operand::LocalIndex(l_idx)) = inst_operands.first() { - let bp = self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .base_pointer; + let bp = frame.base_pointer; let val = self.stack.get(bp + *l_idx as usize)?; self.stack.push(val.clone())?; } else { @@ -95,11 +79,7 @@ impl VM { Opcode::StoreLocal => { if let Some(Operand::LocalIndex(l_idx)) = inst_operands.first() { - let bp = self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .base_pointer; + let bp = frame.base_pointer; let val = self.stack.pop()?; self.stack.set(bp + *l_idx as usize, val)?; } else { @@ -784,13 +764,7 @@ impl VM { Opcode::FieldLoad => { if let Some(Operand::ConstantIndex(c_idx)) = inst_operands.first() { - let current_func = &self.module.functions[self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .function_idx - as usize]; - let lit = current_func + let lit = func .chunk .constants .get(*c_idx) @@ -846,13 +820,7 @@ impl VM { Opcode::FieldStore => { if let Some(Operand::ConstantIndex(c_idx)) = inst_operands.first() { - let current_func = &self.module.functions[self - .frames - .last() - .ok_or(crate::error::VMError::StackUnderflow)? - .function_idx - as usize]; - let lit = current_func + let lit = func .chunk .constants .get(*c_idx)