Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Make JsSymbol thread-safe #2539

Closed
wants to merge 10 commits into from

Conversation

jedel1043
Copy link
Member

@jedel1043 jedel1043 commented Jan 16, 2023

The section about Symbol on the specification says:

The Symbol type is the set of all non-String values that may be used as the key of an Object property (6.1.7).
Each possible Symbol value is unique and immutable.

Our previous implementation of JsSymbol used Rc and a thread local Cell<usize>. However, this meant that two different symbols in two different threads could share the same hash, making symbols not unique.
Also, the GlobalSymbolRegistry is meant to be shared by all realms, including realms that are not in the same thread as the main one; this forces us to replace our current thread local global symbol registry with a thread-safe one that uses DashMap for concurrent access. However, the global symbol registry uses JsStrings as keys and values, which forces us to either use Vec<u16> instead (wasteful and needs to allocate to convert to JsString on each access) or make JsString thread-safe with an atomic counter. For this reason, I implemented the second option.

This PR changes the following:

  • Makes JsSymbol thread-safe by using Arc instead of Rc, and making SYMBOL_HASH_COUNT an AtomicU64.
  • Makes JsString thread-safe by using AtomicUsize instead of Cell<usize> for its ref count. EDIT: Talked with @jasonwilliams and we decided to use Box<[u16]> for the global registry instead, because this won't penalize common usage of JsString, which is used a LOT more than JsSymbol.
  • Makes the GLOBAL_SYMBOL_REGISTRY truly global, using DashMap as our global map that is shared by all threads.
  • Replaces some thread locals with thread-safe alternatives, such as static arrays and static indices.
  • Various improvements to all related code for this.

@jedel1043 jedel1043 added technical debt execution Issues or PRs related to code execution run-benchmark Label used to run banchmarks on PRs labels Jan 16, 2023
@jedel1043 jedel1043 added this to the v0.17.0 milestone Jan 16, 2023
@github-actions
Copy link

Test262 conformance changes

Test result main count PR count difference
Total 94,205 94,205 0
Passed 70,616 70,616 0
Ignored 18,622 18,622 0
Failed 4,967 4,967 0
Panics 0 0 0
Conformance 74.96% 74.96% 0.00%

@codecov
Copy link

codecov bot commented Jan 16, 2023

Codecov Report

Merging #2539 (d5c1d85) into main (20af6a7) will increase coverage by 1.03%.
The diff coverage is 77.37%.

❗ Current head d5c1d85 differs from pull request most recent head 82d54fe. Consider uploading reports for the commit 82d54fe to get more accurate results

@@            Coverage Diff             @@
##             main    #2539      +/-   ##
==========================================
+ Coverage   49.92%   50.96%   +1.03%     
==========================================
  Files         377      374       -3     
  Lines       37557    36805     -752     
==========================================
+ Hits        18751    18756       +5     
+ Misses      18806    18049     -757     
Impacted Files Coverage Δ
boa_engine/src/builtins/function/mod.rs 31.05% <ø> (ø)
boa_engine/src/lib.rs 100.00% <ø> (ø)
boa_engine/src/object/operations.rs 49.00% <ø> (ø)
boa_macros/src/lib.rs 0.00% <0.00%> (ø)
boa_engine/src/builtins/symbol/mod.rs 58.62% <40.00%> (+1.22%) ⬆️
boa_engine/src/builtins/iterable/mod.rs 74.49% <60.00%> (+0.49%) ⬆️
boa_engine/src/builtins/array/mod.rs 74.60% <66.66%> (ø)
boa_engine/src/builtins/typed_array/mod.rs 7.71% <66.66%> (ø)
boa_engine/src/builtins/string/mod.rs 59.66% <72.72%> (ø)
boa_engine/src/symbol.rs 81.60% <85.33%> (-6.63%) ⬇️
... and 48 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@github-actions
Copy link

Benchmark for 1c12fe4

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 545.0±12.19ns 548.5±0.98ns +0.64%
Arithmetic operations (Execution) 549.6±0.71ns 560.5±4.12ns +1.98%
Arithmetic operations (Parser) 7.1±0.04µs 7.2±0.01µs +1.41%
Array access (Compiler) 1441.9±7.44ns 1449.7±4.21ns +0.54%
Array access (Execution) 9.3±0.02µs 9.9±0.02µs +6.45%
Array access (Parser) 14.6±0.02µs 14.7±0.13µs +0.68%
Array creation (Compiler) 2.2±0.01µs 2.3±0.01µs +4.55%
Array creation (Execution) 1301.6±3.33µs 1404.0±2.21µs +7.87%
Array creation (Parser) 17.2±0.03µs 17.2±0.02µs 0.00%
Array pop (Compiler) 4.4±0.01µs 4.3±0.03µs -2.27%
Array pop (Execution) 755.7±1.26µs 825.6±6.77µs +9.25%
Array pop (Parser) 158.3±0.17µs 157.7±0.13µs -0.38%
Boolean Object Access (Compiler) 1238.8±1.84ns 1231.4±1.80ns -0.60%
Boolean Object Access (Execution) 5.4±0.02µs 5.7±0.01µs +5.56%
Boolean Object Access (Parser) 18.3±0.03µs 18.5±0.03µs +1.09%
Clean js (Compiler) 4.8±0.01µs 4.9±0.01µs +2.08%
Clean js (Execution) 732.6±3.76µs 811.8±4.62µs +10.81%
Clean js (Parser) 36.1±0.05µs 36.1±0.02µs 0.00%
Create Realm 286.9±0.26ns 295.8±0.92ns +3.10%
Dynamic Object Property Access (Compiler) 1679.0±3.82ns 1834.8±12.66ns +9.28%
Dynamic Object Property Access (Execution) 5.1±0.01µs 5.4±0.01µs +5.88%
Dynamic Object Property Access (Parser) 13.1±0.01µs 13.3±0.03µs +1.53%
Fibonacci (Compiler) 2.7±0.02µs 2.6±0.01µs -3.70%
Fibonacci (Execution) 1121.9±2.64µs 1148.3±1.86µs +2.35%
Fibonacci (Parser) 20.5±0.02µs 20.6±0.14µs +0.49%
For loop (Compiler) 2.5±0.01µs 2.6±0.00µs +4.00%
For loop (Execution) 15.8±0.02µs 16.2±0.02µs +2.53%
For loop (Parser) 17.6±0.02µs 17.7±0.01µs +0.57%
Mini js (Compiler) 4.2±0.01µs 4.2±0.01µs 0.00%
Mini js (Execution) 686.7±2.39µs 755.4±2.68µs +10.00%
Mini js (Parser) 31.4±0.04µs 31.5±0.03µs +0.32%
Number Object Access (Compiler) 1106.2±1.49ns 1121.1±2.74ns +1.35%
Number Object Access (Execution) 4.1±0.01µs 4.4±0.01µs +7.32%
Number Object Access (Parser) 14.0±0.02µs 13.9±0.02µs -0.71%
Object Creation (Compiler) 1435.6±7.92ns 1501.9±8.64ns +4.62%
Object Creation (Execution) 4.8±0.01µs 5.1±0.02µs +6.25%
Object Creation (Parser) 11.4±0.02µs 11.5±0.02µs +0.88%
RegExp (Compiler) 1689.5±6.44ns 1789.6±14.07ns +5.92%
RegExp (Execution) 13.5±0.04µs 14.0±0.08µs +3.70%
RegExp (Parser) 12.7±0.02µs 12.7±0.02µs 0.00%
RegExp Creation (Compiler) 1507.7±2.82ns 1610.8±8.88ns +6.84%
RegExp Creation (Execution) 9.2±0.02µs 9.5±0.02µs +3.26%
RegExp Creation (Parser) 10.6±0.02µs 10.6±0.02µs 0.00%
RegExp Literal (Compiler) 1690.4±2.49ns 1805.6±17.04ns +6.81%
RegExp Literal (Execution) 13.5±0.04µs 14.0±0.04µs +3.70%
RegExp Literal (Parser) 13.5±0.02µs 13.6±0.02µs +0.74%
RegExp Literal Creation (Compiler) 1505.1±3.16ns 1605.5±8.18ns +6.67%
RegExp Literal Creation (Execution) 9.2±0.05µs 9.5±0.02µs +3.26%
RegExp Literal Creation (Parser) 11.5±0.05µs 11.4±0.02µs -0.87%
Static Object Property Access (Compiler) 1462.7±3.12ns 1551.1±18.84ns +6.04%
Static Object Property Access (Execution) 5.0±0.01µs 5.3±0.01µs +6.00%
Static Object Property Access (Parser) 12.4±0.02µs 12.4±0.01µs 0.00%
String Object Access (Compiler) 1464.9±3.84ns 1556.3±2.56ns +6.24%
String Object Access (Execution) 7.5±0.01µs 8.2±0.03µs +9.33%
String Object Access (Parser) 17.5±0.02µs 17.8±0.03µs +1.71%
String comparison (Compiler) 2.2±0.00µs 2.3±0.00µs +4.55%
String comparison (Execution) 4.4±0.01µs 4.6±0.01µs +4.55%
String comparison (Parser) 13.8±0.02µs 13.9±0.02µs +0.72%
String concatenation (Compiler) 1708.7±3.89ns 1785.4±9.60ns +4.49%
String concatenation (Execution) 4.1±0.01µs 4.4±0.01µs +7.32%
String concatenation (Parser) 9.6±0.01µs 9.7±0.04µs +1.04%
String copy (Compiler) 1368.1±1.90ns 1451.4±7.98ns +6.09%
String copy (Execution) 4.0±0.01µs 4.1±0.01µs +2.50%
String copy (Parser) 7.1±0.01µs 7.2±0.02µs +1.41%
Symbols (Compiler) 1026.6±1.37ns 1043.2±4.76ns +1.62%
Symbols (Execution) 4.0±0.03µs 4.3±0.01µs +7.50%
Symbols (Parser) 5.7±0.01µs 5.7±0.01µs 0.00%

@github-actions
Copy link

Benchmark for 37c9a3b

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 546.4±0.81ns 550.1±1.43ns +0.68%
Arithmetic operations (Execution) 552.0±0.47ns 544.4±0.90ns -1.38%
Arithmetic operations (Parser) 7.3±0.01µs 7.1±0.01µs -2.74%
Array access (Compiler) 1416.3±2.95ns 1432.8±8.84ns +1.17%
Array access (Execution) 9.2±0.01µs 9.7±0.01µs +5.43%
Array access (Parser) 14.7±0.02µs 14.6±0.02µs -0.68%
Array creation (Compiler) 2.2±0.00µs 2.2±0.01µs 0.00%
Array creation (Execution) 1298.2±1.33µs 1400.6±0.88µs +7.89%
Array creation (Parser) 17.3±0.03µs 17.3±0.03µs 0.00%
Array pop (Compiler) 4.4±0.01µs 4.2±0.00µs -4.55%
Array pop (Execution) 748.2±2.15µs 830.5±2.58µs +11.00%
Array pop (Parser) 159.4±1.25µs 158.2±0.16µs -0.75%
Boolean Object Access (Compiler) 1235.0±1.50ns 1220.5±1.48ns -1.17%
Boolean Object Access (Execution) 5.4±0.02µs 5.7±0.01µs +5.56%
Boolean Object Access (Parser) 18.3±0.03µs 18.5±0.05µs +1.09%
Clean js (Compiler) 4.7±0.00µs 4.8±0.02µs +2.13%
Clean js (Execution) 737.5±3.87µs 811.5±3.75µs +10.03%
Clean js (Parser) 36.0±0.05µs 36.2±0.04µs +0.56%
Create Realm 284.0±1.48ns 296.9±0.59ns +4.54%
Dynamic Object Property Access (Compiler) 1663.4±5.99ns 1832.4±16.52ns +10.16%
Dynamic Object Property Access (Execution) 5.0±0.01µs 5.3±0.01µs +6.00%
Dynamic Object Property Access (Parser) 13.2±0.02µs 13.2±0.02µs 0.00%
Fibonacci (Compiler) 2.6±0.01µs 2.7±0.01µs +3.85%
Fibonacci (Execution) 1121.4±5.11µs 1143.8±1.53µs +2.00%
Fibonacci (Parser) 20.6±0.16µs 20.5±0.02µs -0.49%
For loop (Compiler) 2.5±0.01µs 2.6±0.00µs +4.00%
For loop (Execution) 15.7±0.03µs 16.7±0.04µs +6.37%
For loop (Parser) 17.6±0.03µs 17.7±0.04µs +0.57%
Mini js (Compiler) 4.1±0.01µs 4.2±0.01µs +2.44%
Mini js (Execution) 690.5±4.12µs 756.3±3.95µs +9.53%
Mini js (Parser) 31.3±0.07µs 31.5±0.08µs +0.64%
Number Object Access (Compiler) 1111.7±2.70ns 1103.6±1.48ns -0.73%
Number Object Access (Execution) 4.1±0.01µs 4.4±0.02µs +7.32%
Number Object Access (Parser) 13.9±0.02µs 13.9±0.03µs 0.00%
Object Creation (Compiler) 1441.7±14.24ns 1495.8±4.08ns +3.75%
Object Creation (Execution) 4.8±0.01µs 5.0±0.01µs +4.17%
Object Creation (Parser) 11.5±0.02µs 11.5±0.01µs 0.00%
RegExp (Compiler) 1689.1±2.52ns 1789.6±9.31ns +5.95%
RegExp (Execution) 13.5±0.03µs 14.0±0.04µs +3.70%
RegExp (Parser) 12.7±0.02µs 12.7±0.02µs 0.00%
RegExp Creation (Compiler) 1516.3±2.93ns 1596.8±7.22ns +5.31%
RegExp Creation (Execution) 9.4±0.04µs 9.4±0.02µs 0.00%
RegExp Creation (Parser) 10.7±0.02µs 10.6±0.02µs -0.93%
RegExp Literal (Compiler) 1716.7±3.64ns 1808.6±6.53ns +5.35%
RegExp Literal (Execution) 13.6±0.04µs 14.0±0.03µs +2.94%
RegExp Literal (Parser) 13.7±0.02µs 13.5±0.03µs -1.46%
RegExp Literal Creation (Compiler) 1500.2±2.91ns 1616.7±5.79ns +7.77%
RegExp Literal Creation (Execution) 9.4±0.04µs 9.4±0.03µs 0.00%
RegExp Literal Creation (Parser) 11.5±0.03µs 11.4±0.02µs -0.87%
Static Object Property Access (Compiler) 1489.6±14.18ns 1564.1±8.82ns +5.00%
Static Object Property Access (Execution) 5.0±0.01µs 5.3±0.01µs +6.00%
Static Object Property Access (Parser) 12.4±0.02µs 12.3±0.01µs -0.81%
String Object Access (Compiler) 1473.5±5.74ns 1550.5±2.68ns +5.23%
String Object Access (Execution) 7.5±0.04µs 8.2±0.04µs +9.33%
String Object Access (Parser) 17.5±0.02µs 17.7±0.08µs +1.14%
String comparison (Compiler) 2.2±0.00µs 2.3±0.01µs +4.55%
String comparison (Execution) 4.4±0.01µs 4.6±0.01µs +4.55%
String comparison (Parser) 13.8±0.03µs 13.9±0.02µs +0.72%
String concatenation (Compiler) 1699.4±3.45ns 1765.6±9.16ns +3.90%
String concatenation (Execution) 4.1±0.02µs 4.3±0.01µs +4.88%
String concatenation (Parser) 9.5±0.01µs 9.7±0.01µs +2.11%
String copy (Compiler) 1383.8±3.49ns 1392.6±3.88ns +0.64%
String copy (Execution) 3.9±0.01µs 4.1±0.01µs +5.13%
String copy (Parser) 7.2±0.02µs 7.2±0.02µs 0.00%
Symbols (Compiler) 1023.3±1.58ns 1031.9±2.69ns +0.84%
Symbols (Execution) 4.0±0.01µs 4.2±0.01µs +5.00%
Symbols (Parser) 5.8±0.01µs 5.7±0.01µs -1.72%

Some(Self {
// SAFETY: Pointers returned by `Arc::into_raw` must be non-null.
repr: unsafe { Tagged::from_ptr(Arc::into_raw(arc).cast_mut()) },
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks interesting but not sure i understand it.
Could you explain why the JsSymbol holds a Tagged pointer over the Arc? Doesn't the Arc return a pointer anyway?

Copy link
Member Author

@jedel1043 jedel1043 Jan 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing about this is that on the previous implementation, a JsSymbol was 8 bytes in size, making it the same size as an usize. However, on a previous implementation of the static well-known symbols, I tried to encode statics like so:

enum JsSymbol {
    WellKnown(usize),
    Runtime(Arc<Inner>)
}

This doubles the size of JsSymbol to 16 bytes! So, to preserve the original size of 8 bytes, I had to encode the tag itself into the pointer. To do that, I had mainly two options:

  • Store an Arc<Inner> and transmute the tags into Arc<Inner> to store them.
  • Store the NonNull<Inner> returned by Arc::into_raw, and trivially convert usize into NonNull<Inner> using ptr::invalid.

The first option seems tempting, but is EXTREMELY hard to maintain; we need to check on every rustc update that the inner representation of Arc hasn't changed. That's not ideal. And so, I had to go with the second option, which is a bit harder to reason about but just uses APIs provided by Arc itself, so we don't have to worry about breaking the implementation between rustc version bumps.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a JsSymbol was 8 bits in size, making it the same size as an usize

Isn't a usize 32bits on a 32bit machine, 64bits on a 64bit machine? i.e the pointer size? I've not known of a usize be only 1 byte. https://doc.rust-lang.org/std/primitive.usize.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry! I mistyped. Edited my comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I assume pointers of 64-bit in size in the comment, but also applies to 32-bit pointers because the tag itself is usize.

@github-actions
Copy link

Benchmark for 62051de

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 523.9±0.52ns 493.4±0.66ns -5.82%
Arithmetic operations (Execution) 413.3±0.25ns 409.8±0.36ns -0.85%
Arithmetic operations (Parser) 7.7±0.45µs 7.5±0.04µs -2.60%
Array access (Compiler) 1505.9±2.10ns 1496.4±1.95ns -0.63%
Array access (Execution) 9.8±0.02µs 10.5±0.02µs +7.14%
Array access (Parser) 16.1±0.04µs 16.1±0.05µs 0.00%
Array creation (Compiler) 2.4±0.01µs 2.4±0.00µs 0.00%
Array creation (Execution) 1425.3±2.53µs 1518.8±3.24µs +6.56%
Array creation (Parser) 19.1±0.04µs 19.0±0.05µs -0.52%
Array pop (Compiler) 4.3±0.01µs 4.1±0.01µs -4.65%
Array pop (Execution) 844.2±0.87µs 897.9±2.05µs +6.36%
Array pop (Parser) 170.7±0.17µs 170.7±0.15µs 0.00%
Boolean Object Access (Compiler) 1251.2±8.43ns 1244.7±1.24ns -0.52%
Boolean Object Access (Execution) 5.7±0.11µs 6.2±0.05µs +8.77%
Boolean Object Access (Parser) 19.8±0.07µs 19.8±0.08µs 0.00%
Clean js (Compiler) 5.2±0.06µs 5.2±0.02µs 0.00%
Clean js (Execution) 799.2±4.16µs 859.0±3.90µs +7.48%
Clean js (Parser) 39.3±0.09µs 39.7±0.09µs +1.02%
Create Realm 293.1±0.34ns 291.8±0.66ns -0.44%
Dynamic Object Property Access (Compiler) 1815.7±6.47ns 1891.6±8.42ns +4.18%
Dynamic Object Property Access (Execution) 5.4±0.01µs 5.7±0.02µs +5.56%
Dynamic Object Property Access (Parser) 14.5±0.03µs 14.5±0.05µs 0.00%
Fibonacci (Compiler) 2.8±0.01µs 2.8±0.00µs 0.00%
Fibonacci (Execution) 1202.6±2.27µs 1235.1±2.38µs +2.70%
Fibonacci (Parser) 22.5±0.07µs 22.4±0.09µs -0.44%
For loop (Compiler) 2.7±0.01µs 2.8±0.01µs +3.70%
For loop (Execution) 16.1±0.02µs 16.6±0.03µs +3.11%
For loop (Parser) 19.5±0.04µs 19.3±0.03µs -1.03%
Mini js (Compiler) 4.5±0.01µs 4.5±0.01µs 0.00%
Mini js (Execution) 748.5±4.64µs 802.8±3.51µs +7.25%
Mini js (Parser) 34.6±0.06µs 34.2±0.09µs -1.16%
Number Object Access (Compiler) 1120.2±6.36ns 1138.4±6.98ns +1.62%
Number Object Access (Execution) 4.4±0.12µs 4.7±0.02µs +6.82%
Number Object Access (Parser) 15.5±0.03µs 15.4±0.05µs -0.65%
Object Creation (Compiler) 1531.9±14.23ns 1564.6±2.65ns +2.13%
Object Creation (Execution) 5.1±0.02µs 5.4±0.01µs +5.88%
Object Creation (Parser) 12.9±0.06µs 12.7±0.06µs -1.55%
RegExp (Compiler) 1792.6±4.93ns 1862.6±4.09ns +3.90%
RegExp (Execution) 14.3±0.03µs 15.0±0.02µs +4.90%
RegExp (Parser) 13.8±0.04µs 14.0±0.05µs +1.45%
RegExp Creation (Compiler) 1587.9±4.61ns 1659.7±3.51ns +4.52%
RegExp Creation (Execution) 9.8±0.02µs 10.2±0.04µs +4.08%
RegExp Creation (Parser) 11.6±0.03µs 11.6±0.05µs 0.00%
RegExp Literal (Compiler) 1791.9±5.02ns 1861.1±6.45ns +3.86%
RegExp Literal (Execution) 14.3±0.04µs 15.0±0.04µs +4.90%
RegExp Literal (Parser) 14.8±0.03µs 14.8±0.03µs 0.00%
RegExp Literal Creation (Compiler) 1589.7±4.66ns 1656.9±3.60ns +4.23%
RegExp Literal Creation (Execution) 9.8±0.02µs 10.1±0.04µs +3.06%
RegExp Literal Creation (Parser) 12.4±0.02µs 12.3±0.03µs -0.81%
Static Object Property Access (Compiler) 1564.1±3.95ns 1586.2±5.10ns +1.41%
Static Object Property Access (Execution) 5.3±0.01µs 5.6±0.02µs +5.66%
Static Object Property Access (Parser) 13.8±0.02µs 13.8±0.04µs 0.00%
String Object Access (Compiler) 1520.4±6.66ns 1593.6±3.04ns +4.81%
String Object Access (Execution) 8.1±0.12µs 9.0±0.05µs +11.11%
String Object Access (Parser) 19.5±0.06µs 19.5±0.05µs 0.00%
String comparison (Compiler) 2.4±0.01µs 2.5±0.00µs +4.17%
String comparison (Execution) 4.5±0.01µs 4.9±0.02µs +8.89%
String comparison (Parser) 15.3±0.02µs 15.3±0.03µs 0.00%
String concatenation (Compiler) 1811.9±2.37ns 1911.1±3.34ns +5.47%
String concatenation (Execution) 4.3±0.02µs 4.6±0.01µs +6.98%
String concatenation (Parser) 10.5±0.01µs 10.6±0.04µs +0.95%
String copy (Compiler) 1450.5±4.68ns 1494.3±5.66ns +3.02%
String copy (Execution) 4.2±0.02µs 4.4±0.01µs +4.76%
String copy (Parser) 8.0±0.01µs 7.9±0.02µs -1.25%
Symbols (Compiler) 1085.4±20.18ns 1079.8±2.55ns -0.52%
Symbols (Execution) 4.2±0.01µs 4.5±0.01µs +7.14%
Symbols (Parser) 6.4±0.03µs 6.3±0.02µs -1.56%

@github-actions
Copy link

Benchmark for 6a33665

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 555.0±0.75ns 572.0±1.84ns +3.06%
Arithmetic operations (Execution) 543.4±0.59ns 547.1±0.70ns +0.68%
Arithmetic operations (Parser) 7.2±0.01µs 7.2±0.01µs 0.00%
Array access (Compiler) 1423.6±1.26ns 1436.0±3.67ns +0.87%
Array access (Execution) 9.6±0.03µs 9.8±0.03µs +2.08%
Array access (Parser) 14.6±0.02µs 14.6±0.03µs 0.00%
Array creation (Compiler) 2.2±0.01µs 2.3±0.00µs +4.55%
Array creation (Execution) 1335.5±1.72µs 1356.5±4.16µs +1.57%
Array creation (Parser) 17.4±0.03µs 17.3±0.10µs -0.57%
Array pop (Compiler) 4.3±0.01µs 4.2±0.07µs -2.33%
Array pop (Execution) 780.1±1.45µs 795.3±2.18µs +1.95%
Array pop (Parser) 157.8±0.18µs 157.9±0.13µs +0.06%
Boolean Object Access (Compiler) 1227.2±4.61ns 1219.0±3.56ns -0.67%
Boolean Object Access (Execution) 5.2±0.03µs 5.6±0.03µs +7.69%
Boolean Object Access (Parser) 18.3±0.02µs 18.4±0.02µs +0.55%
Clean js (Compiler) 4.8±0.01µs 4.8±0.02µs 0.00%
Clean js (Execution) 745.3±4.28µs 786.3±16.08µs +5.50%
Clean js (Parser) 36.2±0.03µs 35.8±0.08µs -1.10%
Create Realm 298.5±0.32ns 290.8±0.28ns -2.58%
Dynamic Object Property Access (Compiler) 1683.9±2.42ns 1786.6±5.08ns +6.10%
Dynamic Object Property Access (Execution) 5.1±0.01µs 5.3±0.01µs +3.92%
Dynamic Object Property Access (Parser) 13.2±0.02µs 13.2±0.03µs 0.00%
Fibonacci (Compiler) 2.7±0.00µs 2.6±0.00µs -3.70%
Fibonacci (Execution) 1110.6±2.44µs 1117.7±3.20µs +0.64%
Fibonacci (Parser) 20.4±0.02µs 20.4±0.04µs 0.00%
For loop (Compiler) 2.5±0.00µs 2.6±0.00µs +4.00%
For loop (Execution) 15.7±0.02µs 16.1±0.03µs +2.55%
For loop (Parser) 17.7±0.02µs 17.8±0.03µs +0.56%
Mini js (Compiler) 4.1±0.02µs 4.2±0.07µs +2.44%
Mini js (Execution) 696.6±2.42µs 738.8±3.50µs +6.06%
Mini js (Parser) 31.4±0.03µs 31.2±0.04µs -0.64%
Number Object Access (Compiler) 1108.8±2.44ns 1099.5±1.49ns -0.84%
Number Object Access (Execution) 3.9±0.02µs 4.3±0.01µs +10.26%
Number Object Access (Parser) 13.8±0.01µs 13.8±0.03µs 0.00%
Object Creation (Compiler) 1431.0±1.99ns 1489.6±1.41ns +4.10%
Object Creation (Execution) 4.8±0.01µs 5.0±0.00µs +4.17%
Object Creation (Parser) 11.5±0.02µs 11.5±0.02µs 0.00%
RegExp (Compiler) 1670.1±3.60ns 1755.9±3.95ns +5.14%
RegExp (Execution) 13.8±0.05µs 14.2±0.03µs +2.90%
RegExp (Parser) 12.6±0.02µs 12.6±0.01µs 0.00%
RegExp Creation (Compiler) 1492.3±2.84ns 1573.3±3.30ns +5.43%
RegExp Creation (Execution) 9.5±0.04µs 9.7±0.02µs +2.11%
RegExp Creation (Parser) 10.6±0.02µs 10.4±0.03µs -1.89%
RegExp Literal (Compiler) 1657.6±3.63ns 1758.9±4.36ns +6.11%
RegExp Literal (Execution) 13.7±0.04µs 14.2±0.04µs +3.65%
RegExp Literal (Parser) 13.8±0.06µs 13.7±0.03µs -0.72%
RegExp Literal Creation (Compiler) 1495.3±2.45ns 1574.3±4.18ns +5.28%
RegExp Literal Creation (Execution) 9.5±0.02µs 9.7±0.02µs +2.11%
RegExp Literal Creation (Parser) 11.6±0.02µs 11.5±0.02µs -0.86%
Static Object Property Access (Compiler) 1472.7±2.11ns 1510.8±2.68ns +2.59%
Static Object Property Access (Execution) 5.0±0.01µs 5.3±0.01µs +6.00%
Static Object Property Access (Parser) 12.4±0.02µs 12.5±0.02µs +0.81%
String Object Access (Compiler) 1457.2±1.92ns 1546.2±2.07ns +6.11%
String Object Access (Execution) 7.3±0.02µs 8.0±0.02µs +9.59%
String Object Access (Parser) 17.6±0.02µs 17.5±0.03µs -0.57%
String comparison (Compiler) 2.3±0.00µs 2.3±0.01µs 0.00%
String comparison (Execution) 4.5±0.01µs 4.6±0.01µs +2.22%
String comparison (Parser) 13.8±0.06µs 13.8±0.02µs 0.00%
String concatenation (Compiler) 1721.4±4.47ns 1807.7±4.88ns +5.01%
String concatenation (Execution) 4.2±0.03µs 4.3±0.02µs +2.38%
String concatenation (Parser) 9.6±0.02µs 9.5±0.01µs -1.04%
String copy (Compiler) 1395.1±2.01ns 1421.6±3.23ns +1.90%
String copy (Execution) 4.0±0.01µs 4.1±0.01µs +2.50%
String copy (Parser) 7.2±0.01µs 7.1±0.02µs -1.39%
Symbols (Compiler) 1052.2±10.43ns 1040.3±1.14ns -1.13%
Symbols (Execution) 4.0±0.01µs 4.2±0.01µs +5.00%
Symbols (Parser) 5.7±0.01µs 5.6±0.01µs -1.75%

@jedel1043 jedel1043 changed the title Make JsSymbol and JsString thread-safe Make JsSymbol thread-safe Jan 17, 2023
Copy link
Member

@jasonwilliams jasonwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, we will take a performance hit switching from Rc to Arc, thats unavoidable, but probbaly explains the +5% on the Symbols (Execution) benchmark.

As we discussed we probably don't want to take that hit on JsStrings (using atomics) so maybe we can move the penalty into the globalSymbolRegistry.

@github-actions
Copy link

Benchmark for c3b6ecf

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 536.4±0.87ns 545.6±0.75ns +1.72%
Arithmetic operations (Execution) 543.4±0.63ns 516.5±0.51ns -4.95%
Arithmetic operations (Parser) 7.2±0.01µs 7.2±0.01µs 0.00%
Array access (Compiler) 1435.3±3.28ns 1454.3±3.49ns +1.32%
Array access (Execution) 9.2±0.01µs 9.8±0.02µs +6.52%
Array access (Parser) 14.5±0.02µs 14.9±0.02µs +2.76%
Array creation (Compiler) 2.2±0.01µs 2.3±0.01µs +4.55%
Array creation (Execution) 1301.9±1.69µs 1405.6±54.19µs +7.97%
Array creation (Parser) 17.1±0.06µs 17.6±0.09µs +2.92%
Array pop (Compiler) 4.2±0.01µs 4.2±0.02µs 0.00%
Array pop (Execution) 760.1±3.63µs 824.9±0.73µs +8.53%
Array pop (Parser) 158.4±0.14µs 161.5±0.19µs +1.96%
Boolean Object Access (Compiler) 1238.0±3.37ns 1233.0±1.82ns -0.40%
Boolean Object Access (Execution) 5.2±0.01µs 5.5±0.01µs +5.77%
Boolean Object Access (Parser) 18.4±0.05µs 19.0±0.03µs +3.26%
Clean js (Compiler) 4.9±0.01µs 4.8±0.02µs -2.04%
Clean js (Execution) 743.1±3.86µs 801.6±3.35µs +7.87%
Clean js (Parser) 36.0±0.09µs 36.8±0.08µs +2.22%
Create Realm 291.9±1.53ns 287.6±0.30ns -1.47%
Dynamic Object Property Access (Compiler) 1683.8±5.21ns 1739.6±6.92ns +3.31%
Dynamic Object Property Access (Execution) 5.1±0.04µs 5.4±0.02µs +5.88%
Dynamic Object Property Access (Parser) 13.2±0.05µs 13.6±0.02µs +3.03%
Fibonacci (Compiler) 2.6±0.01µs 2.6±0.01µs 0.00%
Fibonacci (Execution) 1120.9±5.58µs 1128.1±1.97µs +0.64%
Fibonacci (Parser) 20.3±0.03µs 20.6±0.03µs +1.48%
For loop (Compiler) 2.5±0.00µs 2.6±0.00µs +4.00%
For loop (Execution) 15.6±0.03µs 16.5±0.03µs +5.77%
For loop (Parser) 17.3±0.02µs 18.1±0.02µs +4.62%
Mini js (Compiler) 4.2±0.01µs 4.2±0.01µs 0.00%
Mini js (Execution) 695.2±2.95µs 764.8±3.52µs +10.01%
Mini js (Parser) 31.5±0.03µs 32.1±0.18µs +1.90%
Number Object Access (Compiler) 1107.9±1.68ns 1114.6±2.38ns +0.60%
Number Object Access (Execution) 4.0±0.02µs 4.3±0.02µs +7.50%
Number Object Access (Parser) 13.9±0.02µs 14.3±0.02µs +2.88%
Object Creation (Compiler) 1439.3±4.62ns 1473.8±4.08ns +2.40%
Object Creation (Execution) 4.9±0.01µs 5.1±0.02µs +4.08%
Object Creation (Parser) 11.5±0.02µs 11.7±0.01µs +1.74%
RegExp (Compiler) 1665.7±2.41ns 1734.6±3.50ns +4.14%
RegExp (Execution) 13.6±0.04µs 14.0±0.04µs +2.94%
RegExp (Parser) 12.6±0.02µs 13.0±0.05µs +3.17%
RegExp Creation (Compiler) 1507.0±2.56ns 1552.4±3.26ns +3.01%
RegExp Creation (Execution) 9.4±0.02µs 9.4±0.01µs 0.00%
RegExp Creation (Parser) 10.5±0.02µs 10.9±0.01µs +3.81%
RegExp Literal (Compiler) 1664.4±6.41ns 1743.2±3.68ns +4.73%
RegExp Literal (Execution) 13.6±0.03µs 14.0±0.04µs +2.94%
RegExp Literal (Parser) 13.5±0.02µs 13.7±0.03µs +1.48%
RegExp Literal Creation (Compiler) 1507.1±2.95ns 1553.6±4.09ns +3.09%
RegExp Literal Creation (Execution) 9.3±0.03µs 9.4±0.02µs +1.08%
RegExp Literal Creation (Parser) 11.3±0.02µs 11.6±0.01µs +2.65%
Static Object Property Access (Compiler) 1456.8±2.04ns 1508.0±1.84ns +3.51%
Static Object Property Access (Execution) 5.0±0.01µs 5.2±0.01µs +4.00%
Static Object Property Access (Parser) 12.3±0.01µs 12.7±0.02µs +3.25%
String Object Access (Compiler) 1526.0±16.21ns 1521.4±6.44ns -0.30%
String Object Access (Execution) 7.4±0.02µs 8.1±0.01µs +9.46%
String Object Access (Parser) 17.6±0.08µs 18.3±0.02µs +3.98%
String comparison (Compiler) 2.3±0.01µs 2.3±0.00µs 0.00%
String comparison (Execution) 4.4±0.01µs 4.6±0.01µs +4.55%
String comparison (Parser) 13.8±0.04µs 14.1±0.01µs +2.17%
String concatenation (Compiler) 1729.4±2.85ns 1775.0±4.05ns +2.64%
String concatenation (Execution) 4.1±0.01µs 4.4±0.01µs +7.32%
String concatenation (Parser) 9.6±0.02µs 9.8±0.01µs +2.08%
String copy (Compiler) 1398.9±4.10ns 1403.9±2.28ns +0.36%
String copy (Execution) 4.0±0.01µs 4.1±0.01µs +2.50%
String copy (Parser) 7.1±0.01µs 7.3±0.02µs +2.82%
Symbols (Compiler) 1032.2±1.30ns 1035.8±5.34ns +0.35%
Symbols (Execution) 4.0±0.01µs 4.2±0.01µs +5.00%
Symbols (Parser) 5.6±0.01µs 5.8±0.01µs +3.57%

@raskad
Copy link
Member

raskad commented Jan 18, 2023

When I run miri (cargo +nightly miri test -p boa_engine string::tests -- --skip builtins --skip parser) on this branch I get some UB:

test string::tests::as_str ... error: Undefined Behavior: attempting a write access using <1734381> at alloc768919[0x10], but that tag does not exist in the borrow stack for this location
   --> boa_engine/src/string/mod.rs:544:13
    |
544 |             ptr::copy_nonoverlapping(string.as_ptr(), data, count);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |             |
    |             attempting a write access using <1734381> at alloc768919[0x10], but that tag does not exist in the borrow stack for this location
    |             this error occurs as part of an access at alloc768919[0x10..0x1a]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <1734381> would have been created here, but this is a zero-size retag ([0x10..0x10]) so the tag in question does not exist anywhere
...

@jedel1043 do you get the same result?

@jedel1043
Copy link
Member Author

Hm yeah, maybe integrating Tagged messed up with the stacked borrows of the code. Let me see what I can do.

@jedel1043
Copy link
Member Author

@raskad I did change some code while integrating Tagged! This should be solved now.

@github-actions
Copy link

Benchmark for 95cb217

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 652.0±5.21ns 634.8±2.20ns -2.64%
Arithmetic operations (Execution) 651.8±1.44ns 654.1±3.18ns +0.35%
Arithmetic operations (Parser) 8.0±0.02µs 8.2±0.02µs +2.50%
Array access (Compiler) 1700.2±8.43ns 1720.3±12.86ns +1.18%
Array access (Execution) 11.0±0.05µs 11.7±0.03µs +6.36%
Array access (Parser) 16.1±0.11µs 16.5±0.04µs +2.48%
Array creation (Compiler) 2.6±0.01µs 2.6±0.01µs 0.00%
Array creation (Execution) 1523.4±5.44µs 1653.2±2.42µs +8.52%
Array creation (Parser) 19.2±0.04µs 19.7±0.11µs +2.60%
Array pop (Compiler) 5.0±0.02µs 4.9±0.01µs -2.00%
Array pop (Execution) 900.4±2.37µs 978.6±8.58µs +8.69%
Array pop (Parser) 179.7±0.86µs 182.8±0.72µs +1.73%
Boolean Object Access (Compiler) 1291.6±14.69ns 1245.5±3.11ns -3.57%
Boolean Object Access (Execution) 6.4±0.01µs 6.6±0.02µs +3.12%
Boolean Object Access (Parser) 20.7±0.10µs 21.2±0.07µs +2.42%
Clean js (Compiler) 5.5±0.01µs 5.4±0.01µs -1.82%
Clean js (Execution) 869.6±4.82µs 944.2±8.31µs +8.58%
Clean js (Parser) 40.3±0.06µs 41.1±0.13µs +1.99%
Create Realm 366.5±2.02ns 348.2±6.23ns -4.99%
Dynamic Object Property Access (Compiler) 1963.4±7.92ns 2.0±0.01µs +1.86%
Dynamic Object Property Access (Execution) 6.2±0.04µs 6.4±0.02µs +3.23%
Dynamic Object Property Access (Parser) 14.6±0.07µs 15.1±0.03µs +3.42%
Fibonacci (Compiler) 3.1±0.01µs 3.0±0.01µs -3.23%
Fibonacci (Execution) 1322.7±7.55µs 1342.6±8.34µs +1.50%
Fibonacci (Parser) 22.8±0.03µs 23.3±0.05µs +2.19%
For loop (Compiler) 2.9±0.01µs 2.9±0.03µs 0.00%
For loop (Execution) 18.8±0.08µs 19.1±0.24µs +1.60%
For loop (Parser) 19.6±0.05µs 20.5±0.04µs +4.59%
Mini js (Compiler) 4.8±0.02µs 4.8±0.01µs 0.00%
Mini js (Execution) 816.4±6.36µs 888.9±7.48µs +8.88%
Mini js (Parser) 35.5±0.08µs 35.5±0.15µs 0.00%
Number Object Access (Compiler) 1165.6±5.97ns 1164.1±2.51ns -0.13%
Number Object Access (Execution) 4.8±0.02µs 5.1±0.03µs +6.25%
Number Object Access (Parser) 15.6±0.04µs 16.1±0.04µs +3.21%
Object Creation (Compiler) 1715.4±13.48ns 1739.0±6.39ns +1.38%
Object Creation (Execution) 5.8±0.02µs 6.1±0.02µs +5.17%
Object Creation (Parser) 12.7±0.03µs 13.1±0.06µs +3.15%
RegExp (Compiler) 1968.9±9.71ns 2.0±0.01µs +1.58%
RegExp (Execution) 16.0±0.06µs 16.5±0.03µs +3.13%
RegExp (Parser) 13.9±0.05µs 14.4±0.07µs +3.60%
RegExp Creation (Compiler) 1797.3±7.98ns 1812.2±8.59ns +0.83%
RegExp Creation (Execution) 11.0±0.06µs 11.2±0.04µs +1.82%
RegExp Creation (Parser) 11.7±0.06µs 12.0±0.03µs +2.56%
RegExp Literal (Compiler) 1988.2±9.37ns 2.0±0.01µs +0.59%
RegExp Literal (Execution) 16.0±0.08µs 16.6±0.05µs +3.75%
RegExp Literal (Parser) 15.2±0.18µs 15.4±0.05µs +1.32%
RegExp Literal Creation (Compiler) 1773.7±15.25ns 1809.4±9.75ns +2.01%
RegExp Literal Creation (Execution) 11.0±0.06µs 11.2±0.05µs +1.82%
RegExp Literal Creation (Parser) 13.0±0.07µs 13.0±0.02µs 0.00%
Static Object Property Access (Compiler) 1758.4±10.00ns 1752.1±5.18ns -0.36%
Static Object Property Access (Execution) 6.0±0.02µs 6.3±0.03µs +5.00%
Static Object Property Access (Parser) 13.7±0.08µs 13.9±0.07µs +1.46%
String Object Access (Compiler) 1611.9±4.08ns 1684.2±8.04ns +4.49%
String Object Access (Execution) 9.0±0.03µs 9.7±0.04µs +7.78%
String Object Access (Parser) 19.9±0.04µs 20.5±0.29µs +3.02%
String comparison (Compiler) 2.7±0.01µs 2.7±0.01µs 0.00%
String comparison (Execution) 5.3±0.01µs 5.5±0.02µs +3.77%
String comparison (Parser) 15.5±0.21µs 15.8±0.04µs +1.94%
String concatenation (Compiler) 2.1±0.01µs 2.1±0.01µs 0.00%
String concatenation (Execution) 4.9±0.02µs 5.2±0.02µs +6.12%
String concatenation (Parser) 10.6±0.04µs 10.9±0.03µs +2.83%
String copy (Compiler) 1673.6±7.23ns 1654.8±5.46ns -1.12%
String copy (Execution) 4.7±0.02µs 4.9±0.05µs +4.26%
String copy (Parser) 7.8±0.02µs 8.1±0.03µs +3.85%
Symbols (Compiler) 1216.8±2.90ns 1213.6±4.41ns -0.26%
Symbols (Execution) 4.8±0.01µs 5.1±0.02µs +6.25%
Symbols (Parser) 6.2±0.03µs 6.3±0.01µs +1.61%

@github-actions
Copy link

Benchmark for edb2e74

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 517.3±0.70ns 500.1±0.53ns -3.32%
Arithmetic operations (Execution) 410.6±0.28ns 416.6±0.22ns +1.46%
Arithmetic operations (Parser) 7.8±0.04µs 7.8±0.02µs 0.00%
Array access (Compiler) 1506.4±2.77ns 1543.1±23.27ns +2.44%
Array access (Execution) 9.9±0.01µs 10.4±0.03µs +5.05%
Array access (Parser) 15.9±0.04µs 16.2±0.03µs +1.89%
Array creation (Compiler) 2.4±0.00µs 2.4±0.02µs 0.00%
Array creation (Execution) 1454.3±2.98µs 1500.0±1.91µs +3.14%
Array creation (Parser) 18.9±0.08µs 19.3±0.05µs +2.12%
Array pop (Compiler) 4.1±0.01µs 4.1±0.01µs 0.00%
Array pop (Execution) 847.4±5.33µs 892.5±2.53µs +5.32%
Array pop (Parser) 168.9±0.10µs 171.8±3.34µs +1.72%
Boolean Object Access (Compiler) 1269.2±2.93ns 1242.9±2.53ns -2.07%
Boolean Object Access (Execution) 5.8±0.01µs 6.0±0.02µs +3.45%
Boolean Object Access (Parser) 19.7±0.06µs 20.4±0.12µs +3.55%
Clean js (Compiler) 5.2±0.02µs 5.1±0.01µs -1.92%
Clean js (Execution) 807.1±3.19µs 860.1±3.23µs +6.57%
Clean js (Parser) 39.2±0.08µs 39.9±0.06µs +1.79%
Create Realm 291.6±1.73ns 294.2±4.42ns +0.89%
Dynamic Object Property Access (Compiler) 1793.7±4.53ns 1844.5±3.81ns +2.83%
Dynamic Object Property Access (Execution) 5.5±0.01µs 5.7±0.01µs +3.64%
Dynamic Object Property Access (Parser) 14.3±0.05µs 14.9±0.50µs +4.20%
Fibonacci (Compiler) 2.8±0.01µs 2.8±0.01µs 0.00%
Fibonacci (Execution) 1220.6±6.31µs 1263.5±1.73µs +3.51%
Fibonacci (Parser) 22.2±0.04µs 22.5±0.04µs +1.35%
For loop (Compiler) 2.7±0.02µs 2.8±0.02µs +3.70%
For loop (Execution) 16.2±0.04µs 17.1±0.05µs +5.56%
For loop (Parser) 19.2±0.07µs 19.7±0.03µs +2.60%
Mini js (Compiler) 4.4±0.01µs 4.4±0.01µs 0.00%
Mini js (Execution) 750.5±4.56µs 810.0±4.31µs +7.93%
Mini js (Parser) 34.1±0.07µs 34.4±0.06µs +0.88%
Number Object Access (Compiler) 1122.0±1.97ns 1121.5±2.95ns -0.04%
Number Object Access (Execution) 4.5±0.06µs 4.6±0.01µs +2.22%
Number Object Access (Parser) 15.2±0.08µs 15.6±0.10µs +2.63%
Object Creation (Compiler) 1554.1±3.04ns 1530.8±2.62ns -1.50%
Object Creation (Execution) 5.1±0.02µs 5.5±0.01µs +7.84%
Object Creation (Parser) 12.6±0.02µs 12.8±0.02µs +1.59%
RegExp (Compiler) 1790.2±4.46ns 1881.6±6.92ns +5.11%
RegExp (Execution) 14.5±0.18µs 15.1±0.04µs +4.14%
RegExp (Parser) 13.7±0.03µs 14.2±0.07µs +3.65%
RegExp Creation (Compiler) 1615.3±5.19ns 1642.5±2.31ns +1.68%
RegExp Creation (Execution) 9.9±0.02µs 10.4±0.03µs +5.05%
RegExp Creation (Parser) 11.5±0.02µs 11.8±0.10µs +2.61%
RegExp Literal (Compiler) 1794.3±4.66ns 1830.5±2.92ns +2.02%
RegExp Literal (Execution) 14.4±0.03µs 15.1±0.07µs +4.86%
RegExp Literal (Parser) 14.6±0.03µs 15.0±0.03µs +2.74%
RegExp Literal Creation (Compiler) 1623.8±3.01ns 1645.0±5.75ns +1.31%
RegExp Literal Creation (Execution) 9.9±0.02µs 10.3±0.02µs +4.04%
RegExp Literal Creation (Parser) 12.3±0.02µs 12.6±0.02µs +2.44%
Static Object Property Access (Compiler) 1573.4±2.72ns 1572.7±4.03ns -0.04%
Static Object Property Access (Execution) 5.4±0.02µs 5.7±0.01µs +5.56%
Static Object Property Access (Parser) 13.5±0.04µs 13.9±0.05µs +2.96%
String Object Access (Compiler) 1524.8±2.33ns 1537.0±3.10ns +0.80%
String Object Access (Execution) 8.3±0.02µs 8.9±0.01µs +7.23%
String Object Access (Parser) 19.2±0.07µs 19.9±0.06µs +3.65%
String comparison (Compiler) 2.4±0.00µs 2.4±0.01µs 0.00%
String comparison (Execution) 4.7±0.02µs 5.0±0.02µs +6.38%
String comparison (Parser) 15.2±0.03µs 15.5±0.03µs +1.97%
String concatenation (Compiler) 1826.7±5.65ns 1872.7±4.88ns +2.52%
String concatenation (Execution) 4.4±0.02µs 4.7±0.01µs +6.82%
String concatenation (Parser) 10.5±0.03µs 10.8±0.03µs +2.86%
String copy (Compiler) 1476.3±1.62ns 1488.0±4.45ns +0.79%
String copy (Execution) 4.2±0.03µs 4.4±0.01µs +4.76%
String copy (Parser) 7.9±0.02µs 8.1±0.03µs +2.53%
Symbols (Compiler) 1078.7±2.42ns 1096.0±1.80ns +1.60%
Symbols (Execution) 4.3±0.01µs 4.6±0.01µs +6.98%
Symbols (Parser) 6.3±0.02µs 6.3±0.02µs 0.00%

boa_engine/src/tagged.rs Outdated Show resolved Hide resolved
@jedel1043 jedel1043 removed the run-benchmark Label used to run banchmarks on PRs label Jan 18, 2023
@jedel1043 jedel1043 requested a review from nekevss January 18, 2023 03:54
Copy link
Member

@HalidOdat HalidOdat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :)

boa_engine/Cargo.toml Show resolved Hide resolved
boa_macros/src/lib.rs Outdated Show resolved Hide resolved
@jedel1043 jedel1043 added the run-benchmark Label used to run banchmarks on PRs label Jan 18, 2023
@jedel1043 jedel1043 force-pushed the symbol-string-thread-safe branch from d5c1d85 to a993253 Compare January 18, 2023 19:25
@jedel1043 jedel1043 requested a review from HalidOdat January 18, 2023 20:22
@github-actions
Copy link

Benchmark for 6171abc

Click to view benchmark
Test Base PR %
Arithmetic operations (Compiler) 523.2±1.00ns 550.4±1.06ns +5.20%
Arithmetic operations (Execution) 414.7±0.23ns 419.3±0.40ns +1.11%
Arithmetic operations (Parser) 7.8±0.07µs 7.7±0.05µs -1.28%
Array access (Compiler) 1516.5±2.08ns 1500.8±2.55ns -1.04%
Array access (Execution) 9.9±0.01µs 10.9±0.02µs +10.10%
Array access (Parser) 15.8±0.04µs 16.1±0.05µs +1.90%
Array creation (Compiler) 2.4±0.00µs 2.4±0.01µs 0.00%
Array creation (Execution) 1452.2±25.19µs 1506.5±2.15µs +3.74%
Array creation (Parser) 18.7±0.04µs 19.2±0.12µs +2.67%
Array pop (Compiler) 4.1±0.09µs 4.3±0.01µs +4.88%
Array pop (Execution) 850.7±1.56µs 909.8±3.09µs +6.95%
Array pop (Parser) 168.9±0.13µs 171.8±0.16µs +1.72%
Boolean Object Access (Compiler) 1279.6±1.52ns 1283.6±2.05ns +0.31%
Boolean Object Access (Execution) 5.8±0.01µs 6.0±0.06µs +3.45%
Boolean Object Access (Parser) 19.5±0.03µs 20.1±0.04µs +3.08%
Clean js (Compiler) 5.1±0.01µs 5.2±0.01µs +1.96%
Clean js (Execution) 809.2±5.31µs 840.7±3.85µs +3.89%
Clean js (Parser) 39.0±0.08µs 39.6±0.11µs +1.54%
Create Realm 289.1±3.15ns 310.3±2.47ns +7.33%
Dynamic Object Property Access (Compiler) 1803.1±11.43ns 1794.0±5.21ns -0.50%
Dynamic Object Property Access (Execution) 5.4±0.01µs 5.6±0.02µs +3.70%
Dynamic Object Property Access (Parser) 14.3±0.03µs 14.7±0.61µs +2.80%
Fibonacci (Compiler) 2.9±0.06µs 2.8±0.01µs -3.45%
Fibonacci (Execution) 1208.5±8.00µs 1266.7±22.28µs +4.82%
Fibonacci (Parser) 22.1±0.03µs 22.4±0.06µs +1.36%
For loop (Compiler) 2.7±0.01µs 2.8±0.01µs +3.70%
For loop (Execution) 16.3±0.11µs 16.4±0.03µs +0.61%
For loop (Parser) 19.2±0.03µs 19.4±0.04µs +1.04%
Mini js (Compiler) 4.4±0.01µs 4.4±0.01µs 0.00%
Mini js (Execution) 751.0±4.02µs 792.4±3.44µs +5.51%
Mini js (Parser) 34.2±0.11µs 34.2±0.10µs 0.00%
Number Object Access (Compiler) 1133.6±2.36ns 1133.7±28.00ns +0.01%
Number Object Access (Execution) 4.4±0.04µs 4.8±0.01µs +9.09%
Number Object Access (Parser) 15.1±0.10µs 15.5±0.03µs +2.65%
Object Creation (Compiler) 1534.8±38.41ns 1562.6±3.37ns +1.81%
Object Creation (Execution) 5.1±0.02µs 5.3±0.02µs +3.92%
Object Creation (Parser) 12.5±0.03µs 12.8±0.03µs +2.40%
RegExp (Compiler) 1803.9±6.79ns 1787.5±4.74ns -0.91%
RegExp (Execution) 14.5±0.03µs 14.8±0.06µs +2.07%
RegExp (Parser) 13.7±0.04µs 14.0±0.03µs +2.19%
RegExp Creation (Compiler) 1627.8±35.85ns 1609.1±5.38ns -1.15%
RegExp Creation (Execution) 10.0±0.03µs 10.2±0.02µs +2.00%
RegExp Creation (Parser) 11.4±0.02µs 11.7±0.03µs +2.63%
RegExp Literal (Compiler) 1814.9±3.79ns 1786.0±51.44ns -1.59%
RegExp Literal (Execution) 14.5±0.03µs 14.8±0.05µs +2.07%
RegExp Literal (Parser) 14.6±0.04µs 14.9±0.03µs +2.05%
RegExp Literal Creation (Compiler) 1612.1±1.95ns 1617.8±20.75ns +0.35%
RegExp Literal Creation (Execution) 10.0±0.02µs 10.1±0.01µs +1.00%
RegExp Literal Creation (Parser) 12.3±0.03µs 12.5±0.02µs +1.63%
Static Object Property Access (Compiler) 1561.4±2.54ns 1564.8±17.93ns +0.22%
Static Object Property Access (Execution) 5.3±0.01µs 5.5±0.02µs +3.77%
Static Object Property Access (Parser) 13.6±0.76µs 13.8±0.06µs +1.47%
String Object Access (Compiler) 1557.7±58.99ns 1550.3±4.03ns -0.48%
String Object Access (Execution) 8.3±0.04µs 8.7±0.02µs +4.82%
String Object Access (Parser) 19.0±0.03µs 19.7±0.03µs +3.68%
String comparison (Compiler) 2.4±0.01µs 2.4±0.01µs 0.00%
String comparison (Execution) 4.7±0.01µs 4.9±0.02µs +4.26%
String comparison (Parser) 15.2±0.02µs 15.4±0.05µs +1.32%
String concatenation (Compiler) 1836.8±3.43ns 1846.2±2.39ns +0.51%
String concatenation (Execution) 4.4±0.01µs 4.5±0.03µs +2.27%
String concatenation (Parser) 10.4±0.02µs 10.6±0.01µs +1.92%
String copy (Compiler) 1479.7±1.19ns 1483.8±3.23ns +0.28%
String copy (Execution) 4.2±0.01µs 4.4±0.17µs +4.76%
String copy (Parser) 7.8±0.03µs 8.1±0.02µs +3.85%
Symbols (Compiler) 1095.4±3.11ns 1092.2±2.66ns -0.29%
Symbols (Execution) 4.3±0.01µs 4.4±0.01µs +2.33%
Symbols (Parser) 6.2±0.03µs 6.3±0.03µs +1.61%

Copy link
Member

@HalidOdat HalidOdat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks perfect to me! :)

@jedel1043
Copy link
Member Author

bors r+

bors bot pushed a commit that referenced this pull request Jan 19, 2023
The section about `Symbol` on the [specification](https://tc39.es/ecma262/#sec-ecmascript-language-types-symbol-type) says:

> The Symbol type is the set of all non-String values that may be used as the key of an Object property ([6.1.7](https://tc39.es/ecma262/#sec-object-type)).
Each possible Symbol value is unique and immutable.

Our previous implementation of `JsSymbol` used `Rc` and a thread local `Cell<usize>`. However, this meant that two different symbols in two different threads could share the same hash, making symbols not unique.
Also, the [GlobalSymbolRegistry](https://tc39.es/ecma262/#table-globalsymbolregistry-record-fields) is meant to be shared by all realms, including realms that are not in the same thread as the main one; this forces us to replace our current thread local global symbol registry with a thread-safe one that uses `DashMap` for concurrent access. However, the global symbol registry uses `JsString`s as keys and values, which forces us to either use `Vec<u16>` instead (wasteful and needs to allocate to convert to `JsString` on each access) or make `JsString` thread-safe with an atomic counter. For this reason, I implemented the second option.

This PR changes the following:

- Makes `JsSymbol` thread-safe by using Arc instead of Rc, and making `SYMBOL_HASH_COUNT` an `AtomicU64`.
- ~~Makes `JsString` thread-safe by using `AtomicUsize` instead of `Cell<usize>` for its ref count.~~ EDIT: Talked with @jasonwilliams and we decided to use `Box<[u16]>` for the global registry instead, because this won't penalize common usage of `JsString`, which is used a LOT more than `JsSymbol`.
- Makes the `GLOBAL_SYMBOL_REGISTRY` truly global, using `DashMap` as our global map that is shared by all threads.
- Replaces some thread locals with thread-safe alternatives, such as static arrays and static indices.
- Various improvements to all related code for this.
@bors
Copy link

bors bot commented Jan 19, 2023

Pull request successfully merged into main.

Build succeeded:

@bors bors bot changed the title Make JsSymbol thread-safe [Merged by Bors] - Make JsSymbol thread-safe Jan 19, 2023
@bors bors bot closed this Jan 19, 2023
@bors bors bot deleted the symbol-string-thread-safe branch January 19, 2023 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
execution Issues or PRs related to code execution run-benchmark Label used to run banchmarks on PRs technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants