perf: CallFrame 构造 this 判别位并入 bool 组省 8 字节

This commit is contained in:
2026-10-13 08:18:34 +00:00
parent 07d72c00de
commit e154b12126
11 changed files with 71 additions and 36 deletions
+6 -4
View File
@@ -625,10 +625,11 @@ impl Vm {
self.raise_error_kind("ReferenceError", "super() called more than once")?;
return Ok(true);
}
let Some(derived_this) = frame.constructed_this else {
if !frame.has_constructed_this {
self.raise_error_kind("ReferenceError", "super() without derived this")?;
return Ok(true);
};
}
let derived_this = frame.constructed_this;
let callee = frame.callee;
let new_target = self.regs[255];
@@ -1197,10 +1198,11 @@ impl Vm {
self.raise_error_kind("ReferenceError", "super() called more than once")?;
return Ok(true);
}
let Some(derived_this) = frame.constructed_this else {
if !frame.has_constructed_this {
self.raise_error_kind("ReferenceError", "super() without derived this")?;
return Ok(true);
};
}
let derived_this = frame.constructed_this;
let callee = frame.callee;
let new_target = self.regs[255];
+2 -1
View File
@@ -102,7 +102,8 @@ fn gc_roots_contains_registers_frames_and_root_roots() {
arguments_obj: JsValue::undefined(),
construct_result_reg: None,
strict: false,
constructed_this: Some(JsValue::from_js_object(child_session)),
constructed_this: JsValue::from_js_object(child_session),
has_constructed_this: true,
is_derived_constructor: false,
super_called: false,
continuation: FrameContinuation::None,
+4 -3
View File
@@ -191,8 +191,8 @@ impl SuspendedFrame {
f(frame.saved_new_target);
f(frame.callee);
f(frame.arguments_obj);
if let Some(ct) = frame.constructed_this {
f(ct);
if frame.has_constructed_this {
f(frame.constructed_this);
}
}
for v in &self.spill_stack {
@@ -307,7 +307,8 @@ mod tests {
callee: tag,
arguments_obj: JsValue::undefined(),
construct_result_reg: None,
constructed_this: Some(tag),
constructed_this: tag,
has_constructed_this: true,
is_derived_constructor: false,
super_called: false,
strict: false,
+2 -1
View File
@@ -381,7 +381,8 @@ impl Vm {
callee,
arguments_obj: JsValue::undefined(),
construct_result_reg: construct.result_reg,
constructed_this: construct.constructed_this,
constructed_this: construct.constructed_this.unwrap_or(JsValue::undefined()),
has_constructed_this: construct.constructed_this.is_some(),
is_derived_constructor: obj.is_derived_constructor(),
super_called: false,
strict: sub_is_strict,
+19 -1
View File
@@ -68,7 +68,13 @@ pub struct CallFrame {
/// 无 mapped arguments 时为 undefined。GC 根(帧遍历期标记)。
pub arguments_obj: JsValue,
pub construct_result_reg: Option<u8>,
pub constructed_this: Option<JsValue>,
/// derived 构造器构造出的 this 值;仅当 `has_constructed_this` 为真时有效,
/// 标志为假时该槽为 undefined。
///
/// 判别位并入结构体尾部 bool 组(单字节容纳四个 bool),字段本体只占
/// 裸 JsValue 的 8 字节,帧整体比 Option 包装省 8 字节。
pub constructed_this: JsValue,
pub has_constructed_this: bool,
pub is_derived_constructor: bool,
/// derived 构造帧是否已成功调用 super()(父构造器正常返回后置位)。
///
@@ -91,6 +97,18 @@ pub struct CallFrame {
pub upvalues: *const [*mut Cell],
}
#[cfg(test)]
mod tests {
use super::CallFrame;
/// CallFrame 尺寸钉:constructed_this 的判别位并入尾部 bool 组后,
/// 帧固定 104 字节(Option 包装时代为 112 字节)。
#[test]
fn call_frame_size_pinned() {
assert_eq!(std::mem::size_of::<CallFrame>(), 104);
}
}
/// 一次 `for-in` 迭代的游标:已收集的 key 列表与当前下标。
///
/// 体是堆上 `Box`:迭代器表与挂起状态盒各独占持有体,出表/状态盒释放时
+8 -1
View File
@@ -74,7 +74,14 @@ impl Vm {
f(RootGroup::Frames, frame.saved_new_target);
f(RootGroup::Frames, frame.callee);
f(RootGroup::Frames, frame.arguments_obj);
f(RootGroup::Frames, frame.constructed_this.unwrap_or(JsValue::undefined()));
f(
RootGroup::Frames,
if frame.has_constructed_this {
frame.constructed_this
} else {
JsValue::undefined()
},
);
}
for &v in &self.save_stack {
f(RootGroup::SaveStack, v);
+5 -1
View File
@@ -819,7 +819,11 @@ impl Vm {
if let Some(frame) = self.frames.pop() {
self.cell_stack.pop();
let construct_result_reg = frame.construct_result_reg;
let constructed_this = frame.constructed_this;
let constructed_this = if frame.has_constructed_this {
Some(frame.constructed_this)
} else {
None
};
let is_derived_constructor = frame.is_derived_constructor;
let super_called = frame.super_called;
let continuation = frame.continuation;
+1 -1
View File
@@ -1646,7 +1646,7 @@ mod tests {
// NEW 帧契约:构造结果寄存器与 constructed_this 随帧携带
assert_eq!(frame.construct_result_reg, Some(0), "构造结果写回 regs[0]");
assert!(
frame.constructed_this.is_some_and(|v| v.is_object()),
frame.has_constructed_this && frame.constructed_this.is_object(),
"基类构造路径 constructed_this 应为新对象"
);
assert!(!frame.is_derived_constructor, "普通函数非 derived 构造器");
+2 -1
View File
@@ -852,7 +852,8 @@ fn reset_clears_runtime_state_like_rerun() {
arguments_obj: JsValue::undefined(),
construct_result_reg: None,
strict: false,
constructed_this: None,
constructed_this: JsValue::undefined(),
has_constructed_this: false,
is_derived_constructor: false,
super_called: false,
continuation: crate::vm::FrameContinuation::None,