Skip to content

Commit f19dced

Browse files
committed
perf: JIT native regression because of program reuse
1 parent 24fede8 commit f19dced

5 files changed

Lines changed: 63 additions & 72 deletions

File tree

pd-vm/src/vm/jit/native/aarch64.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{
33
STATUS_YIELDED,
44
};
55
use crate::vm::jit::TraceStep;
6-
use crate::vm::{HostCallExecOutcome, Program, Value, Vm, VmError, VmResult};
6+
use crate::vm::{HostCallExecOutcome, Value, Vm, VmError, VmResult};
77
use std::sync::OnceLock;
88

99
pub(super) struct AArch64Backend;
@@ -83,9 +83,9 @@ struct ValueLayout {
8383
struct NativeStackLayout {
8484
vm_stack_offset: i32,
8585
vm_locals_offset: i32,
86-
vm_program_offset: i32,
86+
vm_program_constants_ptr_offset: i32,
87+
vm_program_constants_len_offset: i32,
8788
vm_ip_offset: i32,
88-
program_constants_offset: i32,
8989
stack_vec: VecLayout,
9090
value: ValueLayout,
9191
}
@@ -936,13 +936,8 @@ fn emit_native_step_ldc_inline(
936936
let stack_len_offset = vec_len_disp(layout.vm_stack_offset, layout.stack_vec)?;
937937
let stack_ptr_offset = vec_ptr_disp(layout.vm_stack_offset, layout.stack_vec)?;
938938
let stack_cap_offset = vec_cap_disp(layout.vm_stack_offset, layout.stack_vec)?;
939-
let constants_base = checked_add_i32(
940-
layout.vm_program_offset,
941-
layout.program_constants_offset,
942-
"vm constants base overflow",
943-
)?;
944-
let constants_len_offset = vec_len_disp(constants_base, layout.stack_vec)?;
945-
let constants_ptr_offset = vec_ptr_disp(constants_base, layout.stack_vec)?;
939+
let constants_len_offset = layout.vm_program_constants_len_offset;
940+
let constants_ptr_offset = layout.vm_program_constants_ptr_offset;
946941

947942
emit_ldr_x_disp(code, 15, VM_REG, constants_len_offset)?;
948943
emit_mov_imm64(code, 14, u64::from(const_index));
@@ -1485,20 +1480,23 @@ fn detect_native_stack_layout() -> VmResult<NativeStackLayout> {
14851480
fn detect_native_stack_layout_uncached() -> VmResult<NativeStackLayout> {
14861481
let vm_stack_offset = usize_to_i32(std::mem::offset_of!(Vm, stack), "Vm::stack offset")?;
14871482
let vm_locals_offset = usize_to_i32(std::mem::offset_of!(Vm, locals), "Vm::locals offset")?;
1488-
let vm_program_offset = usize_to_i32(std::mem::offset_of!(Vm, program), "Vm::program offset")?;
1489-
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
1490-
let program_constants_offset = usize_to_i32(
1491-
std::mem::offset_of!(Program, constants),
1492-
"Program::constants offset",
1483+
let vm_program_constants_ptr_offset = usize_to_i32(
1484+
std::mem::offset_of!(Vm, program_constants_ptr),
1485+
"Vm::program_constants_ptr offset",
14931486
)?;
1487+
let vm_program_constants_len_offset = usize_to_i32(
1488+
std::mem::offset_of!(Vm, program_constants_len),
1489+
"Vm::program_constants_len offset",
1490+
)?;
1491+
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
14941492
let stack_vec = detect_vec_layout()?;
14951493
let value = detect_value_layout()?;
14961494
Ok(NativeStackLayout {
14971495
vm_stack_offset,
14981496
vm_locals_offset,
1499-
vm_program_offset,
1497+
vm_program_constants_ptr_offset,
1498+
vm_program_constants_len_offset,
15001499
vm_ip_offset,
1501-
program_constants_offset,
15021500
stack_vec,
15031501
value,
15041502
})

pd-vm/src/vm/jit/native/cranelift.rs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use super::super::super::{
2-
HostCallExecOutcome, NumericValue, Program, Value, Vm, VmError, VmResult,
3-
};
1+
use super::super::super::{HostCallExecOutcome, NumericValue, Value, Vm, VmError, VmResult};
42
use super::super::{JitTrace, TraceStep};
53
use super::{
64
STATUS_CONTINUE, STATUS_ERROR, STATUS_HALTED, STATUS_TRACE_EXIT, STATUS_WAITING,
@@ -76,9 +74,9 @@ struct ValueLayout {
7674
struct NativeStackLayout {
7775
vm_stack_offset: i32,
7876
vm_locals_offset: i32,
79-
vm_program_offset: i32,
77+
vm_program_constants_ptr_offset: i32,
78+
vm_program_constants_len_offset: i32,
8079
vm_ip_offset: i32,
81-
program_constants_offset: i32,
8280
stack_vec: VecLayout,
8381
value: ValueLayout,
8482
}
@@ -1700,21 +1698,8 @@ fn resolve_offsets(layout: NativeStackLayout) -> VmResult<ResolvedOffsets> {
17001698
"locals len offset overflow",
17011699
)?;
17021700

1703-
let constants_vec_base = checked_add_i32(
1704-
layout.vm_program_offset,
1705-
layout.program_constants_offset,
1706-
"constants vec base offset overflow",
1707-
)?;
1708-
let constants_ptr = checked_add_i32(
1709-
constants_vec_base,
1710-
layout.stack_vec.ptr_offset,
1711-
"constants ptr offset overflow",
1712-
)?;
1713-
let constants_len = checked_add_i32(
1714-
constants_vec_base,
1715-
layout.stack_vec.len_offset,
1716-
"constants len offset overflow",
1717-
)?;
1701+
let constants_ptr = layout.vm_program_constants_ptr_offset;
1702+
let constants_len = layout.vm_program_constants_len_offset;
17181703

17191704
Ok(ResolvedOffsets {
17201705
stack_ptr,
@@ -1814,20 +1799,23 @@ fn detect_native_stack_layout() -> VmResult<NativeStackLayout> {
18141799
fn detect_native_stack_layout_uncached() -> VmResult<NativeStackLayout> {
18151800
let vm_stack_offset = usize_to_i32(std::mem::offset_of!(Vm, stack), "Vm::stack offset")?;
18161801
let vm_locals_offset = usize_to_i32(std::mem::offset_of!(Vm, locals), "Vm::locals offset")?;
1817-
let vm_program_offset = usize_to_i32(std::mem::offset_of!(Vm, program), "Vm::program offset")?;
1818-
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
1819-
let program_constants_offset = usize_to_i32(
1820-
std::mem::offset_of!(Program, constants),
1821-
"Program::constants offset",
1802+
let vm_program_constants_ptr_offset = usize_to_i32(
1803+
std::mem::offset_of!(Vm, program_constants_ptr),
1804+
"Vm::program_constants_ptr offset",
18221805
)?;
1806+
let vm_program_constants_len_offset = usize_to_i32(
1807+
std::mem::offset_of!(Vm, program_constants_len),
1808+
"Vm::program_constants_len offset",
1809+
)?;
1810+
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
18231811
let stack_vec = detect_vec_layout()?;
18241812
let value = detect_value_layout()?;
18251813
Ok(NativeStackLayout {
18261814
vm_stack_offset,
18271815
vm_locals_offset,
1828-
vm_program_offset,
1816+
vm_program_constants_ptr_offset,
1817+
vm_program_constants_len_offset,
18291818
vm_ip_offset,
1830-
program_constants_offset,
18311819
stack_vec,
18321820
value,
18331821
})

pd-vm/src/vm/jit/native/x86_64.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::{
44
};
55
use crate::builtins::BuiltinFunction;
66
use crate::vm::jit::TraceStep;
7-
use crate::vm::{HostCallExecOutcome, Program, Value, Vm, VmError, VmResult};
7+
use crate::vm::{HostCallExecOutcome, Value, Vm, VmError, VmResult};
88
use std::sync::OnceLock;
99

1010
pub(super) struct X86_64Backend;
@@ -87,9 +87,9 @@ struct ValueLayout {
8787
struct NativeStackLayout {
8888
vm_stack_offset: i32,
8989
vm_locals_offset: i32,
90-
vm_program_offset: i32,
90+
vm_program_constants_ptr_offset: i32,
91+
vm_program_constants_len_offset: i32,
9192
vm_ip_offset: i32,
92-
program_constants_offset: i32,
9393
stack_vec: VecLayout,
9494
value: ValueLayout,
9595
}
@@ -362,20 +362,23 @@ fn detect_native_stack_layout() -> VmResult<NativeStackLayout> {
362362
fn detect_native_stack_layout_uncached() -> VmResult<NativeStackLayout> {
363363
let vm_stack_offset = usize_to_i32(std::mem::offset_of!(Vm, stack), "Vm::stack offset")?;
364364
let vm_locals_offset = usize_to_i32(std::mem::offset_of!(Vm, locals), "Vm::locals offset")?;
365-
let vm_program_offset = usize_to_i32(std::mem::offset_of!(Vm, program), "Vm::program offset")?;
366-
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
367-
let program_constants_offset = usize_to_i32(
368-
std::mem::offset_of!(Program, constants),
369-
"Program::constants offset",
365+
let vm_program_constants_ptr_offset = usize_to_i32(
366+
std::mem::offset_of!(Vm, program_constants_ptr),
367+
"Vm::program_constants_ptr offset",
368+
)?;
369+
let vm_program_constants_len_offset = usize_to_i32(
370+
std::mem::offset_of!(Vm, program_constants_len),
371+
"Vm::program_constants_len offset",
370372
)?;
373+
let vm_ip_offset = usize_to_i32(std::mem::offset_of!(Vm, ip), "Vm::ip offset")?;
371374
let stack_vec = detect_vec_layout()?;
372375
let value = detect_value_layout()?;
373376
Ok(NativeStackLayout {
374377
vm_stack_offset,
375378
vm_locals_offset,
376-
vm_program_offset,
379+
vm_program_constants_ptr_offset,
380+
vm_program_constants_len_offset,
377381
vm_ip_offset,
378-
program_constants_offset,
379382
stack_vec,
380383
value,
381384
})
@@ -1198,13 +1201,8 @@ fn emit_native_step_ldc_inline(
11981201
let stack_len_offset = vec_len_disp(layout.vm_stack_offset, layout.stack_vec)?;
11991202
let stack_ptr_offset = vec_ptr_disp(layout.vm_stack_offset, layout.stack_vec)?;
12001203
let stack_cap_offset = vec_cap_disp(layout.vm_stack_offset, layout.stack_vec)?;
1201-
let constants_base = checked_add_i32(
1202-
layout.vm_program_offset,
1203-
layout.program_constants_offset,
1204-
"vm constants base overflow",
1205-
)?;
1206-
let constants_len_offset = vec_len_disp(constants_base, layout.stack_vec)?;
1207-
let constants_ptr_offset = vec_ptr_disp(constants_base, layout.stack_vec)?;
1204+
let constants_len_offset = layout.vm_program_constants_len_offset;
1205+
let constants_ptr_offset = layout.vm_program_constants_ptr_offset;
12081206

12091207
code.extend_from_slice(&[0x4C, 0x8B, 0x83]); // mov r8, [rbx+disp32] ; constants len
12101208
code.extend_from_slice(&constants_len_offset.to_le_bytes());

pd-vm/src/vm/mod.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ enum VmHostFunction {
340340

341341
pub struct Vm {
342342
program: Arc<Program>,
343+
program_constants_ptr: *const Value,
344+
program_constants_len: usize,
343345
program_cache_key: u64,
344346
program_cache_key_ready: bool,
345347
ip: usize,
@@ -453,8 +455,12 @@ impl Vm {
453455
}
454456

455457
pub fn new_shared(program: Arc<Program>) -> Self {
458+
let program_constants_ptr = program.constants.as_ptr();
459+
let program_constants_len = program.constants.len();
456460
Self {
457461
program,
462+
program_constants_ptr,
463+
program_constants_len,
458464
program_cache_key: 0,
459465
program_cache_key_ready: false,
460466
ip: 0,
@@ -484,8 +490,12 @@ impl Vm {
484490
}
485491

486492
pub fn with_locals_shared(program: Arc<Program>, local_count: usize) -> Self {
493+
let program_constants_ptr = program.constants.as_ptr();
494+
let program_constants_len = program.constants.len();
487495
Self {
488496
program,
497+
program_constants_ptr,
498+
program_constants_len,
489499
program_cache_key: 0,
490500
program_cache_key_ready: false,
491501
ip: 0,
@@ -872,13 +882,13 @@ impl Vm {
872882
return Err(VmError::BytecodeBounds);
873883
}
874884

875-
if self.fuel_remaining.is_some() {
876-
if let Err(err) = self.charge_fuel_tick() {
877-
if self.handle_debugger_error(&mut debugger, &err) {
878-
continue;
879-
}
880-
return Err(err);
885+
if self.fuel_remaining.is_some()
886+
&& let Err(err) = self.charge_fuel_tick()
887+
{
888+
if self.handle_debugger_error(&mut debugger, &err) {
889+
continue;
881890
}
891+
return Err(err);
882892
}
883893
let opcode = self.read_u8()?;
884894
let outcome = match self.execute_interpreter_instruction(opcode) {
@@ -1084,10 +1094,6 @@ impl Vm {
10841094
self.call_depth
10851095
}
10861096

1087-
pub(in crate::vm) fn fuel_metering_enabled(&self) -> bool {
1088-
self.fuel_remaining.is_some()
1089-
}
1090-
10911097
fn pending_fuel_debt(&self) -> u64 {
10921098
if self.fuel_remaining.is_none() {
10931099
return 0;

pd-vm/tests/compiler_common_tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,8 @@ fn find_first_while_loop_span(instructions: &[DecodedInstr]) -> (usize, usize, u
704704
};
705705
let target = target_u32 as usize;
706706
if target < instruction.ip {
707-
backedge_ip = Some(backedge_ip.map_or(candidate.ip, |current| current.max(candidate.ip)));
707+
backedge_ip =
708+
Some(backedge_ip.map_or(candidate.ip, |current| current.max(candidate.ip)));
708709
}
709710
}
710711

0 commit comments

Comments
 (0)