refactor: 动态编译改经 CompilerService 注入,oxide_vm 去编译器依赖

This commit is contained in:
2026-10-08 05:51:58 +00:00
parent 66735f802f
commit 4f9b6ab444
94 changed files with 459 additions and 67 deletions
+14 -1
View File
@@ -4,6 +4,7 @@ use std::sync::Arc;
use std::time::Instant;
use oxide_compiler::compiler::{compiled_module_hash, Compiler};
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::{KernelConfig, KernelCore};
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
@@ -225,6 +226,7 @@ pub fn run_mem_vm_creation_leak(kernel: &Arc<KernelCore>) -> ExitCode {
for i in 0..ITERATIONS {
{
let mut vm = Vm::with_kernel_core(Arc::clone(kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
if let Err(e) = vm.run(&module) {
eprintln!("[vm_creation] iteration {i} run failed: {e}");
return ExitCode::FAILURE;
@@ -318,6 +320,7 @@ pub fn run_mem_dirty_rebuild_leak(kernel: &Arc<KernelCore>) -> ExitCode {
const SAMPLE_EVERY: usize = 10;
let mut vm = Vm::with_kernel_core(Arc::clone(kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let compiler = Compiler::new();
let mut sampler = LeakSampler::new(20);
@@ -421,6 +424,7 @@ pub fn run_mem_closure_dead_leak(kernel: &Arc<KernelCore>) -> ExitCode {
let mut series: Vec<(usize, f64)> = Vec::new();
for window in 0..WINDOWS {
let mut vm = Vm::with_kernel_core(Arc::clone(kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
for round in 0..ROUNDS_PER_WINDOW {
if let Err(e) = vm.run(create) {
eprintln!("[closure_dead_leak] window {window} round {round} create run failed: {e}");
@@ -479,6 +483,7 @@ pub fn run_mem_pool_high_water(kernel: &Arc<KernelCore>) -> ExitCode {
let light = compile_one(light_js);
let mut vm = Vm::with_kernel_core(Arc::clone(kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
if let Err(e) = vm.run(&heavy) {
eprintln!("[pool_high_water] heavy run failed: {e}");
return ExitCode::FAILURE;
@@ -548,6 +553,7 @@ pub fn run_mem_object_churn_peak(kernel: &Arc<KernelCore>) -> ExitCode {
};
let mut vm = Vm::with_kernel_core(Arc::clone(kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let mut series: Vec<(usize, f64)> = Vec::new();
if let Some(kb) = read_vmrss_kb() {
series.push((0, kb as f64));
@@ -652,6 +658,7 @@ pub fn run_mem_kernel_lifetime() -> ExitCode {
let rss_pre = read_vmrss_kb().unwrap_or(0);
{
let mut vm = Vm::with_kernel_core(Arc::clone(&kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = match vm.run(&js_module) {
Ok(v) => v,
Err(e) => {
@@ -769,7 +776,12 @@ pub fn run_mem_startup_breakdown() -> ExitCode {
let t1 = Instant::now();
// 池构造:同步预热 min_size 个 Vm,预热成本计入本段。
let pool = VmPool::new(Arc::clone(&kernel), config.min_pool_size, config.max_pool_size);
let pool = VmPool::new(
Arc::clone(&kernel),
Arc::new(DefaultCompilerService),
config.min_pool_size,
config.max_pool_size,
);
let t2 = Instant::now();
// 首次 spawn:命中预热池,近零成本。
@@ -904,6 +916,7 @@ mod tests {
fn session_accounting_zero_after_full_reset() {
let kernel = KernelCore::new(KernelConfig::standard());
let mut vm = Vm::with_kernel_core(Arc::clone(&kernel));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let allocator = Allocator::default();
let program = oxide_parser::parse(&allocator, "var o = { a: 1 }; o").expect("parse");
let hash = compiled_module_hash(&program);
+9 -1
View File
@@ -19,6 +19,7 @@ use oxide_cli::server::spawn;
use oxide_cli::server::watchdog;
use oxide_compiler::compiler::{compiled_module_hash, Compiler};
use oxide_compiler::compiler_error;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::{KernelConfig, KernelCore};
use oxide_kernel::shape_forge::ShapeForge;
use oxide_kernel::string_forge::PermInterner;
@@ -620,7 +621,12 @@ fn make_kernel(verbose: bool, quiet: bool) -> Arc<KernelCore> {
}
fn make_pool(kernel: &Arc<KernelCore>) -> Arc<VmPool> {
VmPool::new(Arc::clone(kernel), kernel.config.min_pool_size, kernel.config.max_pool_size)
VmPool::new(
Arc::clone(kernel),
Arc::new(DefaultCompilerService),
kernel.config.min_pool_size,
kernel.config.max_pool_size,
)
}
fn eval(
@@ -767,6 +773,8 @@ fn repl() -> ExitCode {
let kernel = make_kernel(false, false);
let mut vm = Vm::with_kernel_core(Arc::clone(&kernel));
// REPL 源经 eval 路径动态编译(含 `new Function` / eval 内置),注入真实编译服务。
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let mut input_buf = String::new();
loop {
+2 -1
View File
@@ -100,12 +100,13 @@ fn panic_payload_str(payload: &Box<dyn std::any::Any + Send>) -> String {
#[cfg(test)]
mod tests {
use super::*;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::KernelConfig;
/// 测试环境:minimal 内核加单 VM 池(与池既有测试同口径)。
fn test_env() -> (Arc<KernelCore>, Arc<VmPool>) {
let kernel = KernelCore::new(KernelConfig::minimal());
let pool = VmPool::new(Arc::clone(&kernel), 1, Some(2));
let pool = VmPool::new(Arc::clone(&kernel), Arc::new(DefaultCompilerService), 1, Some(2));
(kernel, pool)
}
+2 -1
View File
@@ -73,12 +73,13 @@ pub fn handle_forge_query(
mod tests {
use super::*;
use crate::server::eval;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::KernelConfig;
/// 测试环境:minimal 内核加单 VM 池(与 eval 测试同口径)。
fn test_env() -> (Arc<KernelCore>, Arc<VmPool>) {
let kernel = KernelCore::new(KernelConfig::minimal());
let pool = VmPool::new(Arc::clone(&kernel), 1, Some(2));
let pool = VmPool::new(Arc::clone(&kernel), Arc::new(DefaultCompilerService), 1, Some(2));
(kernel, pool)
}
+9 -1
View File
@@ -13,6 +13,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{mpsc, Arc, Mutex};
use std::thread::JoinHandle;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::KernelCore;
use oxide_vm::vm_pool::{PoolCounters, VmPool};
@@ -111,7 +112,14 @@ pub fn spawn_workers(
let counters = Arc::clone(&counters);
handles.push(std::thread::spawn(move || {
// 池在本线程上创建,永不跨线程移动(Vm 不是 Send)。
let pool = VmPool::with_counters(Arc::clone(&kernel), min_pool_size, max_pool_size, counters);
// 编译服务随池构造注入:worker 池内 Vm 的 eval 动态编译面由此供给。
let pool = VmPool::with_counters(
Arc::clone(&kernel),
Arc::new(DefaultCompilerService),
min_pool_size,
max_pool_size,
counters,
);
worker_loop(rx, kernel, pool);
}));
senders.push(tx);