boa icon indicating copy to clipboard operation
boa copied to clipboard

NaN boxed JavaScript Value

Open HalidOdat opened this issue 3 years ago • 9 comments

Currently a JavaScript value in Boa is defined as a fat enum. With NaN boxing we can reduce this to 8 bytes having all the variants of a JS value fit in u64/f64. With this we can reduce the memory footprint of Boa, also a JS value will be able to be put into a 64bit register.

Many JS engines use this, like spidermonkey, JavaScriptCore, etc.

For more information: - https://anniecherkaev.com/the-secret-life-of-nan - https://leonardschuetz.ch/blog/nan-boxing/ - https://github.com/mozilla/gecko-dev/blob/master/js/public/Value.h

HalidOdat avatar Jun 29 '21 20:06 HalidOdat

I ended up reading through the links and can see the benefit in doing NaN boxing, however, what is the memory footprint of the fat enum being used currently? Not totally sure how or whether Rust does any sort of padding or whatnot on fat enums.

neeldug avatar Jun 29 '21 23:06 neeldug

I ended up reading through the links and can see the benefit in doing NaN boxing, however, what is the memory footprint of the fat enum being used currently? Not totally sure how or whether Rust does any sort of padding or whatnot on fat enums.

Currently the size of Value is 24 bytes (size_of::<Value>()).

HalidOdat avatar Jun 29 '21 23:06 HalidOdat

If you're looking for impl of NaN boxing in Rust Starlight has two different implementations of them for handling JS values: https://github.com/Starlight-JS/starlight/blob/dev/crates/starlight/src/vm/value.rs :)

playXE avatar Jul 07 '21 06:07 playXE

If you're looking for impl of NaN boxing in Rust Starlight has two different implementations of them for handling JS values: https://github.com/Starlight-JS/starlight/blob/dev/crates/starlight/src/vm/value.rs :)

Awesome! thanks, for the suggestion. I have implemented NaN boxing locally, but the problem is refactoring the existing match value stuff (which we use a lot, this generates a couple of hundred of erros :sweat_smile: )

HalidOdat avatar Jul 07 '21 12:07 HalidOdat

What about having ValueVariant enum which essentially can hold all the values NaN-boxed value can encode and then add JsValue::variant() which returns this ValueVariant. I'm pretty sure Rust and LLVM are able to optimize this.

playXE avatar Jul 07 '21 13:07 playXE

What about having ValueVariant enum which essentially can hold all the values NaN-boxed value can encode and then add JsValue::variant() which returns this ValueVariant. I'm pretty sure Rust and LLVM are able to optimize this.

Yup. thought about this as a possible solution and it's probably the best solution, since refactoring will be a nightmare otherwise.

HalidOdat avatar Jul 07 '21 14:07 HalidOdat

@HalidOdat any news on this?

Razican avatar Jan 31 '22 10:01 Razican

@HalidOdat any news on this?

Sorry for not replying I have been very busy, but plan to start to do more contributions in the future.

I'll start working on this again. had a semi-working implementation of this that needs a rebase (it's pretty old). Hopefully I can get it working by this weekend :)

HalidOdat avatar Feb 03 '22 09:02 HalidOdat

Will try to do some investigation on how to reduce the size of JsObject.

jedel1043 avatar Apr 14 '24 15:04 jedel1043