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)