mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: 超时崩溃记录带 last-pc 现场(pc/opcode/帧深)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
//! dispatch 主循环:逐指令解码与 OpCode 臂分派、执行期 GC 安全点、
|
||||
//! 步数/分配上限采样与二元运算宏 `binary_arith!`。
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use num_traits::Zero;
|
||||
use oxide_bytecode::opcode::{self, OpCode};
|
||||
use oxide_runtime_api as coercion;
|
||||
@@ -216,6 +218,21 @@ impl Vm {
|
||||
eprintln!("pc={pc:4} {op:>16} rd={rd} a={a} b={b}");
|
||||
}
|
||||
|
||||
// last-pc 现场:开启时每 2^16 指令追加写一行 pc/opcode/flat_id/frames,
|
||||
// 供监督者超时/崩溃杀子进程后读回挂死点(精度 = 距挂死点 2^16 指令内);
|
||||
// 关闭时零输出零分配。
|
||||
if let Some(watch) = self.pc_watch.as_ref() {
|
||||
if (steps & 0xFFFF) == 0 {
|
||||
let line =
|
||||
format!("pc={pc} op={op} flat_id={} frames={}\n", self.active_flat_id, self.frames.len());
|
||||
let _ = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(watch)
|
||||
.and_then(|mut f| f.write_all(line.as_bytes()));
|
||||
}
|
||||
}
|
||||
|
||||
match op {
|
||||
OpCode::NOP => {}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#![allow(clippy::arc_with_non_send_sync)]
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
#[cfg(test)]
|
||||
use std::sync::OnceLock;
|
||||
@@ -354,6 +355,10 @@ pub struct Vm {
|
||||
/// `pc + opcode + 操作数`。运行时开关,旁路 tracing 级别上限(release
|
||||
/// 构建可用);默认关闭,关闭时热路径仅一次 bool 比较,零输出零分配。
|
||||
pub trace_instructions: bool,
|
||||
/// last-pc 现场文件路径:开启时 dispatch 主循环每 2^16 指令追加写一行
|
||||
/// `pc/opcode/flat_id/frames`,供监督者超时/崩溃杀子进程后读回挂死点;
|
||||
/// 默认 None(零输出零分配)。
|
||||
pub(crate) pc_watch: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Drop for Vm {
|
||||
@@ -423,6 +428,13 @@ impl Vm {
|
||||
self.trace_instructions = on;
|
||||
}
|
||||
|
||||
/// 设置 last-pc 现场文件路径(开启后 dispatch 主循环每 2^16 指令追加写一行
|
||||
/// `pc/opcode/flat_id/frames`,供监督者超时/崩溃杀子进程后读回挂死点);
|
||||
/// None 清除。
|
||||
pub fn set_pc_watch(&mut self, path: Option<PathBuf>) {
|
||||
self.pc_watch = path;
|
||||
}
|
||||
|
||||
/// 只读访问 VM 的 epoch arena。
|
||||
pub fn epoch(&self) -> &Epoch {
|
||||
&self.epoch
|
||||
|
||||
@@ -158,6 +158,7 @@ impl Vm {
|
||||
saved_flat_id_stack: Vec::new(),
|
||||
saved_table_gen_stack: Vec::new(),
|
||||
trace_instructions: false,
|
||||
pc_watch: None,
|
||||
};
|
||||
vm.init_generator_intrinsics();
|
||||
vm.init_promise_intrinsics();
|
||||
@@ -293,6 +294,7 @@ impl Vm {
|
||||
saved_flat_id_stack: Vec::new(),
|
||||
saved_table_gen_stack: Vec::new(),
|
||||
trace_instructions: false,
|
||||
pc_watch: None,
|
||||
};
|
||||
vm.init_generator_intrinsics();
|
||||
vm.init_promise_intrinsics();
|
||||
|
||||
Reference in New Issue
Block a user