Skip to content

Commit 11276f4

Browse files
Perf(vm): Annotate error constructors with #[cold] to keep hot paths linear.
1 parent 0e0fce8 commit 11276f4

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

compiler/src/modules/vm/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,15 @@ impl<'a> VM<'a> {
358358
OpCode::JumpIfFalse => {
359359
let v = self.pop()?;
360360
if !self.truthy(v) {
361-
if self.budget == 0 { return Err(VmErr::Budget); }
361+
if self.budget == 0 { return Err(cold_budget()); }
362362
self.budget -= 1;
363363
let target = op as usize;
364364
if target > chunk.instructions.len() { return Err(VmErr::Runtime("jump target out of bounds".into())); }
365365
ip = target;
366366
}
367367
}
368368
OpCode::Jump => {
369-
if self.budget == 0 { return Err(VmErr::Budget); }
369+
if self.budget == 0 { return Err(cold_budget()); }
370370
self.budget -= 1;
371371
let target = op as usize;
372372
if target > chunk.instructions.len() {
@@ -463,7 +463,7 @@ impl<'a> VM<'a> {
463463
self.iter_stack.push(frame);
464464
}
465465
OpCode::ForIter => {
466-
if self.budget == 0 { return Err(VmErr::Budget); }
466+
if self.budget == 0 { return Err(cold_budget()); }
467467
self.budget -= 1;
468468
if self.heap.needs_gc() { self.collect(slots); }
469469
match self.iter_stack.last_mut().and_then(|f| f.next_item()) {
@@ -496,7 +496,7 @@ impl<'a> VM<'a> {
496496
}
497497
OpCode::Call => {
498498
let argc = op as usize;
499-
if self.depth >= self.max_calls { return Err(VmErr::CallDepth); }
499+
if self.depth >= self.max_calls { return Err(cold_depth()); }
500500
let mut args: Vec<Val> = (0..argc).map(|_| self.pop()).collect::<Result<_,_>>()?;
501501
args.reverse();
502502
let callee = self.pop()?;

compiler/src/modules/vm/types.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl HeapPool {
189189
if let Some(&idx) = self.strings.get(s) { return Ok(Val::heap(idx)); }
190190
}
191191
}
192-
if self.usage() >= self.limit { return Err(VmErr::Heap); }
192+
if self.usage() >= self.limit { return Err(cold_heap()); }
193193
if self.objects.len() >= (1 << 28) { return Err(VmErr::Heap); }
194194

195195
let idx = if let Some(i) = self.free_list.pop() {
@@ -380,4 +380,13 @@ pub fn fpowf(base: f64, exp: f64) -> f64 {
380380
return f64::NAN;
381381
}
382382
fexp(exp * fln(base))
383-
}
383+
}
384+
385+
/*
386+
Cold Error Constructors
387+
Out-of-line error paths keep hot dispatch loop linear for instruction cache.
388+
*/
389+
390+
#[cold] #[inline(never)] pub fn cold_heap() -> VmErr { VmErr::Heap }
391+
#[cold] #[inline(never)] pub fn cold_budget() -> VmErr { VmErr::Budget }
392+
#[cold] #[inline(never)] pub fn cold_depth() -> VmErr { VmErr::CallDepth }

0 commit comments

Comments
 (0)