feat: 编译管线/类型层 crate 补全多级日志宏 + 关键路径日志

This commit is contained in:
2026-08-10 17:56:28 +08:00
parent 9fa8ae5b5f
commit 8a53bfb584
34 changed files with 421 additions and 1 deletions
+1
View File
@@ -7,3 +7,4 @@ rust-version.workspace = true
description = "OxideJS - Shared bytecode protocol and compiled module ABI"
[dependencies]
oxide_log = { path = "../oxide_log" }
+37
View File
@@ -0,0 +1,37 @@
//! bytecode 日志宏:`bytecode_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! bytecode_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! bytecode_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! bytecode_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! bytecode_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! bytecode_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+3
View File
@@ -1,5 +1,8 @@
#![doc = "OxideJS - Shared bytecode protocol and compiled module ABI"]
/// bytecode 日志宏(`bytecode_error`/`bytecode_info` 等),target 为 `oxide::kernel`。
mod bytecode_log;
/// 编译产物与常量池 ABI([`CompiledModule`] / [`Constant`])。
pub mod module;
/// 操作码表与指令编解码([`OpCode`] / [`Instr`])。
+1
View File
@@ -9,6 +9,7 @@ description = "OxideJS - basic block partition and CFG analysis pass over IR"
[dependencies]
oxide_ir = { path = "../oxide_ir" }
oxide_bytecode = { path = "../oxide_bytecode" }
oxide_log = { path = "../oxide_log" }
[dev-dependencies]
oxide_parser = { path = "../oxide_parser" }
+37
View File
@@ -0,0 +1,37 @@
//! CFG 日志宏:`cfg_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! cfg_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! cfg_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! cfg_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! cfg_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! cfg_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+4 -1
View File
@@ -8,6 +8,7 @@
//! (异常边)→ `finalize`(exit 哨兵 + preds 反推)。每阶段是独立文件的纯函数,
//! 中间产物(heads / blocks / exit_id)显式传参,无共享可变状态。
mod cfg_log;
mod exception;
mod finalize;
mod partition;
@@ -93,7 +94,9 @@ pub fn build_cfg(f: &IRFunction) -> Cfg {
let heads = partition::partition_blocks(f);
let (mut blocks, exit_id) = split::split_and_edges(f, &heads);
exception::add_exception_edges(f, &mut blocks);
finalize::finalize(blocks, exit_id)
let cfg = finalize::finalize(blocks, exit_id);
cfg_debug!("build_cfg: {} blocks", cfg.blocks.len());
cfg
}
#[cfg(test)]
+3
View File
@@ -43,8 +43,10 @@ impl Compiler {
pub fn compile(&self, program: &oxide_parser::Program) -> Result<CompiledModule, String> {
crate::compiler_debug!("compile: starting...");
let mut ir = Emitter::new().emit_program(program)?;
crate::compiler_debug!("compile: after emit {} insts", ir.insts.len());
if self.enable_dce {
oxide_dce::dce(&mut ir); // 顶层函数;nested 不递归
crate::compiler_debug!("compile: after DCE {} insts", ir.insts.len());
}
if self.enable_regalloc && !ir.const_overflow {
// 优化管线:liveness → 精确 DCE → 重算 liveness → RegAlloc
@@ -56,6 +58,7 @@ impl Compiler {
let cfg2 = oxide_cfg::build_cfg(&ir); // 精确 DCE 删指令后 inst 下标位移,CFG 重建
let live2 = oxide_liveness::liveness(&ir, &cfg2); // 重算,绝不用过期 live
oxide_regalloc::alloc(&mut ir, &live2)?; // 无可行染色 → RangeError 上抛
crate::compiler_debug!("compile: after regalloc {} insts", ir.insts.len());
}
crate::compiler_debug!("compile: done, {} instructions", ir.insts.len());
let mut module = lower(&ir)?;
+1
View File
@@ -11,6 +11,7 @@ oxide_ir = { path = "../oxide_ir" }
oxide_cfg = { path = "../oxide_cfg" }
oxide_bytecode = { path = "../oxide_bytecode" }
oxide_liveness = { path = "../oxide_liveness" }
oxide_log = { path = "../oxide_log" }
[dev-dependencies]
oxide_parser = { path = "../oxide_parser" }
+37
View File
@@ -0,0 +1,37 @@
//! DCE 日志宏:`dce_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! dce_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! dce_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! dce_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! dce_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! dce_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+3
View File
@@ -13,6 +13,7 @@
//! 精确二轮 `dce_precise`:liveness 驱动的死指令 + 局部死 STORE_VAR 删除,
//! 消费 `oxide_liveness::LiveInfo`,mark-sweep 重建复用 Pass C。
mod dce_log;
mod iter_sweep;
mod precise_sweep;
mod reachability;
@@ -31,6 +32,8 @@ pub fn dce(f: &mut IRFunction) {
let mut keep = reachability::pass_a_reachable(f);
// Pass B:可达存活指令上全函数 use 计数迭代删除到不动点(连锁删上游写者)。
iter_sweep::pass_b_dead_code(f, &mut keep);
let dead = keep.iter().filter(|k| !**k).count();
dce_info!("DCE: removing {} dead instructions", dead);
// Pass C:mark-sweep 一次性重建 insts + label_pos 重映射。
rebuild::pass_c_sweep(f, &keep);
}
+1
View File
@@ -10,6 +10,7 @@ description = "OxideJS - AST to IR emit pass"
oxide_parser = { path = "../oxide_parser" }
oxide_bytecode = { path = "../oxide_bytecode" }
oxide_ir = { path = "../oxide_ir" }
oxide_log = { path = "../oxide_log" }
regex.workspace = true
regress.workspace = true
+1
View File
@@ -1270,6 +1270,7 @@ impl Emitter {
/// 调用方为 `oxide_compiler::Compiler::compile`:本函数完成 emit 半程,
/// 随后由 `oxide_ir::lower::lower` 降为字节码。
pub fn emit_program(&self, program: &oxide_parser::Program) -> Result<IRFunction, String> {
crate::emit_debug!("emit_program: {} stmts", program.body.len());
let mut ctx = CompileCtx::new();
// 脚本顶层:var/function 声明需落到全局对象,let/const/class 不进全局。
ctx.is_global_scope = true;
+37
View File
@@ -0,0 +1,37 @@
//! emit 日志宏:`emit_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! emit_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! emit_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! emit_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! emit_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! emit_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -8,6 +8,7 @@
pub mod class;
pub mod closure;
pub mod emit;
mod emit_log;
pub mod emit_ctx;
pub mod expr;
pub mod prepass;
+1
View File
@@ -8,4 +8,5 @@ description = "OxideJS - IR intermediate representation and lowering to bytecode
[dependencies]
oxide_bytecode = { path = "../oxide_bytecode" }
oxide_log = { path = "../oxide_log" }
smallvec.workspace = true
+37
View File
@@ -0,0 +1,37 @@
//! IR 日志宏:`ir_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! ir_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! ir_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! ir_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! ir_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! ir_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -13,6 +13,7 @@
pub mod contract;
pub mod inst;
mod ir_log;
pub mod lower;
pub mod operand;
+1
View File
@@ -15,6 +15,7 @@ use crate::IRFunction;
/// IRFunction → CompiledModule 等价转换。溢出/标签错误消息为既有格式,逐字保持一致。
pub fn lower(f: &IRFunction) -> Result<CompiledModule, String> {
crate::ir_debug!("lower: {} insts", f.insts.len());
// 溢出检查 1:常量池(先于寄存器——超大常量池伴生的海量 vreg 会使后续检查的
// 稠密 bitset 表示爆内存;常量池超限是更基础的失效,先报它)
if f.const_overflow || f.constants.len() > u16::MAX as usize {
+1
View File
@@ -9,6 +9,7 @@ description = "OxideJS - liveness analysis pass over IR (CFG dataflow + per-inst
[dependencies]
oxide_ir = { path = "../oxide_ir" }
oxide_cfg = { path = "../oxide_cfg" }
oxide_log = { path = "../oxide_log" }
[dev-dependencies]
oxide_parser = { path = "../oxide_parser" }
+2
View File
@@ -7,6 +7,7 @@
mod dataflow;
mod live_info;
mod liveness_log;
mod ranges;
pub use live_info::LiveInfo;
@@ -20,6 +21,7 @@ pub fn liveness(f: &IRFunction, cfg: &Cfg) -> LiveInfo {
if f.insts.is_empty() {
return LiveInfo::new();
}
liveness_debug!("liveness: {} blocks, {} insts", cfg.blocks.len(), f.insts.len());
let (block_in, block_out, reg_count) = dataflow::block_liveness(f, cfg);
let (inst_before, inst_after) = ranges::inst_liveness(f, cfg, &block_out, &block_in, reg_count);
LiveInfo {
+37
View File
@@ -0,0 +1,37 @@
//! liveness 日志宏:`liveness_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! liveness_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! liveness_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! liveness_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! liveness_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! liveness_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -7,6 +7,7 @@ rust-version.workspace = true
description = "OxideJS - JavaScript parser (oxc_parser re-export)"
[dependencies]
oxide_log = { path = "../oxide_log" }
oxc_parser.workspace = true
oxc_allocator.workspace = true
oxc_ast.workspace = true
+1
View File
@@ -1,6 +1,7 @@
#![doc = "OxideJS - JavaScript parser (oxc_parser re-export)"]
mod error;
mod parser_log;
/// 解析错误:消息 + 源文件字节区间(起始,结束)。
pub use error::OxideError;
+37
View File
@@ -0,0 +1,37 @@
//! parser 日志宏:`parser_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! parser_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! parser_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! parser_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! parser_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! parser_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -11,6 +11,7 @@ oxide_ir = { path = "../oxide_ir" }
oxide_liveness = { path = "../oxide_liveness" }
oxide_bytecode = { path = "../oxide_bytecode" }
oxide_cfg = { path = "../oxide_cfg" }
oxide_log = { path = "../oxide_log" }
[dev-dependencies]
oxide_parser = { path = "../oxide_parser" }
+2
View File
@@ -10,6 +10,7 @@ mod alloc_map;
mod color;
mod finish;
mod graph;
mod regalloc_log;
mod rewrite;
pub use alloc_map::{Alloc, AllocMap, FreshKind, FreshVreg, SpillPlan};
@@ -50,6 +51,7 @@ pub fn alloc(f: &mut IRFunction, live: &LiveInfo) -> Result<(), String> {
oxide_liveness::liveness(f, &cfg)
};
let map = color(f, &live)?;
regalloc_debug!("alloc: {} vregs -> {} phys", map.map.len(), map.phys_peak);
rewrite::run(f, &map);
finish::run(f, &map);
for child in &mut f.nested {
+37
View File
@@ -0,0 +1,37 @@
//! RegAlloc 日志宏:`regalloc_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 编译管线属 Kernel 子系统,`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志。
#[macro_export]
macro_rules! regalloc_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! regalloc_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! regalloc_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! regalloc_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! regalloc_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -9,4 +9,5 @@ description = "OxideJS - VmHost trait: the abstract Vm interface builtins are wr
[dependencies]
oxide_types = { path = "../oxide_types" }
oxide_kernel = { path = "../oxide_kernel" }
oxide_log = { path = "../oxide_log" }
ryu.workspace = true
+2
View File
@@ -10,6 +10,8 @@
//! trait 面向泛型而非对象安全:单态化 `H = Vm` 使每个 `host.*()` 调用内联,
//! 相对 builtins 直接位于 `oxide_vm` 内部没有运行时开销。
mod runtime_api_log;
use std::sync::Arc;
use oxide_kernel::kernel::{KernelCore, KernelSession};
@@ -0,0 +1,38 @@
//! runtime_api 日志宏:`runtime_api_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 接口层供编译管线与运行时共享,日志归 Kernel 子系统
//! (`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志)。
#[macro_export]
macro_rules! runtime_api_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! runtime_api_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! runtime_api_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! runtime_api_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! runtime_api_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}
+1
View File
@@ -9,6 +9,7 @@ description = "OxideJS - Shared core types (JsValue, JsObject, Shape, P, Epoch)"
[dependencies]
bumpalo.workspace = true
hashbrown.workspace = true
oxide_log = { path = "../oxide_log" }
rustc-hash.workspace = true
[dev-dependencies]
+3
View File
@@ -13,5 +13,8 @@ pub mod shape;
/// ECMAScript 值(NaN-boxing 的 `JsValue`)。
pub mod value;
/// 类型层日志宏(`types_error`/`types_info` 等),target 为 `oxide::kernel`。
mod types_log;
/// 重导出 [`error`] 模块的运行时错误类型。
pub use error::{JsError, JsErrorKind};
+38
View File
@@ -0,0 +1,38 @@
//! 类型层日志宏:`types_error!/warn!/info!/debug!/trace!`,经由 oxide_log 上报。
//! 类型层供编译管线与运行时共享,日志归 Kernel 子系统
//! (`OXIDE_LOG=oxide::kernel=debug` 控制本 crate 日志)。
#[macro_export]
macro_rules! types_error {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::ERROR, $($arg)*)
};
}
#[macro_export]
macro_rules! types_warn {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::WARN, $($arg)*)
};
}
#[macro_export]
macro_rules! types_info {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::INFO, $($arg)*)
};
}
#[macro_export]
macro_rules! types_debug {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::DEBUG, $($arg)*)
};
}
#[macro_export]
macro_rules! types_trace {
($($arg:tt)*) => {
oxide_log::__log_event!("oxide::kernel", oxide_log::tracing::Level::TRACE, $($arg)*)
};
}