mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: GC 统计随 run 边界复位,bench GC 列逐文件独立
This commit is contained in:
@@ -1607,6 +1607,7 @@ fn in_run_collection_keeps_live_addresses_stable() {
|
|||||||
|
|
||||||
// 第一轮执行期收集:o 及其 epoch 子引用晋升 session。
|
// 第一轮执行期收集:o 及其 epoch 子引用晋升 session。
|
||||||
vm.maybe_collect_in_run();
|
vm.maybe_collect_in_run();
|
||||||
|
assert!(vm.session_gc_stats().total_collections >= 1, "第一轮收集应执行");
|
||||||
let o = global_prop_opt(&vm, "o").expect("o 应挂在 global");
|
let o = global_prop_opt(&vm, "o").expect("o 应挂在 global");
|
||||||
let o_ptr = o.as_js_object_ptr();
|
let o_ptr = o.as_js_object_ptr();
|
||||||
assert!(unsafe { (*o_ptr).is_session_epoch() }, "o 晋升后应为 session 对象");
|
assert!(unsafe { (*o_ptr).is_session_epoch() }, "o 晋升后应为 session 对象");
|
||||||
@@ -1627,8 +1628,11 @@ fn in_run_collection_keeps_live_addresses_stable() {
|
|||||||
.expect("run2");
|
.expect("run2");
|
||||||
// run 边界清空执行状态:churn 局部(t 数组与 50 个对象)自此不可达。
|
// run 边界清空执行状态:churn 局部(t 数组与 50 个对象)自此不可达。
|
||||||
vm.run(&Arc::new(compile("0"))).expect("run3");
|
vm.run(&Arc::new(compile("0"))).expect("run3");
|
||||||
|
// 统计按 run 复位:run 边界后只认第二轮计数,记录前值作增量基准。
|
||||||
|
let before = vm.session_gc_stats().total_collections;
|
||||||
vm.maybe_collect_in_run();
|
vm.maybe_collect_in_run();
|
||||||
assert!(vm.session_gc_stats().total_collections >= 2, "两轮收集均应执行");
|
assert!(vm.session_gc_stats().total_collections >= 1, "第二轮收集应执行");
|
||||||
|
assert!(vm.session_gc_stats().total_collections > before, "两轮收集均应执行");
|
||||||
|
|
||||||
assert_eq!(global_prop_opt(&vm, "o").expect("o").as_js_object_ptr(), o_ptr, "存活对象地址不变");
|
assert_eq!(global_prop_opt(&vm, "o").expect("o").as_js_object_ptr(), o_ptr, "存活对象地址不变");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -558,6 +558,21 @@ impl Vm {
|
|||||||
// per-run 指标(ic_hit_rate)跨文件累积,报告失真。
|
// per-run 指标(ic_hit_rate)跨文件累积,报告失真。
|
||||||
self.profiling.ic_hits.set(0);
|
self.profiling.ic_hits.set(0);
|
||||||
self.profiling.ic_misses.set(0);
|
self.profiling.ic_misses.set(0);
|
||||||
|
// GC 统计同属执行期状态:池化 Vm 跨 run 复用,不清零则 per-run
|
||||||
|
// 指标(gc_trigger_count)跨文件累积,报告失真。
|
||||||
|
let gc = &mut self.gc_state.session_gc;
|
||||||
|
gc.total_collections = 0;
|
||||||
|
gc.total_bytes_freed = 0;
|
||||||
|
gc.total_objects_scanned = 0;
|
||||||
|
gc.total_objects_live = 0;
|
||||||
|
gc.total_objects_dead = 0;
|
||||||
|
gc.last_collection_objects_scanned = 0;
|
||||||
|
gc.last_collection_objects_live = 0;
|
||||||
|
gc.last_collection_objects_dead = 0;
|
||||||
|
gc.last_collection_bytes_freed = 0;
|
||||||
|
gc.last_collection_duration_us = 0;
|
||||||
|
gc.max_collection_duration_us = 0;
|
||||||
|
gc.min_collection_duration_us = u64::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 轻量重置:清空执行状态并回收 epoch 内存,但保留 session 字符串与 builtin。
|
/// 轻量重置:清空执行状态并回收 epoch 内存,但保留 session 字符串与 builtin。
|
||||||
|
|||||||
@@ -490,13 +490,14 @@ fn gc_runtime_collection_keeps_entries() {
|
|||||||
.expect("parse");
|
.expect("parse");
|
||||||
let module = Compiler::new().compile(&program).expect("compile");
|
let module = Compiler::new().compile(&program).expect("compile");
|
||||||
vm.run(&Arc::new(module)).expect("run1");
|
vm.run(&Arc::new(module)).expect("run1");
|
||||||
|
// 统计按 run 复位:churn 在 run1 内,断言须在 run1 后读。
|
||||||
|
assert!(vm.session_gc_stats().total_collections > 0, "低阈值应触发执行期 GC");
|
||||||
let allocator = Allocator::default();
|
let allocator = Allocator::default();
|
||||||
let program2 = oxide_parser::parse(&allocator, "globalThis.log.length + ''").expect("parse");
|
let program2 = oxide_parser::parse(&allocator, "globalThis.log.length + ''").expect("parse");
|
||||||
let module2 = Compiler::new().compile(&program2).expect("compile");
|
let module2 = Compiler::new().compile(&program2).expect("compile");
|
||||||
let result = vm.run(&Arc::new(module2)).expect("run2");
|
let result = vm.run(&Arc::new(module2)).expect("run2");
|
||||||
let text = vm.lookup_str(result).unwrap_or_default().to_string();
|
let text = vm.lookup_str(result).unwrap_or_default().to_string();
|
||||||
assert_eq!(text, "200");
|
assert_eq!(text, "200");
|
||||||
assert!(vm.session_gc_stats().total_collections > 0, "低阈值应触发执行期 GC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// promote 交叉:栈的 entries 引用 epoch 对象(释放函数),写 global 触发 promote,
|
/// promote 交叉:栈的 entries 引用 epoch 对象(释放函数),写 global 触发 promote,
|
||||||
|
|||||||
@@ -416,13 +416,14 @@ fn promise_result_string_survives_runtime_gc() {
|
|||||||
0",
|
0",
|
||||||
);
|
);
|
||||||
vm.run(&Arc::new(first)).expect("run1");
|
vm.run(&Arc::new(first)).expect("run1");
|
||||||
|
// 统计按 run 复位:churn 在 run1 内,断言须在 run1 后读。
|
||||||
|
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期字符串 GC");
|
||||||
|
|
||||||
let second = compile("globalThis.got");
|
let second = compile("globalThis.got");
|
||||||
let result = vm.run(&Arc::new(second)).expect("run2");
|
let result = vm.run(&Arc::new(second)).expect("run2");
|
||||||
let text = vm.lookup_str(result).expect("got 应为字符串").to_string();
|
let text = vm.lookup_str(result).expect("got 应为字符串").to_string();
|
||||||
|
|
||||||
assert_eq!(text, "prombox".repeat(8));
|
assert_eq!(text, "prombox".repeat(8));
|
||||||
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期字符串 GC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 盒持唯一引用 session BigInt(Promise 结算值,运行时乘积非常量池字面量):
|
/// 盒持唯一引用 session BigInt(Promise 结算值,运行时乘积非常量池字面量):
|
||||||
@@ -440,6 +441,8 @@ fn promise_result_bigint_survives_runtime_gc() {
|
|||||||
0",
|
0",
|
||||||
);
|
);
|
||||||
vm.run(&Arc::new(first)).expect("run1");
|
vm.run(&Arc::new(first)).expect("run1");
|
||||||
|
// 统计按 run 复位:churn 在 run1 内,断言须在 run1 后读。
|
||||||
|
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
||||||
|
|
||||||
let second = compile("globalThis.got");
|
let second = compile("globalThis.got");
|
||||||
let result = vm.run(&Arc::new(second)).expect("run2");
|
let result = vm.run(&Arc::new(second)).expect("run2");
|
||||||
@@ -447,7 +450,6 @@ fn promise_result_bigint_survives_runtime_gc() {
|
|||||||
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
||||||
assert!(result.is_bigint(), "got 应为 BigInt");
|
assert!(result.is_bigint(), "got 应为 BigInt");
|
||||||
assert_eq!(vm.bigint_value(result), &expected);
|
assert_eq!(vm.bigint_value(result), &expected);
|
||||||
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 挂起生成器帧寄存器持唯一引用 session BigInt:yield 挂起后仅状态盒
|
/// 挂起生成器帧寄存器持唯一引用 session BigInt:yield 挂起后仅状态盒
|
||||||
@@ -485,6 +487,8 @@ fn suspended_async_function_bigint_survives_runtime_gc() {
|
|||||||
0",
|
0",
|
||||||
);
|
);
|
||||||
vm.run(&Arc::new(first)).expect("run1");
|
vm.run(&Arc::new(first)).expect("run1");
|
||||||
|
// 统计按 run 复位:churn 在 run1 内,断言须在 run1 后读。
|
||||||
|
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
||||||
|
|
||||||
let second = compile("globalThis.got");
|
let second = compile("globalThis.got");
|
||||||
let result = vm.run(&Arc::new(second)).expect("run2");
|
let result = vm.run(&Arc::new(second)).expect("run2");
|
||||||
@@ -492,7 +496,6 @@ fn suspended_async_function_bigint_survives_runtime_gc() {
|
|||||||
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
||||||
assert!(result.is_bigint(), "got 应为 BigInt");
|
assert!(result.is_bigint(), "got 应为 BigInt");
|
||||||
assert_eq!(vm.bigint_value(result), &expected);
|
assert_eq!(vm.bigint_value(result), &expected);
|
||||||
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 挂起异步生成器帧持唯一引用 session BigInt:首次 next 挂起后仅状态盒
|
/// 挂起异步生成器帧持唯一引用 session BigInt:首次 next 挂起后仅状态盒
|
||||||
@@ -511,6 +514,8 @@ fn suspended_async_generator_bigint_survives_runtime_gc() {
|
|||||||
run().then(function(v){ globalThis.got = v; })",
|
run().then(function(v){ globalThis.got = v; })",
|
||||||
);
|
);
|
||||||
vm.run(&Arc::new(first)).expect("run1");
|
vm.run(&Arc::new(first)).expect("run1");
|
||||||
|
// 统计按 run 复位:churn 在 run1 内,断言须在 run1 后读。
|
||||||
|
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
||||||
|
|
||||||
let second = compile("globalThis.got");
|
let second = compile("globalThis.got");
|
||||||
let result = vm.run(&Arc::new(second)).expect("run2");
|
let result = vm.run(&Arc::new(second)).expect("run2");
|
||||||
@@ -518,7 +523,6 @@ fn suspended_async_generator_bigint_survives_runtime_gc() {
|
|||||||
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
let expected = num_bigint::BigInt::from(987654321u64) * num_bigint::BigInt::from(123456789u64);
|
||||||
assert!(result.is_bigint(), "got 应为 BigInt");
|
assert!(result.is_bigint(), "got 应为 BigInt");
|
||||||
assert_eq!(vm.bigint_value(result), &expected);
|
assert_eq!(vm.bigint_value(result), &expected);
|
||||||
assert!(vm.session_gc_stats().total_collections > 0, "churn 应触发执行期 GC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 盒持唯一引用 session 串(Map 值):churn 窗口内收集经盒边闭合存活,
|
/// 盒持唯一引用 session 串(Map 值):churn 窗口内收集经盒边闭合存活,
|
||||||
|
|||||||
Reference in New Issue
Block a user