mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
feat: run 装载期对共享模块字节码显式复制,COW 深拷贝移出热路径
This commit is contained in:
Generated
+19
-19
@@ -1160,7 +1160,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_builtins"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"fast-float",
|
||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_bytecode"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxide_log",
|
||||
@@ -1193,7 +1193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cfg"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_emit",
|
||||
@@ -1204,7 +1204,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cli"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"bumpalo",
|
||||
@@ -1226,7 +1226,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_code_cache"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"lru",
|
||||
"oxide_bytecode",
|
||||
@@ -1235,7 +1235,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_compiler"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1255,7 +1255,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_dce"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1269,7 +1269,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_emit"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxc_allocator",
|
||||
@@ -1284,7 +1284,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_engine"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1296,7 +1296,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_ir"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_log",
|
||||
@@ -1305,7 +1305,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_kernel"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1319,7 +1319,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_liveness"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1331,7 +1331,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_log"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
@@ -1340,7 +1340,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_parser"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
@@ -1355,7 +1355,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_regalloc"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1371,7 +1371,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_runtime_api"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
@@ -1384,7 +1384,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_test262"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1402,7 +1402,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_types"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1415,7 +1415,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_vm"
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"chrono",
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.8.94"
|
||||
version = "0.8.95"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
rust-version = "1.80"
|
||||
|
||||
@@ -168,7 +168,8 @@ pub struct Vm {
|
||||
pub(crate) regs: [JsValue; 256],
|
||||
pub(crate) pc: usize,
|
||||
/// 当前活动字节码。以 `Arc<[Instr]>` 共享:函数调用经 `Arc::clone` 换帧(O(1)),
|
||||
/// 不再逐帧深拷贝。与子模块平表源共享同一缓冲,IC 写回经 `bytecode_mut` 的
|
||||
/// 不再逐帧深拷贝。顶层装载期按引用计数条件复制(共享时显式深拷贝,独占时
|
||||
/// 零拷贝),子模块平表源保持惰性 COW,IC 写回经 `bytecode_mut` 的
|
||||
/// `Arc::make_mut` 写时复制,保证独占后才改写(miss 时才深拷贝,频率低)。
|
||||
pub(crate) bytecode: Arc<[opcode::Instr]>,
|
||||
/// 当前活动模块已转换不可变常量的只读视图(指向当前表代际的 immutables 内部)。
|
||||
|
||||
@@ -664,7 +664,8 @@ impl Vm {
|
||||
/// 加载并执行一个已编译模块,返回模块顶层执行结果或未捕获异常消息。
|
||||
///
|
||||
/// 模块以 `Arc` 与调用方共享(如 CodeForge 缓存条目):平表装载只做
|
||||
/// Arc::clone,run 期零模块拷贝。内部初始化寄存器/bytecode/immutables 与
|
||||
/// Arc::clone,顶层字节码按引用计数条件复制(共享时装载期显式深拷贝,
|
||||
/// 独占时零拷贝)。内部初始化寄存器/bytecode/immutables 与
|
||||
/// builtin 寄存器预绑定,然后进入 dispatch 主循环;执行完成或异常展开后返回。
|
||||
pub fn run(&mut self, module: &Arc<CompiledModule>) -> Result<JsValue, String> {
|
||||
vm_debug!("run: starting bytecode execution, {} instructions", module.bytecode.len());
|
||||
@@ -696,7 +697,15 @@ impl Vm {
|
||||
self.active_table_gen = self.current_gen;
|
||||
// 顶层脚本严格模式:无帧且无 inline 时写路径的 strict/sloppy 判定来源。
|
||||
self.top_level_strict = module.is_strict;
|
||||
self.bytecode = Arc::clone(&module.bytecode);
|
||||
// 顶层字节码按模块引用计数条件复制:模块被宿主共享(外层 Arc 计数 > 1,
|
||||
// 如 CodeForge 缓存条目与调用方各持一份)时装载期显式深拷贝,把 COW 深拷贝
|
||||
// 从 dispatch 主循环热路径挪到 run 装载期(批量、可预测);模块独占(计数 1,
|
||||
// 如 worker 新编译模块)保持 Arc::clone,无宿主共享缓冲需保护,复制无收益。
|
||||
if Arc::strong_count(module) > 1 {
|
||||
self.bytecode = Arc::from(&module.bytecode[..]);
|
||||
} else {
|
||||
self.bytecode = Arc::clone(&module.bytecode);
|
||||
}
|
||||
self.activate_immutables(self.current_gen, 0, &module.constants);
|
||||
self.root_reg_limit = module.n_registers.max(1);
|
||||
self.active_reg_limit = self.root_reg_limit;
|
||||
@@ -933,6 +942,22 @@ mod tests {
|
||||
assert_eq!(vm.bytecode.len(), module.bytecode.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_copies_bytecode_when_shared() {
|
||||
// 顶层字节码装载期显式副本:共享模块(引用计数 > 1)在 run 装载期即深拷贝,
|
||||
// 即使零 IC miss(无写回触发惰性 COW)Vm.bytecode 也须是私有 Arc 实例。
|
||||
// 本钉在惰性 COW 行为下必失败(无写回则不拷贝,保持与宿主同一实例)。
|
||||
let mut vm = Vm::new();
|
||||
let module = Arc::new(compile("var x = 1; x + 1"));
|
||||
let shared = Arc::clone(&module); // 双 Arc 计数,模拟宿主缓存共享
|
||||
vm.run(&shared).expect("run");
|
||||
assert!(
|
||||
!Arc::ptr_eq(&module.bytecode, &vm.bytecode),
|
||||
"共享模块装载期须显式复制,Vm.bytecode 不得与宿主共享同一 Arc"
|
||||
);
|
||||
assert_eq!(vm.bytecode.len(), module.bytecode.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_restore_inline_round_trip() {
|
||||
// 构造带哨兵的 VM → save → 恢复 → 断言全部字段逐字往返(含 accessor_frame_target_reg)。
|
||||
|
||||
Reference in New Issue
Block a user