serenity icon indicating copy to clipboard operation
serenity copied to clipboard

LibJS: Resurrect the JIT

Open skyrising opened this issue 1 year ago • 4 comments

This brings back the JIT, including all necessary changes for the new bytecode format.

Test results:

Same test262 diff as before the bytecode change
    test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-try-finally-return.js               ✅ -> ❌
    test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-try-finally-throw.js                ✅ -> ❌
    test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-try-finally.js                      ✅ -> ❌
    test/built-ins/AsyncGeneratorPrototype/throw/throw-suspendedYield-try-finally.js                        ❌ -> ✅
    test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js                   ✅ -> ❌
    test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js ✅ -> ❌
    test/built-ins/GeneratorPrototype/return/try-finally-within-try.js                                      ✅ -> ❌
    test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js                    ❌ -> ✅
    test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js   ❌ -> ✅
    test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js  ❌ -> ✅
    test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js                                       ❌ -> ✅
    test/built-ins/Proxy/set/call-parameters-prototype-index.js                                             ✅ -> ❌
    test/built-ins/decodeURI/S15.1.3.1_A2.5_T1.js                                                           💀 -> ✅
    test/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js                                                  💀 -> ✅
    test/language/expressions/async-arrow-function/try-return-finally-reject.js                             ✅ -> ❌
    test/language/expressions/async-arrow-function/try-return-finally-return.js                             ✅ -> ❌
    test/language/expressions/async-arrow-function/try-return-finally-throw.js                              ✅ -> ❌
    test/language/expressions/async-function/try-return-finally-reject.js                                   ✅ -> ❌
    test/language/expressions/async-function/try-return-finally-return.js                                   ✅ -> ❌
    test/language/expressions/async-function/try-return-finally-throw.js                                    ✅ -> ❌
    test/language/expressions/yield/star-rhs-iter-rtrn-no-rtrn.js                                           ✅ -> ❌
    test/language/expressions/yield/star-rhs-iter-rtrn-res-value-final.js                                   ✅ -> ❌
    test/language/statements/async-function/try-return-finally-reject.js                                    ✅ -> ❌
    test/language/statements/async-function/try-return-finally-return.js                                    ✅ -> ❌
    test/language/statements/async-function/try-return-finally-throw.js                                     ✅ -> ❌
Old JIT vs. new JIT: ~2% speedup
Suite       Test                                   Speedup  Old (Mean ± Range)        New (Mean ± Range)
----------  -----------------------------------  ---------  ------------------------  ------------------------
SunSpider   3d-cube.js                               1.333  0.027 ± 0.020 … 0.030     0.020 ± 0.020 … 0.020
SunSpider   3d-morph.js                              1      0.040 ± 0.040 … 0.040     0.040 ± 0.040 … 0.040
SunSpider   3d-raytrace.js                           1      0.050 ± 0.050 … 0.050     0.050 ± 0.050 … 0.050
SunSpider   access-binary-trees.js                   1.048  0.073 ± 0.070 … 0.080     0.070 ± 0.070 … 0.070
SunSpider   access-fannkuch.js                       1.333  0.013 ± 0.010 … 0.020     0.010 ± 0.010 … 0.010
SunSpider   access-nbody.js                          1      0.010 ± 0.010 … 0.010     0.010 ± 0.010 … 0.010
SunSpider   access-nsieve.js                         1      0.003 ± 0.000 … 0.010     0.003 ± 0.000 … 0.010
SunSpider   bitops-3bit-bits-in-byte.js              1.222  0.037 ± 0.030 … 0.040     0.030 ± 0.030 … 0.030
SunSpider   bitops-bits-in-byte.js                   1      0.030 ± 0.030 … 0.030     0.030 ± 0.030 … 0.030
SunSpider   bitops-bitwise-and.js                    1.023  0.297 ± 0.290 … 0.300     0.290 ± 0.290 … 0.290
SunSpider   bitops-nsieve-bits.js                    0.6    0.010 ± 0.010 … 0.010     0.017 ± 0.010 … 0.030
SunSpider   controlflow-recursive.js                 1.031  0.110 ± 0.110 … 0.110     0.107 ± 0.100 … 0.110
SunSpider   crypto-aes.js                            1.125  0.030 ± 0.030 … 0.030     0.027 ± 0.020 … 0.040
SunSpider   crypto-md5.js                            1.091  0.040 ± 0.040 … 0.040     0.037 ± 0.030 … 0.040
SunSpider   crypto-sha1.js                           1.333  0.040 ± 0.040 … 0.040     0.030 ± 0.030 … 0.030
SunSpider   date-format-tofte.js                     1.037  0.187 ± 0.180 … 0.190     0.180 ± 0.180 … 0.180
SunSpider   date-format-xparb.js                     1.1    0.073 ± 0.070 … 0.080     0.067 ± 0.060 … 0.070
SunSpider   math-cordic.js                           1.133  0.057 ± 0.050 … 0.060     0.050 ± 0.050 … 0.050
SunSpider   math-partial-sums.js                     1      0.110 ± 0.110 … 0.110     0.110 ± 0.110 … 0.110
SunSpider   math-spectral-norm.js                    0.923  0.040 ± 0.030 … 0.050     0.043 ± 0.040 … 0.050
SunSpider   regexp-dna.js                            1      0.420 ± 0.410 … 0.430     0.420 ± 0.420 … 0.420
SunSpider   string-base64.js                         1.077  0.047 ± 0.040 … 0.060     0.043 ± 0.040 … 0.050
SunSpider   string-fasta.js                          1.051  0.347 ± 0.340 … 0.350     0.330 ± 0.330 … 0.330
SunSpider   string-tagcloud.js                       1.114  0.327 ± 0.320 … 0.340     0.293 ± 0.290 … 0.300
SunSpider   string-unpack-code.js                    0.912  0.413 ± 0.400 … 0.430     0.453 ± 0.450 … 0.460
SunSpider   string-validate-input.js                 0.957  0.073 ± 0.070 … 0.080     0.077 ± 0.070 … 0.090
Kraken      ai-astar.js                              1.121  0.837 ± 0.830 … 0.840     0.747 ± 0.740 … 0.760
Kraken      audio-beat-detection.js                  1.138  0.493 ± 0.490 … 0.500     0.433 ± 0.430 … 0.440
Kraken      audio-dft.js                             1.235  0.403 ± 0.360 … 0.430     0.327 ± 0.320 … 0.340
Kraken      audio-fft.js                             1.12   0.343 ± 0.340 … 0.350     0.307 ± 0.300 … 0.310
Kraken      audio-oscillator.js                      0.942  0.437 ± 0.430 … 0.450     0.463 ± 0.450 … 0.480
Kraken      imaging-darkroom.js                      1.087  2.837 ± 2.790 … 2.910     2.610 ± 2.560 … 2.660
Kraken      imaging-desaturate.js                    1.222  0.680 ± 0.660 … 0.690     0.557 ± 0.540 … 0.570
Kraken      imaging-gaussian-blur.js                 0.849  2.217 ± 2.150 … 2.250     2.610 ± 2.590 … 2.620
Kraken      json-parse-financial.js                  1.114  0.163 ± 0.140 … 0.190     0.147 ± 0.140 … 0.160
Kraken      json-stringify-tinderbox.js              1.017  0.203 ± 0.200 … 0.210     0.200 ± 0.190 … 0.210
Kraken      stanford-crypto-aes.js                   1.048  0.583 ± 0.560 … 0.610     0.557 ± 0.550 … 0.560
Kraken      stanford-crypto-ccm.js                   1.058  0.610 ± 0.600 … 0.620     0.577 ± 0.560 … 0.590
Kraken      stanford-crypto-pbkdf2.js                1.095  1.037 ± 1.030 … 1.050     0.947 ± 0.930 … 0.960
Kraken      stanford-crypto-sha256-iterative.js      1.045  0.460 ± 0.460 … 0.460     0.440 ± 0.430 … 0.450
Octane      box2d.js                                 1.029  2.457 ± 2.450 … 2.460     2.387 ± 2.360 … 2.430
Octane      code-load.js                             0.998  2.127 ± 2.110 … 2.140     2.130 ± 2.120 … 2.140
Octane      crypto.js                                1.001  5.100 ± 5.060 … 5.130     5.097 ± 5.080 … 5.110
Octane      deltablue.js                             1.003  3.057 ± 3.030 … 3.080     3.047 ± 3.030 … 3.080
Octane      earley-boyer.js                          1.009  21.737 ± 21.280 … 22.370  21.553 ± 21.080 … 21.910
Octane      gbemu.js                                 1.027  3.677 ± 3.630 … 3.710     3.580 ± 3.480 … 3.660
Octane      mandreel.js                              1.05   20.750 ± 20.480 … 21.030  19.763 ± 19.500 … 20.000
Octane      navier-stokes.js                         5.932  2.037 ± 2.020 … 2.060     0.343 ± 0.330 … 0.350
Octane      pdfjs.js                                 0.996  3.547 ± 3.480 … 3.610     3.560 ± 3.480 … 3.620
Octane      raytrace.js                              1.011  8.210 ± 8.140 … 8.320     8.117 ± 8.060 … 8.160
Octane      regexp.js                                0.973  27.083 ± 26.650 … 27.580  27.843 ± 27.720 … 28.020
Octane      richards.js                              1.002  2.023 ± 2.010 … 2.030     2.020 ± 2.010 … 2.030
Octane      splay.js                                 0.998  2.993 ± 2.980 … 3.000     3.000 ± 2.990 … 3.010
Octane      typescript.js                            0.989  48.023 ± 47.930 … 48.160  48.543 ± 48.070 … 48.930
Octane      zlib.js                                  1.024  83.333 ± 82.740 … 83.820  81.347 ± 79.380 … 83.020
SunSpider   Total                                    1.024  2.903                     2.837
Kraken      Total                                    1.035  11.303                    10.920
Octane      Total                                    1.016  236.153                   232.330
All Suites  Total                                    1.017  250.360                   246.087
New BC vs. new JIT: ~2x speedup
Suite       Test                                   Speedup  Old (Mean ± Range)           New (Mean ± Range)
----------  -----------------------------------  ---------  ---------------------------  ------------------------
SunSpider   3d-cube.js                               2.5    0.050 ± 0.050 … 0.050        0.020 ± 0.020 … 0.020
SunSpider   3d-morph.js                              1.75   0.070 ± 0.070 … 0.070        0.040 ± 0.040 … 0.040
SunSpider   3d-raytrace.js                           1.6    0.080 ± 0.080 … 0.080        0.050 ± 0.050 … 0.050
SunSpider   access-binary-trees.js                   1.19   0.083 ± 0.080 … 0.090        0.070 ± 0.070 … 0.070
SunSpider   access-fannkuch.js                       9      0.090 ± 0.090 … 0.090        0.010 ± 0.010 … 0.010
SunSpider   access-nbody.js                          5      0.050 ± 0.050 … 0.050        0.010 ± 0.010 … 0.010
SunSpider   access-nsieve.js                        12      0.040 ± 0.040 … 0.040        0.003 ± 0.000 … 0.010
SunSpider   bitops-3bit-bits-in-byte.js              1.889  0.057 ± 0.050 … 0.060        0.030 ± 0.030 … 0.030
SunSpider   bitops-bits-in-byte.js                   2.333  0.070 ± 0.070 … 0.070        0.030 ± 0.030 … 0.030
SunSpider   bitops-bitwise-and.js                    1.126  0.327 ± 0.320 … 0.330        0.290 ± 0.290 … 0.290
SunSpider   bitops-nsieve-bits.js                    3.6    0.060 ± 0.060 … 0.060        0.017 ± 0.010 … 0.030
SunSpider   controlflow-recursive.js                 1.156  0.123 ± 0.120 … 0.130        0.107 ± 0.100 … 0.110
SunSpider   crypto-aes.js                            2.25   0.060 ± 0.060 … 0.060        0.027 ± 0.020 … 0.040
SunSpider   crypto-md5.js                            1.364  0.050 ± 0.050 … 0.050        0.037 ± 0.030 … 0.040
SunSpider   crypto-sha1.js                           1.667  0.050 ± 0.050 … 0.050        0.030 ± 0.030 … 0.030
SunSpider   date-format-tofte.js                     0.667  0.120 ± 0.120 … 0.120        0.180 ± 0.180 … 0.180
SunSpider   date-format-xparb.js                     1.05   0.070 ± 0.070 … 0.070        0.067 ± 0.060 … 0.070
SunSpider   math-cordic.js                           2      0.100 ± 0.100 … 0.100        0.050 ± 0.050 … 0.050
SunSpider   math-partial-sums.js                     1.182  0.130 ± 0.130 … 0.130        0.110 ± 0.110 … 0.110
SunSpider   math-spectral-norm.js                    1.385  0.060 ± 0.060 … 0.060        0.043 ± 0.040 … 0.050
SunSpider   regexp-dna.js                            0.984  0.413 ± 0.410 … 0.420        0.420 ± 0.420 … 0.420
SunSpider   string-base64.js                         1.385  0.060 ± 0.060 … 0.060        0.043 ± 0.040 … 0.050
SunSpider   string-fasta.js                          1.131  0.373 ± 0.370 … 0.380        0.330 ± 0.330 … 0.330
SunSpider   string-tagcloud.js                       1      0.293 ± 0.290 … 0.300        0.293 ± 0.290 … 0.300
SunSpider   string-unpack-code.js                    0.993  0.450 ± 0.440 … 0.460        0.453 ± 0.450 … 0.460
SunSpider   string-validate-input.js                 1.043  0.080 ± 0.080 … 0.080        0.077 ± 0.070 … 0.090
Kraken      ai-astar.js                              6.598  4.927 ± 4.890 … 4.970        0.747 ± 0.740 … 0.760
Kraken      audio-beat-detection.js                  6.308  2.733 ± 2.700 … 2.750        0.433 ± 0.430 … 0.440
Kraken      audio-dft.js                             7.929  2.590 ± 2.520 … 2.630        0.327 ± 0.320 … 0.340
Kraken      audio-fft.js                             8.522  2.613 ± 2.560 … 2.650        0.307 ± 0.300 … 0.310
Kraken      audio-oscillator.js                      6.108  2.830 ± 2.790 … 2.900        0.463 ± 0.450 … 0.480
Kraken      imaging-darkroom.js                      1.833  4.783 ± 4.720 … 4.890        2.610 ± 2.560 … 2.660
Kraken      imaging-desaturate.js                    7.162  3.987 ± 3.940 … 4.070        0.557 ± 0.540 … 0.570
Kraken      imaging-gaussian-blur.js                 6.604  17.237 ± 16.700 … 17.740     2.610 ± 2.590 … 2.620
Kraken      json-parse-financial.js                  0.977  0.143 ± 0.140 … 0.150        0.147 ± 0.140 … 0.160
Kraken      json-stringify-tinderbox.js              0.933  0.187 ± 0.180 … 0.190        0.200 ± 0.190 … 0.210
Kraken      stanford-crypto-aes.js                   2.317  1.290 ± 1.270 … 1.310        0.557 ± 0.550 … 0.560
Kraken      stanford-crypto-ccm.js                   1.803  1.040 ± 1.010 … 1.060        0.577 ± 0.560 … 0.590
Kraken      stanford-crypto-pbkdf2.js                2.687  2.543 ± 2.460 … 2.610        0.947 ± 0.930 … 0.960
Kraken      stanford-crypto-sha256-iterative.js      2.083  0.917 ± 0.910 … 0.930        0.440 ± 0.430 … 0.450
Octane      box2d.js                                 1.858  4.433 ± 4.370 … 4.470        2.387 ± 2.360 … 2.430
Octane      code-load.js                             1.017  2.167 ± 2.160 … 2.180        2.130 ± 2.120 … 2.140
Octane      crypto.js                                2.258  11.507 ± 11.460 … 11.540     5.097 ± 5.080 … 5.110
Octane      deltablue.js                             1.008  3.070 ± 3.040 … 3.090        3.047 ± 3.030 … 3.080
Octane      earley-boyer.js                          1.212  26.117 ± 25.860 … 26.330     21.553 ± 21.080 … 21.910
Octane      gbemu.js                                 1.74   6.230 ± 6.210 … 6.260        3.580 ± 3.480 … 3.660
Octane      mandreel.js                              1.816  35.887 ± 35.610 … 36.310     19.763 ± 19.500 … 20.000
Octane      navier-stokes.js                         7.66   2.630 ± 2.560 … 2.680        0.343 ± 0.330 … 0.350
Octane      pdfjs.js                                 1.34   4.770 ± 4.460 … 5.390        3.560 ± 3.480 … 3.620
Octane      raytrace.js                              1.164  9.447 ± 9.430 … 9.470        8.117 ± 8.060 … 8.160
Octane      regexp.js                                1.015  28.273 ± 28.150 … 28.470     27.843 ± 27.720 … 28.020
Octane      richards.js                              1      2.020 ± 2.020 … 2.020        2.020 ± 2.010 … 2.030
Octane      splay.js                                 1.038  3.113 ± 3.080 … 3.150        3.000 ± 2.990 … 3.010
Octane      typescript.js                            1.28   62.127 ± 61.750 … 62.770     48.543 ± 48.070 … 48.930
Octane      zlib.js                                  3.036  246.957 ± 244.860 … 249.870  81.347 ± 79.380 … 83.020
SunSpider   Total                                    1.202  3.410                        2.837
Kraken      Total                                    4.379  47.820                       10.920
Octane      Total                                    1.932  448.747                      232.330
All Suites  Total                                    2.032  499.977                      246.087

skyrising avatar Feb 20 '24 17:02 skyrising

The bytecode instruction format and VM architecture will change repeatedly in the near future, and I don't intend to maintain the JIT through all these changes.

As I stated when originally introducing the JIT, it was meant to be an experiment. If you want to keep hacking on it, you are free to do so anywhere but the master branch :)

awesomekling avatar Feb 20 '24 19:02 awesomekling

The bytecode instruction format and VM architecture will change repeatedly in the near future, and I don't intend to maintain the JIT through all these changes.

How much change are you planning? This PR is not even 400 lines of pretty simple changes for a major change of the format. I don't agree with the assumption that maintaining the JIT is hard. New bytecode instructions can be added without touching the JIT and if some instruction changes in a way that wouldn't be simple to translate, it can simply be removed from the JIT and someone else can bring it back later.

As I stated when originally introducing the JIT, it was meant to be an experiment.

I would say a successful one.

Looking back at the first video regarding the JIT you said: "in order to evaluate the security versus performance tradeoffs of anything you need to actually know what you're trading for what and we don't know how much performance we are giving up right now". Now we know it's about 2x, but does anybody actually know what the security side of the tradeoff looks like? How do you even measure that?

While it's cute to say that we're 5x slower than JSC without JIT, we're even slower than JSC with JIT. When we're trailing behind, does it really make sense to take a step in the opposite direction, while the "competitor" has lots of engineers working on pulling ahead?

If you want to keep hacking on it, you are free to do so anywhere but the master branch :)

What would be my motivation to spend time on that? Working on something that others appreciate is especially fun, while working on something that's essentially unwelcome is pretty much the opposite. Not to mention the increased difficulty of maintaining something in parallel to the main stream of development, where you have to spend a considerable effort on rebasing alone, in addition to the changes required to keep it working. After all, there is a reason ladybird isn't in a separate repository anymore...

skyrising avatar Feb 20 '24 20:02 skyrising

but does anybody actually know what the security side of the tradeoff looks like? How do you even measure that?

Google hands out $10K+ in rewards for V8 security vulnerabilities in nearly every major release of Chrome, most of which can be traced to TurboFan (their JIT compiler). So we do know these vulnerabilities are frequent and costly.

trflynn89 avatar Feb 20 '24 22:02 trflynn89

Google hands out $10K+ in rewards for V8 security vulnerabilities in nearly every major release of Chrome, most of which can be traced to TurboFan (their JIT compiler). So we do know these vulnerabilities are frequent and costly.

I don't have an opinion on this PR (not that it would matter if I had one), but to add some data to this: https://lyra.horse/misc/chromium_vrp_tree.html shows security payouts by directory. I'll leave it up to you decide what that means about JITs and risk surface :)

nico avatar Feb 22 '24 23:02 nico