mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
refactor: 退役逃逸写屏障 vm 侧调用点与固有方法
This commit is contained in:
@@ -717,7 +717,6 @@ impl Vm {
|
|||||||
self.raise_error_kind("TypeError", "SET_HOME_OBJECT expects function and object")?;
|
self.raise_error_kind("TypeError", "SET_HOME_OBJECT expects function and object")?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let home_val = self.promote_if_needed_for_write_ptr(func_val.as_js_object_ptr(), home_val);
|
|
||||||
let func_obj = unsafe { &mut *func_val.as_js_object_ptr() };
|
let func_obj = unsafe { &mut *func_val.as_js_object_ptr() };
|
||||||
if !func_obj.is_function() {
|
if !func_obj.is_function() {
|
||||||
self.raise_error_kind("TypeError", "SET_HOME_OBJECT target is not a function")?;
|
self.raise_error_kind("TypeError", "SET_HOME_OBJECT target is not a function")?;
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ impl Vm {
|
|||||||
return self.raise_type_error("private field has no setter");
|
return self.raise_type_error("private field has no setter");
|
||||||
}
|
}
|
||||||
let setter = meta.set;
|
let setter = meta.set;
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
return self.call_or_push_setter(setter, obj_val, value, true);
|
return self.call_or_push_setter(setter, obj_val, value, true);
|
||||||
}
|
}
|
||||||
// 私有方法槽不可写(init 时打标记)。
|
// 私有方法槽不可写(init 时打标记)。
|
||||||
@@ -237,7 +237,7 @@ impl Vm {
|
|||||||
.raise_type_error("Cannot write private member to an object whose class did not declare it");
|
.raise_type_error("Cannot write private member to an object whose class did not declare it");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
obj.set_prop_shape(pos, value);
|
obj.set_prop_shape(pos, value);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -257,7 +257,7 @@ impl Vm {
|
|||||||
return self.raise_type_error("private field has no setter");
|
return self.raise_type_error("private field has no setter");
|
||||||
}
|
}
|
||||||
let setter = meta.set;
|
let setter = meta.set;
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
return self.call_or_push_setter(setter, obj_val, value, true);
|
return self.call_or_push_setter(setter, obj_val, value, true);
|
||||||
}
|
}
|
||||||
// 私有方法槽不可写(init 时打标记)。
|
// 私有方法槽不可写(init 时打标记)。
|
||||||
@@ -266,7 +266,7 @@ impl Vm {
|
|||||||
.raise_type_error("Cannot write private member to an object whose class did not declare it");
|
.raise_type_error("Cannot write private member to an object whose class did not declare it");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let value = self.promote_if_needed_for_write_ptr(home_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let home = unsafe { &mut *home_ptr };
|
let home = unsafe { &mut *home_ptr };
|
||||||
home.set_prop_shape(pos, value);
|
home.set_prop_shape(pos, value);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -281,7 +281,7 @@ impl Vm {
|
|||||||
let private_key = self.private_key_from_reg(b);
|
let private_key = self.private_key_from_reg(b);
|
||||||
let is_method = self.bytecode[self.pc] != 0;
|
let is_method = self.bytecode[self.pc] != 0;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
if self
|
if self
|
||||||
.kernel_core
|
.kernel_core
|
||||||
@@ -453,7 +453,7 @@ impl Vm {
|
|||||||
// read_ic_slot0 先消费全部扩展字,命中路径无需解析键。
|
// read_ic_slot0 先消费全部扩展字,命中路径无需解析键。
|
||||||
let (cached_shape_id, cached_slot, cached_depth) = ic_helper::read_ic_slot0(&self.bytecode, &mut self.pc);
|
let (cached_shape_id, cached_slot, cached_depth) = ic_helper::read_ic_slot0(&self.bytecode, &mut self.pc);
|
||||||
let ic_pc = self.pc;
|
let ic_pc = self.pc;
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let receiver = self.regs[rd];
|
let receiver = self.regs[rd];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
|
|
||||||
@@ -534,7 +534,7 @@ impl Vm {
|
|||||||
};
|
};
|
||||||
let prop_name_si = self.property_key_si(self.regs[b])?;
|
let prop_name_si = self.property_key_si(self.regs[b])?;
|
||||||
if self.kernel_core.perm_interner().lookup(prop_name_si) == Some("__proto__") {
|
if self.kernel_core.perm_interner().lookup(prop_name_si) == Some("__proto__") {
|
||||||
let proto_value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let proto_value = self.regs[a];
|
||||||
if self.is_object_prototype(obj_ptr) && !proto_value.is_null() {
|
if self.is_object_prototype(obj_ptr) && !proto_value.is_null() {
|
||||||
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
|
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -543,25 +543,24 @@ impl Vm {
|
|||||||
obj.set_proto(proto_value).map_err(|e| e.to_string())?;
|
obj.set_proto(proto_value).map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
self.ordinary_set_dispatch(obj, prop_name_si, value, self.regs[rd], self.current_strict())?;
|
self.ordinary_set_dispatch(obj, prop_name_si, value, self.regs[rd], self.current_strict())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 对象字面量批量构造的纯槽写:把值写入键序预建 shape 的 `slot` 槽。
|
/// 对象字面量批量构造的纯槽写:把值写入键序预建 shape 的 `slot` 槽。
|
||||||
/// 不做键解析/`__proto__` 拦截/promote 之外的任何形状变更——键与槽位由
|
/// 不做键解析、`__proto__` 拦截或任何形状变更——键与槽位由
|
||||||
/// NEW_OBJECT 的键常量表一次性建好。
|
/// NEW_OBJECT 的键常量表一次性建好。
|
||||||
///
|
///
|
||||||
/// # 边界与前提
|
/// # 边界与前提
|
||||||
/// - `slot` 必须 < NEW_OBJECT 预分配的槽数(emit 保证 ≤255)。
|
/// - `slot` 必须 < NEW_OBJECT 预分配的槽数(emit 保证 ≤255)。
|
||||||
/// - 值仍需 promote(对象值可能来自 session epoch 且目标是逃逸根)。
|
|
||||||
fn dispatch_set_prop_batch(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
fn dispatch_set_prop_batch(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||||
vm_trace!("SET_PROP_BATCH rd={} slot={}", rd, b);
|
vm_trace!("SET_PROP_BATCH rd={} slot={}", rd, b);
|
||||||
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
|
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
|
let value = self.regs[a];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
obj.set_prop_storage(b, value);
|
obj.set_prop_storage(b, value);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -619,9 +618,7 @@ impl Vm {
|
|||||||
if obj.is_array() && obj.array_elements_meta_vec().is_none() {
|
if obj.is_array() && obj.array_elements_meta_vec().is_none() {
|
||||||
let idx = int_key_value(prop_name_si);
|
let idx = int_key_value(prop_name_si);
|
||||||
if idx < obj.array_prop_count {
|
if idx < obj.array_prop_count {
|
||||||
// promote 必须保留:obj 是 session 根、写入值可能是 epoch 对象,
|
let value = self.regs[b];
|
||||||
// 不 promote 下轮 GC 会悬垂。
|
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[b]);
|
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
obj.set_prop_storage(idx as usize, value);
|
obj.set_prop_storage(idx as usize, value);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -631,7 +628,7 @@ impl Vm {
|
|||||||
// 整数键恒不可能等于 "__proto__"(字符串 intern id 远小于整数键区间),
|
// 整数键恒不可能等于 "__proto__"(字符串 intern id 远小于整数键区间),
|
||||||
// 短路免去每次 set 的 RwLock 查询。
|
// 短路免去每次 set 的 RwLock 查询。
|
||||||
if !is_int_key(prop_name_si) && self.kernel_core.perm_interner().lookup(prop_name_si) == Some("__proto__") {
|
if !is_int_key(prop_name_si) && self.kernel_core.perm_interner().lookup(prop_name_si) == Some("__proto__") {
|
||||||
let proto_value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[b]);
|
let proto_value = self.regs[b];
|
||||||
if self.is_object_prototype(obj_ptr) && !proto_value.is_null() {
|
if self.is_object_prototype(obj_ptr) && !proto_value.is_null() {
|
||||||
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
|
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -640,7 +637,7 @@ impl Vm {
|
|||||||
obj.set_proto(proto_value).map_err(|e| e.to_string())?;
|
obj.set_proto(proto_value).map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[b]);
|
let value = self.regs[b];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
self.ordinary_set_dispatch(obj, prop_name_si, value, self.regs[rd], self.current_strict())?;
|
self.ordinary_set_dispatch(obj, prop_name_si, value, self.regs[rd], self.current_strict())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -658,7 +655,7 @@ impl Vm {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[b]);
|
let value = self.regs[b];
|
||||||
let obj = unsafe { &mut *obj_ptr };
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
// 有属性 meta(freeze/seal 逐属性写 meta 后恒 true,含 accessor 元素/描述符
|
// 有属性 meta(freeze/seal 逐属性写 meta 后恒 true,含 accessor 元素/描述符
|
||||||
// 元素):回落 ordinary_set 走完整 writable/accessor/extensible 检查,防止
|
// 元素):回落 ordinary_set 走完整 writable/accessor/extensible 检查,防止
|
||||||
|
|||||||
@@ -1080,8 +1080,7 @@ impl Vm {
|
|||||||
));
|
));
|
||||||
let rest = unsafe { &mut *rest_ptr };
|
let rest = unsafe { &mut *rest_ptr };
|
||||||
for (si, val) in assignments {
|
for (si, val) in assignments {
|
||||||
let promoted = self.promote_if_needed_for_write_ptr(rest_ptr, val);
|
self.set_or_create_prop_value(rest, si, val);
|
||||||
self.set_or_create_prop_value(rest, si, promoted);
|
|
||||||
}
|
}
|
||||||
self.regs[rd] = JsValue::from_js_object(rest_ptr);
|
self.regs[rd] = JsValue::from_js_object(rest_ptr);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1156,8 +1155,7 @@ impl Vm {
|
|||||||
// 提交:覆盖目标已有同名属性(从左到右求值,后展开者胜)。
|
// 提交:覆盖目标已有同名属性(从左到右求值,后展开者胜)。
|
||||||
let target = unsafe { &mut *target_val.as_js_object_ptr() };
|
let target = unsafe { &mut *target_val.as_js_object_ptr() };
|
||||||
for (si, val) in assignments {
|
for (si, val) in assignments {
|
||||||
let promoted = self.promote_if_needed_for_write_ptr(target, val);
|
self.set_or_create_prop_value(target, si, val);
|
||||||
self.set_or_create_prop_value(target, si, promoted);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1199,9 +1197,9 @@ impl Vm {
|
|||||||
|
|
||||||
let proto_ptr = self.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
let proto_ptr = self.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||||
let proto_val = JsValue::from_js_object(proto_ptr);
|
let proto_val = JsValue::from_js_object(proto_ptr);
|
||||||
// 模板对象直接分配为 session 对象:跨 epoch 写入(存进 global/数组)时
|
// 模板对象直接分配为 session 对象:写入 session 根(存进 global/数组)
|
||||||
// 免 promote 搬移——若按 epoch 分配,首次写入 session 根会把对象搬到新
|
// 时对象地址稳定,缓存指针不失效——分配档不同则首次写入触发搬移,
|
||||||
// 地址,缓存中的旧指针与新实例分叉,同一 site 两次取值将返回不同对象。
|
// 缓存旧指针与新实例分叉,同一 site 两次取值将返回不同对象。
|
||||||
let mut alloc_session_array = |n: usize| {
|
let mut alloc_session_array = |n: usize| {
|
||||||
let clone = JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump());
|
let clone = JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump());
|
||||||
self.alloc_session_object(clone)
|
self.alloc_session_object(clone)
|
||||||
@@ -1215,7 +1213,7 @@ impl Vm {
|
|||||||
let elem_attrs = PropAttributes::new(false, true, false);
|
let elem_attrs = PropAttributes::new(false, true, false);
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
let (c_val, r_val) = {
|
let (c_val, r_val) = {
|
||||||
// immutables 借用限于本块:promote 需 &mut self,先取值再放行借用。
|
// immutables 借用限于本块:先取出本段两值,再放行借用。
|
||||||
let imm = self.immutables();
|
let imm = self.immutables();
|
||||||
let c_val = if cooked_words[i] & 0x8000_0000 != 0 {
|
let c_val = if cooked_words[i] & 0x8000_0000 != 0 {
|
||||||
JsValue::undefined()
|
JsValue::undefined()
|
||||||
@@ -1225,13 +1223,11 @@ impl Vm {
|
|||||||
let r_val = imm.get(raw_idxs[i] as usize).copied().unwrap_or(JsValue::undefined());
|
let r_val = imm.get(raw_idxs[i] as usize).copied().unwrap_or(JsValue::undefined());
|
||||||
(c_val, r_val)
|
(c_val, r_val)
|
||||||
};
|
};
|
||||||
let c_promoted = self.promote_if_needed_for_write_ptr(cooked, c_val);
|
|
||||||
let r_promoted = self.promote_if_needed_for_write_ptr(raw, r_val);
|
|
||||||
// SAFETY: cooked/raw 为本函数刚分配的 epoch 对象,借用仅在本循环内消费。
|
// SAFETY: cooked/raw 为本函数刚分配的 epoch 对象,借用仅在本循环内消费。
|
||||||
unsafe {
|
unsafe {
|
||||||
(*cooked).set_prop_at(i, c_promoted);
|
(*cooked).set_prop_at(i, c_val);
|
||||||
(*cooked).set_data_meta(i, elem_attrs);
|
(*cooked).set_data_meta(i, elem_attrs);
|
||||||
(*raw).set_prop_at(i, r_promoted);
|
(*raw).set_prop_at(i, r_val);
|
||||||
(*raw).set_data_meta(i, elem_attrs);
|
(*raw).set_data_meta(i, elem_attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,7 +326,6 @@ impl Vm {
|
|||||||
pub(crate) fn ordinary_set(
|
pub(crate) fn ordinary_set(
|
||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
|
|
||||||
self.ordinary_set_inner(obj, prop_name_si, val, receiver, false, strict, false)
|
self.ordinary_set_inner(obj, prop_name_si, val, receiver, false, strict, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,11 +335,10 @@ impl Vm {
|
|||||||
pub(crate) fn ordinary_set_builtin(
|
pub(crate) fn ordinary_set_builtin(
|
||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
|
|
||||||
self.ordinary_set_inner(obj, prop_name_si, val, receiver, false, strict, true)
|
self.ordinary_set_inner(obj, prop_name_si, val, receiver, false, strict, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 分发期入口:调用方(dispatch_set_prop 等)已对值做过 promote。
|
/// 分发期入口:值直接落位。
|
||||||
pub(crate) fn ordinary_set_dispatch(
|
pub(crate) fn ordinary_set_dispatch(
|
||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, strict: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@@ -792,7 +790,6 @@ impl Vm {
|
|||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, ext_pc: usize,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, ext_pc: usize,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
ic_trace!("set_member_prop: shape_id={} prop_name_si={}", obj.shape_id(), prop_name_si);
|
ic_trace!("set_member_prop: shape_id={} prop_name_si={}", obj.shape_id(), prop_name_si);
|
||||||
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
|
|
||||||
// 写方即当前执行函数(赋值语义),strict/sloppy 判定取当前上下文。
|
// 写方即当前执行函数(赋值语义),strict/sloppy 判定取当前上下文。
|
||||||
let strict = self.current_strict();
|
let strict = self.current_strict();
|
||||||
if obj.has_prop_meta() {
|
if obj.has_prop_meta() {
|
||||||
@@ -1008,7 +1005,6 @@ impl Vm {
|
|||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, attributes: PropAttributes,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, attributes: PropAttributes,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
vm_trace!("define_data_property: shape={} prop_si={}", obj.shape_id(), prop_name_si);
|
vm_trace!("define_data_property: shape={} prop_si={}", obj.shape_id(), prop_name_si);
|
||||||
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
|
|
||||||
// TypedArray 统一数值键门:界内规范键走元素定义(界内写 buffer);
|
// TypedArray 统一数值键门:界内规范键走元素定义(界内写 buffer);
|
||||||
// 规范越界键(含 detach:live 长 0)拒绝定义;非规范数值串
|
// 规范越界键(含 detach:live 长 0)拒绝定义;非规范数值串
|
||||||
// ("+1"/"1.0" 等,round-trip 不成)与 symbol 键落命名属性路径。
|
// ("+1"/"1.0" 等,round-trip 不成)与 symbol 键落命名属性路径。
|
||||||
@@ -1129,9 +1125,6 @@ impl Vm {
|
|||||||
&mut self, obj: &mut JsObject, prop_name_si: u32, get: JsValue, set: JsValue, attributes: PropAttributes,
|
&mut self, obj: &mut JsObject, prop_name_si: u32, get: JsValue, set: JsValue, attributes: PropAttributes,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
vm_trace!("define_accessor_property: shape={} prop_si={}", obj.shape_id(), prop_name_si);
|
vm_trace!("define_accessor_property: shape={} prop_si={}", obj.shape_id(), prop_name_si);
|
||||||
let target_ptr = obj as *mut JsObject;
|
|
||||||
let get = self.promote_if_needed_for_write_ptr(target_ptr, get);
|
|
||||||
let set = self.promote_if_needed_for_write_ptr(target_ptr, set);
|
|
||||||
// TA 数值索引臂:界内 / 数字无效索引不接受 accessor(false);非规范数字
|
// TA 数值索引臂:界内 / 数字无效索引不接受 accessor(false);非规范数字
|
||||||
// 串 / symbol 键落真实 accessor 属性。
|
// 串 / symbol 键落真实 accessor 属性。
|
||||||
if obj.is_typed_array_obj() {
|
if obj.is_typed_array_obj() {
|
||||||
|
|||||||
@@ -555,11 +555,6 @@ impl Vm {
|
|||||||
self.active_reg_limit = 0;
|
self.active_reg_limit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 逃逸写屏障:写向全局/session 目标的对象值原样直通,不克隆。
|
|
||||||
pub(crate) fn promote_if_needed_for_write_ptr(&mut self, _target_ptr: *mut JsObject, value: JsValue) -> JsValue {
|
|
||||||
value
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 分配一个可被 session GC 回收的字符串 `JsValue`(session-heap 字符串)。
|
/// 分配一个可被 session GC 回收的字符串 `JsValue`(session-heap 字符串)。
|
||||||
pub fn new_string(&mut self, s: &str) -> JsValue {
|
pub fn new_string(&mut self, s: &str) -> JsValue {
|
||||||
self.new_string_owned(s.to_string())
|
self.new_string_owned(s.to_string())
|
||||||
@@ -719,8 +714,8 @@ impl Vm {
|
|||||||
obj.set_captured_this(self.regs[254]);
|
obj.set_captured_this(self.regs[254]);
|
||||||
}
|
}
|
||||||
// 函数对象直接 session 分配:寿命从调用级延至 session 级(session GC
|
// 函数对象直接 session 分配:寿命从调用级延至 session 级(session GC
|
||||||
// mark/sweep 回收)。若按 epoch 分配,写入全局等逃逸根时 promote 屏障会
|
// mark/sweep 回收),写入全局等逃逸根时地址稳定,全局属性与局部槽
|
||||||
// 深克隆进 session,全局属性与局部槽指针分裂、严格相等恒 false。
|
// 指向同一对象,严格相等保持。
|
||||||
let obj_ptr = self.alloc_session_object(obj);
|
let obj_ptr = self.alloc_session_object(obj);
|
||||||
let func_val = JsValue::object(obj_ptr as *mut u8);
|
let func_val = JsValue::object(obj_ptr as *mut u8);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user