boa-dev / boa

Boa is an embeddable and experimental Javascript engine written in Rust. Currently, it has support for some of the language.
MIT License
5.01k stars 397 forks source link

NaN boxed JavaScript Value #1373

Open HalidOdat opened 3 years ago

HalidOdat commented 3 years ago

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:

neeldug commented 3 years ago

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.

HalidOdat commented 3 years ago

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>()).

playXE commented 3 years ago

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 :)

HalidOdat commented 3 years ago

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: )

playXE commented 3 years ago

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.

HalidOdat commented 3 years ago

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.

Razican commented 2 years ago

@HalidOdat any news on this?

HalidOdat commented 2 years ago

@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 :)

jedel1043 commented 5 months ago

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