Skip to content

Commit e3e94e3

Browse files
committed
Replace NanBoxing's Box with Arc and improve clone/drop
1 parent 13a030a commit e3e94e3

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

core/engine/src/value/inner/nan_boxed.rs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ use boa_gc::{custom_trace, Finalize, Trace};
114114
use boa_string::JsString;
115115
use core::fmt;
116116
use static_assertions::const_assert;
117+
use std::sync::Arc;
117118

118119
// We cannot NaN-box pointers larger than 64 bits.
119120
const_assert!(size_of::<usize>() <= size_of::<u64>());
@@ -128,6 +129,7 @@ mod bits {
128129
use boa_engine::{JsBigInt, JsObject, JsSymbol};
129130
use boa_string::JsString;
130131
use std::ptr::NonNull;
132+
use std::sync::Arc;
131133

132134
/// Undefined value in `u64`.
133135
pub(super) const UNDEFINED: u64 = 0x7FF4_0000_0000_0000;
@@ -296,8 +298,8 @@ mod bits {
296298
/// by calling `[Self::drop_pointer]`.
297299
#[inline(always)]
298300
#[allow(clippy::identity_op)]
299-
pub(super) unsafe fn tag_bigint(value: Box<JsBigInt>) -> u64 {
300-
let value = Box::into_raw(value) as u64;
301+
pub(super) unsafe fn tag_bigint(value: Arc<JsBigInt>) -> u64 {
302+
let value = Arc::into_raw(value) as u64;
301303
let value_masked: u64 = value & POINTER_MASK;
302304

303305
// Assert alignment and location of the pointer.
@@ -321,8 +323,8 @@ mod bits {
321323
/// The box is forgotten after this operation. It must be dropped separately,
322324
/// by calling `[Self::drop_pointer]`.
323325
#[inline(always)]
324-
pub(super) unsafe fn tag_object(value: Box<JsObject>) -> u64 {
325-
let value = Box::into_raw(value) as u64;
326+
pub(super) unsafe fn tag_object(value: Arc<JsObject>) -> u64 {
327+
let value = Arc::into_raw(value) as u64;
326328
let value_masked: u64 = value & POINTER_MASK;
327329

328330
// Assert alignment and location of the pointer.
@@ -346,8 +348,8 @@ mod bits {
346348
/// The box is forgotten after this operation. It must be dropped separately,
347349
/// by calling `[Self::drop_pointer]`.
348350
#[inline(always)]
349-
pub(super) unsafe fn tag_symbol(value: Box<JsSymbol>) -> u64 {
350-
let value = Box::into_raw(value) as u64;
351+
pub(super) unsafe fn tag_symbol(value: Arc<JsSymbol>) -> u64 {
352+
let value = Arc::into_raw(value) as u64;
351353
let value_masked: u64 = value & POINTER_MASK;
352354

353355
// Assert alignment and location of the pointer.
@@ -371,8 +373,8 @@ mod bits {
371373
/// The box is forgotten after this operation. It must be dropped separately,
372374
/// by calling `[Self::drop_pointer]`.
373375
#[inline(always)]
374-
pub(super) unsafe fn tag_string(value: Box<JsString>) -> u64 {
375-
let value = Box::into_raw(value) as u64;
376+
pub(super) unsafe fn tag_string(value: Arc<JsString>) -> u64 {
377+
let value = Arc::into_raw(value) as u64;
376378
let value_masked: u64 = value & POINTER_MASK;
377379

378380
// Assert alignment and location of the pointer.
@@ -455,17 +457,17 @@ unsafe impl Trace for NanBoxedValue {
455457
impl Clone for NanBoxedValue {
456458
#[inline(always)]
457459
fn clone(&self) -> Self {
458-
if let Some(o) = self.as_object() {
459-
Self::object(o.clone())
460-
} else if let Some(b) = self.as_bigint() {
461-
Self::bigint(b.clone())
462-
} else if let Some(s) = self.as_symbol() {
463-
Self::symbol(s.clone())
464-
} else if let Some(s) = self.as_string() {
465-
Self::string(s.clone())
466-
} else {
467-
Self(self.0)
460+
let maybe_ptr = self.0 & bits::POINTER_MASK;
461+
if self.is_object() {
462+
unsafe { Arc::increment_strong_count(maybe_ptr as *const JsObject) };
463+
} else if self.is_bigint() {
464+
unsafe { Arc::increment_strong_count(maybe_ptr as *const JsBigInt) };
465+
} else if self.is_symbol() {
466+
unsafe { Arc::increment_strong_count(maybe_ptr as *const JsSymbol) };
467+
} else if self.is_string() {
468+
unsafe { Arc::increment_strong_count(maybe_ptr as *const JsString) };
468469
}
470+
Self(self.0)
469471
}
470472
}
471473

@@ -518,28 +520,28 @@ impl NanBoxedValue {
518520
#[must_use]
519521
#[inline(always)]
520522
pub(crate) fn bigint(value: JsBigInt) -> Self {
521-
Self::from_inner_unchecked(unsafe { bits::tag_bigint(Box::new(value)) })
523+
Self::from_inner_unchecked(unsafe { bits::tag_bigint(Arc::new(value)) })
522524
}
523525

524526
/// Returns a `InnerValue` from a boxed `[JsObject]`.
525527
#[must_use]
526528
#[inline(always)]
527529
pub(crate) fn object(value: JsObject) -> Self {
528-
Self::from_inner_unchecked(unsafe { bits::tag_object(Box::new(value)) })
530+
Self::from_inner_unchecked(unsafe { bits::tag_object(Arc::new(value)) })
529531
}
530532

531533
/// Returns a `InnerValue` from a boxed `[JsSymbol]`.
532534
#[must_use]
533535
#[inline(always)]
534536
pub(crate) fn symbol(value: JsSymbol) -> Self {
535-
Self::from_inner_unchecked(unsafe { bits::tag_symbol(Box::new(value)) })
537+
Self::from_inner_unchecked(unsafe { bits::tag_symbol(Arc::new(value)) })
536538
}
537539

538540
/// Returns a `InnerValue` from a boxed `[JsString]`.
539541
#[must_use]
540542
#[inline(always)]
541543
pub(crate) fn string(value: JsString) -> Self {
542-
Self::from_inner_unchecked(unsafe { bits::tag_string(Box::new(value)) })
544+
Self::from_inner_unchecked(unsafe { bits::tag_string(Arc::new(value)) })
543545
}
544546

545547
/// Returns true if a value is undefined.
@@ -725,14 +727,14 @@ impl Drop for NanBoxedValue {
725727

726728
// Drop the pointer if it is a pointer.
727729
if self.is_pointer() {
728-
if self.is_string() {
729-
drop(unsafe { Box::from_raw(maybe_ptr as *mut JsString) });
730-
} else if self.is_object() {
731-
drop(unsafe { Box::from_raw(maybe_ptr as *mut JsObject) });
730+
if self.is_object() {
731+
unsafe { Arc::decrement_strong_count(maybe_ptr as *const JsObject) };
732732
} else if self.is_bigint() {
733-
drop(unsafe { Box::from_raw(maybe_ptr as *mut JsBigInt) });
733+
unsafe { Arc::decrement_strong_count(maybe_ptr as *const JsBigInt) };
734734
} else if self.is_symbol() {
735-
drop(unsafe { Box::from_raw(maybe_ptr as *mut JsSymbol) });
735+
unsafe { Arc::decrement_strong_count(maybe_ptr as *const JsSymbol) };
736+
} else if self.is_string() {
737+
unsafe { Arc::decrement_strong_count(maybe_ptr as *const JsString) };
736738
}
737739
}
738740
}

0 commit comments

Comments
 (0)