Skip to content

Commit db5f70e

Browse files
committed
pd-vm: JIT native avoid jump back to interpreter as possible
1 parent e057ccf commit db5f70e

2 files changed

Lines changed: 72 additions & 16 deletions

File tree

pd-vm/src/vm/jit/runtime.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -577,16 +577,24 @@ impl Vm {
577577
{
578578
continue;
579579
}
580-
// Chain directly into another already-compiled trace at the current ip.
581-
if !has_yielding_call
582-
&& let Some(next_trace_id) = self.jit.compiled_trace_for_ip(self.ip)
583-
&& next_trace_id != current_trace_id
584-
{
585-
current_trace_id = next_trace_id;
586-
self.ensure_native_trace(current_trace_id)?;
587-
(entry, root_ip, terminal, has_yielding_call) =
588-
self.native_trace_state(current_trace_id)?;
589-
continue;
580+
if !has_yielding_call {
581+
let ip = self.ip;
582+
let mut next_trace_id = self.jit.compiled_trace_for_ip(ip);
583+
if next_trace_id.is_none() {
584+
next_trace_id = {
585+
let program = &self.program;
586+
self.jit.observe_exit_ip(ip, program)
587+
};
588+
}
589+
if let Some(next_trace_id) = next_trace_id
590+
&& next_trace_id != current_trace_id
591+
{
592+
current_trace_id = next_trace_id;
593+
self.ensure_native_trace(current_trace_id)?;
594+
(entry, root_ip, terminal, has_yielding_call) =
595+
self.native_trace_state(current_trace_id)?;
596+
continue;
597+
}
590598
}
591599
return Ok(ExecOutcome::Continue);
592600
}

pd-vm/src/vm/jit/trace.rs

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,9 @@ impl TraceJitEngine {
252252
if self.blocked_roots.contains(&ip) {
253253
return None;
254254
}
255-
if !self.is_loop_header(program, ip) {
256-
return None;
257-
}
255+
if !self.is_loop_header(program, ip) {
256+
return None;
257+
}
258258

259259
let count = self.hot_counts.entry(ip).or_insert(0);
260260
*count = count.saturating_add(1);
@@ -296,9 +296,57 @@ impl TraceJitEngine {
296296
}
297297
}
298298

299-
pub fn trace_clone(&self, trace_id: usize) -> Option<JitTrace> {
300-
self.traces.get(trace_id).cloned()
301-
}
299+
pub fn trace_clone(&self, trace_id: usize) -> Option<JitTrace> {
300+
self.traces.get(trace_id).cloned()
301+
}
302+
303+
pub fn observe_exit_ip(&mut self, ip: usize, program: &Program) -> Option<usize> {
304+
if !self.config.enabled || !native_jit_supported() {
305+
return None;
306+
}
307+
// Keep default behavior unchanged: only aggressively chain-compile exit roots when the
308+
// user requested the most aggressive hotness policy.
309+
if self.config.hot_loop_threshold > 1 {
310+
return None;
311+
}
312+
if let Some(&trace_id) = self.compiled_by_root.get(&ip) {
313+
return Some(trace_id);
314+
}
315+
if self.blocked_roots.contains(&ip) {
316+
return None;
317+
}
318+
319+
let line = program
320+
.debug
321+
.as_ref()
322+
.and_then(|debug| debug.line_for_offset(ip));
323+
let result = if self.config.hot_loop_threshold == 0 {
324+
Err(JitNyiReason::HotLoopThresholdZero)
325+
} else {
326+
self.compile_trace(program, ip)
327+
};
328+
329+
match result {
330+
Ok(trace_id) => {
331+
self.attempts.push(JitAttempt {
332+
root_ip: ip,
333+
line,
334+
result: Ok(trace_id),
335+
});
336+
self.compiled_by_root.insert(ip, trace_id);
337+
Some(trace_id)
338+
}
339+
Err(reason) => {
340+
self.attempts.push(JitAttempt {
341+
root_ip: ip,
342+
line,
343+
result: Err(reason),
344+
});
345+
self.blocked_roots.insert(ip);
346+
None
347+
}
348+
}
349+
}
302350

303351
pub fn trace_has_call(&self, trace_id: usize) -> bool {
304352
self.traces

0 commit comments

Comments
 (0)