Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1088cc4

Browse files
authored
OptimizeNanBoxedValue related operations (#4506)
Another batch of optimizations.- Optimize NanBoxedValue::clone by inlining the calls to`as_object/string/symbol/bigint`.- Optimize NanBoxedValue::tag_pointer by receiving a `NonNull` pointer,which removes the assertion we have there. Also marks the rarest path(unsupported platform) as a cold function.- Optimize GcHeader::inc_ref_count by marking the possible ref countoverflow as a cold path.### Main resultsRESULT Richards 237RESULT DeltaBlue 243RESULT Crypto 192RESULT RayTrace 524RESULT EarleyBoyer 618RESULT RegExp 87.6RESULT Splay 877RESULT NavierStokes 427SCORE 323### PR resultsRESULT Richards 229RESULT DeltaBlue 238RESULT Crypto 197RESULT RayTrace 532RESULT EarleyBoyer 635RESULT RegExp 91.8RESULT Splay 888RESULT NavierStokes 439SCORE 327
1 parentc9b1f94 commit1088cc4

File tree

3 files changed

+71
-36
lines changed

3 files changed

+71
-36
lines changed

‎core/engine/src/bigint.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use num_traits::{FromPrimitive, One, ToPrimitive, Zero, pow::Pow};
77
use std::{
88
fmt::{self,Display},
99
ops::{Add,BitAnd,BitOr,BitXor,Div,Mul,Neg,Rem,Shl,Shr,Sub},
10+
ptr::NonNull,
1011
rc::Rc,
1112
};
1213

@@ -334,8 +335,9 @@ impl JsBigInt {
334335
#[inline]
335336
#[must_use]
336337
#[allow(unused, reason ="only used in nan-boxed implementation of JsValue")]
337-
pub(crate)fninto_raw(self) ->*constRawBigInt{
338-
Rc::into_raw(self.inner)
338+
pub(crate)fninto_raw(self) ->NonNull<RawBigInt>{
339+
// SAFETY: `Rc::into_raw` must always return a non-null pointer.
340+
unsafe{NonNull::new_unchecked(Rc::into_raw(self.inner).cast_mut())}
339341
}
340342

341343
/// Constructs a `JsBigInt` from a pointer to [`RawBigInt`].

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

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ use boa_string::{JsString, RawJsString};
115115
use core::fmt;
116116
use static_assertions::const_assert;
117117
use std::{
118-
mem::ManuallyDrop,
118+
mem::{self,ManuallyDrop},
119119
ptr::{self,NonNull},
120120
};
121121

@@ -139,6 +139,7 @@ const _NAN_BOX_COMPAT_CHECK: () = const {
139139
///
140140
/// All bit magic is done here.
141141
mod bits{
142+
use std::ptr::NonNull;
142143

143144
/// The mask for the bits that indicate if the value is a NaN-value.
144145
constMASK_NAN:u64 =0x7FF0_0000_0000_0000;
@@ -262,19 +263,29 @@ mod bits {
262263
value&MASK_BOOLEAN_VALUE !=0
263264
}
264265

265-
pub(super)fntag_pointer<T>(ptr:*mutT,type_mask:u64) ->u64{
266-
let value = ptr.addr()asu64;
266+
#[inline(always)]
267+
pub(super)fntag_pointer<T>(ptr:NonNull<T>,type_mask:u64) ->u64{
268+
// Mark this as `cold` since on well-behaved platforms
269+
// this will never be called.
270+
#[cold]
271+
#[inline(never)]
272+
fnunsupported_platform(){
273+
panic!(
274+
"this platform is not compatible with a nan-boxed `JsValueInner`\n\
275+
enable the `jsvalue-enum` feature to use the enum-based `JsValueInner`"
276+
)
277+
}
278+
279+
let value = ptr.addr().get()asu64;
267280
let value_masked:u64 = value&MASK_POINTER_VALUE;
268281

269282
// Assert alignment and location of the pointer.
270-
assert_eq!(
271-
value_masked, value,
272-
"this platform is not compatible with a nan-boxed `JsValueInner`\n\
273-
enable the `jsvalue-enum` feature to use the enum-based `JsValueInner`"
274-
);
275-
276-
// Cannot have a null pointer.
277-
assert_ne!(value_masked,0,"pointer is null");
283+
// TODO: we may want to have nan-boxing be the default only on
284+
// certain platforms, and make it an unsafe operation
285+
// to manually enable the implementation.
286+
if value_masked != value{
287+
unsupported_platform();
288+
}
278289

279290
value_masked | type_mask
280291
}
@@ -342,21 +353,32 @@ unsafe impl Trace for NanBoxedValue {
342353
implCloneforNanBoxedValue{
343354
#[inline(always)]
344355
fnclone(&self) ->Self{
345-
ifletSome(o) =self.as_object(){
346-
Self::object(o.clone())
347-
}elseifletSome(s) =self.as_string(){
348-
Self::string(s.clone())
349-
}elseifletSome(b) =self.as_bigint(){
350-
Self::bigint(b.clone())
351-
}elseifletSome(s) =self.as_symbol(){
352-
Self::symbol(s.clone())
353-
}else{
354-
Self{
355-
#[cfg(target_pointer_width ="32")]
356-
half:self.half,
357-
ptr:self.ptr,
356+
// This way of inlining ensures the compiler
357+
// knows it can convert the match into a
358+
// jump table.
359+
matchself.value()& bits::MASK_KIND{
360+
bits::MASK_OBJECT =>unsafe{
361+
mem::forget((*self.as_object_unchecked()).clone());
362+
},
363+
bits::MASK_STRING =>unsafe{
364+
mem::forget((*self.as_string_unchecked()).clone());
365+
},
366+
bits::MASK_SYMBOL =>unsafe{
367+
mem::forget((*self.as_symbol_unchecked()).clone());
368+
},
369+
bits::MASK_BIGINT =>unsafe{
370+
mem::forget((*self.as_bigint_unchecked()).clone());
371+
},
372+
_ =>{
373+
// Rest of the variants don't need additional handling.
358374
}
359375
}
376+
377+
Self{
378+
#[cfg(target_pointer_width ="32")]
379+
half:self.half,
380+
ptr:self.ptr,
381+
}
360382
}
361383
}
362384

@@ -377,11 +399,11 @@ impl NanBoxedValue {
377399
/// pointer.
378400
///
379401
/// This preserves the provenance of the original pointer.
380-
fnfrom_object_like<T>(ptr:*mutT,addr:u64) ->Self{
402+
fnfrom_object_like<T>(ptr:NonNull<T>,addr:u64) ->Self{
381403
Self{
382404
#[cfg(target_pointer_width ="32")]
383405
half:(addr >>32)asu32,
384-
ptr: ptr.cast::<()>().with_addr(addrasusize),
406+
ptr: ptr.cast::<()>().as_ptr().with_addr(addrasusize),
385407
}
386408
}
387409

@@ -437,7 +459,7 @@ impl NanBoxedValue {
437459
#[must_use]
438460
#[inline(always)]
439461
pub(crate)fnbigint(value:JsBigInt) ->Self{
440-
let ptr = value.into_raw().cast_mut();
462+
let ptr = value.into_raw();
441463
let addr = bits::tag_pointer(ptr, bits::MASK_BIGINT);
442464
Self::from_object_like(ptr, addr)
443465
}
@@ -446,7 +468,7 @@ impl NanBoxedValue {
446468
#[must_use]
447469
#[inline(always)]
448470
pub(crate)fnobject(value:JsObject) ->Self{
449-
let ptr = value.into_raw().as_ptr();
471+
let ptr = value.into_raw();
450472
let addr = bits::tag_pointer(ptr, bits::MASK_OBJECT);
451473
Self::from_object_like(ptr, addr)
452474
}
@@ -455,7 +477,7 @@ impl NanBoxedValue {
455477
#[must_use]
456478
#[inline(always)]
457479
pub(crate)fnsymbol(value:JsSymbol) ->Self{
458-
let ptr = value.into_raw().as_ptr();
480+
let ptr = value.into_raw();
459481
let addr = bits::tag_pointer(ptr, bits::MASK_SYMBOL);
460482
Self::from_object_like(ptr, addr)
461483
}
@@ -464,7 +486,7 @@ impl NanBoxedValue {
464486
#[must_use]
465487
#[inline(always)]
466488
pub(crate)fnstring(value:JsString) ->Self{
467-
let ptr = value.into_raw().as_ptr();
489+
let ptr = value.into_raw();
468490
let addr = bits::tag_pointer(ptr, bits::MASK_STRING);
469491
Self::from_object_like(ptr, addr)
470492
}

‎core/gc/src/internals/gc_header.rs‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,24 @@ impl GcHeader {
5959
self.non_root_count.get()&MARK_MASK !=0
6060
}
6161

62-
#[inline]
6362
pub(crate)fninc_ref_count(&self){
64-
self.ref_count.set(self.ref_count.get() +1);
63+
// Mark this as `cold` since the ref count will
64+
// (almost) never overflow.
65+
#[cold]
66+
#[inline(never)]
67+
fnoverflow_panic(){
68+
panic!("too many references to a gc allocation");
69+
}
70+
71+
let count =self.ref_count.get().wrapping_add(1);
72+
73+
self.ref_count.set(count);
74+
75+
if count ==0{
76+
overflow_panic();
77+
}
6578
}
6679

67-
#[inline]
6880
pub(crate)fndec_ref_count(&self){
6981
self.ref_count.set(self.ref_count.get() -1);
7082
}
@@ -75,7 +87,6 @@ impl GcHeader {
7587
///
7688
/// This only gives valid result if the we have run through the
7789
/// tracing non roots phase.
78-
#[inline]
7990
pub(crate)fnis_rooted(&self) ->bool{
8091
self.non_root_count() <self.ref_count()
8192
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp