Skip to content

Commit 490f6a4

Browse files
Perf(vm): Peek stack in exec_fast to avoid pop+push on cache miss.
1 parent 9420d5c commit 490f6a4

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

compiler/src/modules/vm/mod.rs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -138,51 +138,50 @@ impl<'a> VM<'a> {
138138

139139
/*
140140
Fast-Path Execution
141-
Runs specialized ops from inline cache or adaptive overlay; returns false to trigger deopt.
141+
Peeks stack without popping; returns false with stack untouched to trigger deopt.
142142
*/
143143

144144
#[inline]
145145
fn exec_fast(&mut self, fast: FastOp) -> Result<bool, VmErr> {
146-
let (a, b) = self.pop2()?;
147-
let hit = match fast {
146+
let len = self.stack.len();
147+
if len < 2 { return Ok(false); }
148+
let a = self.stack[len - 2];
149+
let b = self.stack[len - 1];
150+
let result = match fast {
148151
FastOp::AddInt if a.is_int() && b.is_int() => {
149152
let r = a.as_int() as i128 + b.as_int() as i128;
150-
self.push(if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) });
151-
true
153+
if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) }
152154
}
153-
FastOp::AddFloat if a.is_float() && b.is_float() => { self.push(Val::float(a.as_float() + b.as_float())); true }
155+
FastOp::AddFloat if a.is_float() && b.is_float() => Val::float(a.as_float() + b.as_float()),
154156
FastOp::SubInt if a.is_int() && b.is_int() => {
155157
let r = a.as_int() as i128 - b.as_int() as i128;
156-
self.push(if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) });
157-
true
158+
if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) }
158159
}
159-
FastOp::SubFloat if a.is_float() && b.is_float() => { self.push(Val::float(a.as_float() - b.as_float())); true }
160+
FastOp::SubFloat if a.is_float() && b.is_float() => Val::float(a.as_float() - b.as_float()),
160161
FastOp::MulInt if a.is_int() && b.is_int() => {
161162
let r = a.as_int() as i128 * b.as_int() as i128;
162-
self.push(if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) });
163-
true
163+
if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { Val::float(r as f64) }
164164
}
165-
FastOp::MulFloat if a.is_float() && b.is_float() => { self.push(Val::float(a.as_float() * b.as_float())); true }
166-
FastOp::LtInt if a.is_int() && b.is_int() => { self.push(Val::bool(a.as_int() < b.as_int())); true }
167-
FastOp::LtFloat if a.is_float() && b.is_float() => { self.push(Val::bool(a.as_float() < b.as_float())); true }
168-
FastOp::EqInt if a.is_int() && b.is_int() => { self.push(Val::bool(a.as_int() == b.as_int())); true }
169-
FastOp::AddStr | FastOp::EqStr => {
170-
if a.is_heap() && b.is_heap() {
171-
let (sa, sb) = match (self.heap.get(a), self.heap.get(b)) {
172-
(HeapObj::Str(x), HeapObj::Str(y)) => (x.clone(), y.clone()),
173-
_ => { self.push(a); self.push(b); return Ok(false); }
174-
};
175-
match fast {
176-
FastOp::AddStr => { let v = self.heap.alloc(HeapObj::Str(format!("{}{}", sa, sb)))?; self.push(v); }
177-
_ => { self.push(Val::bool(sa == sb)); }
178-
}
179-
true
180-
} else { false }
165+
FastOp::MulFloat if a.is_float() && b.is_float() => Val::float(a.as_float() * b.as_float()),
166+
FastOp::LtInt if a.is_int() && b.is_int() => Val::bool(a.as_int() < b.as_int()),
167+
FastOp::LtFloat if a.is_float() && b.is_float() => Val::bool(a.as_float() < b.as_float()),
168+
FastOp::EqInt if a.is_int() && b.is_int() => Val::bool(a.as_int() == b.as_int()),
169+
FastOp::AddStr | FastOp::EqStr if a.is_heap() && b.is_heap() => {
170+
let (sa, sb) = match (self.heap.get(a), self.heap.get(b)) {
171+
(HeapObj::Str(x), HeapObj::Str(y)) => (x.clone(), y.clone()),
172+
_ => return Ok(false),
173+
};
174+
match fast {
175+
FastOp::AddStr => self.heap.alloc(HeapObj::Str(format!("{}{}", sa, sb)))?,
176+
_ => Val::bool(sa == sb),
177+
}
181178
}
182-
_ => false,
179+
_ => return Ok(false),
183180
};
184-
if !hit { self.push(a); self.push(b); }
185-
Ok(hit)
181+
// Replace both operands with computed result.
182+
self.stack.truncate(len - 2);
183+
self.push(result);
184+
Ok(true)
186185
}
187186

188187
/*

0 commit comments

Comments
 (0)