The Baseline Interpreter: A Faster JavaScript Interpreter in Firefox 70
hacks.mozilla.org
hacks.mozilla.org
Informative and easy to digest. I can only think of one other company blogging with similar consistency/quality: Cloudflare.
Firefox performance has seen tremendous gains since their Project Quantum efforts.
It mostly feels on par with Chrome for me pretty much everywhere.
There is one glaring omission though: a single company where I have problems with FF on multiple apps - Google.
Gmail was still dog-slow the last time I tried, Youtube can send my fan into a frenzy and Docs is also regularly problematic. (on Linux)
SpiderMonkey should get around to jitting generators, but I have a hard time blaming the team for focusing on real-world improvements first.
That is benchmarcking most used ALEXA websites. It's named TP 5 and TP6, mozilla use it internally (e. G to measure progress on stylo) Why is the real world (TP5/6) not public?? Phoronix has never used it, mozilla has never publicly published benchmarcks. I guess they favor chromium but I've never seen all results only the few mozillians posted on bugzilla. Let the world know, publish the results, even if it favor chromium. Anyway the mainstream will never be affected by that public information (most people have difficulties discerning a search engine from the concept of browser, let alone talking about benchmarcks)
Maybe there are people (ab)using the async stuf do do something else, but at least it's not really common.
I'd be curious to see how 68 versus 69 versus 70 compare.
Google has been getting better though with supporting FF. They now support Hangouts on FF and Gmail is actually faster for me in FF than it is in Chrome.
A mute point however now with EdgeChrome.
Fun fact, the word "moot" has the same origin as "meet". A "moot point" was originally "something that has to be discussed and decided at a meeting" (like a town hall or similar). Thus there was no sense in discussing it, since it was up to the meeting to decide. Also, scouts still call their congregations "a moot".
<small rant mode>
Nowadays I have two sources of errors when writing.
My own lack of knowledge, or incorrect knowledge, and then the stupid auto corrections that just go down the drain due to me mostly typing across multiple languages. </small rant mode>
So whatever caused it, thanks again.
It sucks that we have to do that, but I can't entirely blame them for making their own products work better on their own browser.
Rambox went proprietary, but was forked into Hamsket. Might be easier than what you're using now.
You mean like MS for a long time did with MSIE?
Are we really back in the 90s, back to “This page works best in $one_specific_browser”?
This is not the future I was hoping for... On the flip side I can use Linux for almost anything, so i guess it’s not all bad.
Do webdevs really check for Chrome AND Firefox compatibility? The devs I know consider the job done as long as their site works with Chrome.
That would technically only make them Chrome-devs.
It seems to work fine on my system running Ubuntu 18.04 with ublock origin installed. Which OS are you using?
I still use it as my default browser on macOS though because it does excel in other areas.
No extensions, no GIFs, no heavy tabs open, perhaps one or two open tabs.
No slowdowns at all after 8 hours on Slack w/ Safari or Brave. Firefox is definitely the worst browser on macOS, compared to the Windows version where it's absolutely perfect and always quick.
Still waiting on Firefox to support hardware-accelerated decoding of videos though.
Wait, Firefox doesn't do this already? Didn't know.
www.mpv.io : a lightweight player that among other things can transparently stream any url understood by youtube-dl
It uses 20x as much cpu as mpv. For purposes of comparison this is like Toyota selling a car that goes just as fast as your Ford so long as you are OK with only getting 4MPG.
There is an addon if you prefer to right click on a url and open in mpv or in an addon like Tridactyl you can do the same with your keyboard. It also lets you speed up and slow down the playback speed which is nice for speakers who talk too slow and take a while to get to the point.
https://bugzilla.mozilla.org/show_bug.cgi?id=1210726
Bug opened 4 years ago. Hundreds of millions in revenue and can't task one person for a summer to hook into the support that already exists.
and probably < 0.5% of it due to its linux userbase?
Firefox has 230 million monthly users, using FF for an average of over 5 hours per day.
Many executives would sell their families for less opportunity.
I seriously doubt that those 20% Firefox users even consider doing a $1 donation.
After all plenty also switch to other search engines.
Its probably more fair to go on profit not revenue.
100 million in revenue * 2.18% is 2.2 million. A decrease of 10% of that is 220k. If engineers at mozilla are 150k then 3 months of work is aprox 38k.
This would put the break even point at losing 2% of its linux users by not spending the money.
> 3 months of work
according to whom? this will almost certainly need more than a single engineer's eyes on it. and even if it is 3 months, that's 3 months they don't spend working on features for 98% of their userbase.
i want this to happen as much as anyone, but i just don't see the compelling math here. it's a chicken-egg problem (if FF could use VA API [1], then more might switch to linux).
personally, i'm happy that Panfrost recently got mainlined.
While for all major platforms even including Windows on ARM64 the performance is good for VP9, and somewhat degraded for high resolution H264 videos, the results for Mac are bad across all of them. It's not even possible to playback videos with a 480p resolution, without being affected by a lot of framedrops.
In those 15s of playback a 480p VP9 video produces around 5 dropped frames, a 720p and 1080p video already ~45 dropped frames. Really worse it is with 4k@60fps videos which have more than 400 dropped frames even with a playback speed of 1.0x!
With an AMD GPU on Linux, Chrome churns, drops frames, and stutters horribly on even 1080p videos at 30fps. Firefox, meanwhile, handles 1440p60 video with no problem. Even two such videos simultaneously, on separate monitors.
Chrome became inexplicably better for parts of early 2019 (I did not note which versions), but starting 2 or 3 months ago Chrome returned to being unusable for YouTube beyond 720p videos.
Before anyone asks, this is on an AMD RX 580 with Mesa 18.0.
Only some distribution-specific Chromium builds do.
For hw decoding to have sense, GPU composition is needed. Hopefully webrender will bring that in for Linux too.
[1] Firefox actually, Chrome does use GPU composition. Chrome for ChromeOS even uses the same driver (libva+intel-vaapi-driver) as desktop linux for video decoding, Google just is not willing to support it on desktop. That's what some distributions enable in their Chromium builds.
I should add that for an identical Linux distro-and-version, and identical browser versions, my laptop (I forget the SKU, but Intel Broadwell U-series GPU) is about equal in performance between Chrome and Firefox. That is to say, 1440p60 runs smooth on each, so they're good enough that there's no issue from which to discern a difference (which is damned impressive for a 4-year old mobile chip, imo).
The annoying part is that hardware acceleration works on chrome OS, so we know the support is buried in there somewhere.
I doubt they will take Linux outside their own walled gardens seruously, Google has already shown their indifference to us Linux users.
But using res on reddit and click "show images" you can tell chrome isn't as fast as other browsers, firefox/brave are visually faster/smoother in scrolling with pics. Hell, even firefox focus is faster on android. But I like chrome addons and sync with my mobile, its my daily driver. Normally I never notice, but a quick clean if starts acting out fixes it for me.
>Accelerated video decode is unavailable on Linux: [137247](https://bugs.chromium.org/p/chromium/issues/detail?id=137247)
>Disabled Features: accelerated_video_decode
I guess Mozilla wins this way.
Thumderbird is underrated.
Back home, Thunderbird, and the occasional donations.
[1]: https://www.thunderbird.net/en-US/thunderbird/68.0/releaseno...
[2]: https://www.thunderbird.net/en-US/thunderbird/60.0/releaseno...
The layman hates updates.
1. Mozilla Corp. dropped Thunderbird as one of their projects, and told the community they would have to figure out how to move ahead with the project if they wanted to. News of "Thunderbird is dead" spread out after this announcement.
2. It turned out there was plenty of interest in the project among the public. Donations came in, and the project was kept alive. They established the "Thunderbird Council" as their governance body.
3. The project still needed some legal home and assistance. The Mozilla Foundation (the non-profit) offered to serve as that. The council studied several options and decided to accept this offer.
And this is how they got here: https://www.thunderbird.net/en-US/about/
I use the HTML version instead to deal with this issue
0: Even with remote code execution vulnerabilities enabled it shows a corporate spam clip instead of the video I'm trying to watch.
- More than just two tiers (JSC has four, and I guess Moz has four too now; I guess it's just a matter of time before V8 follows).
- Bottom tiers must include a fast interpreter that uses JIT ABI and collects types (Ignition and this Moz interpreter smells a lot like JSC's LLInt, which pioneered exactly this for JS).
It's weird that they kept the C++ interpreter. But not too weird, if the IC logic in the new interpreter is costly. In the LLInt, the IC/type logic is either a win (ICs are always a win) or neutral (value profiling and case flag profiling costs nothing in LLInt).
Also worth noting that this architecture - a JIT ABI interpreter that collects types as a bottom tier - is older than any JS engine. I learned it from HotSpot, and I guess that design was based on a Strongtalk VM.
This is the current state of the art of JSC's bottom interpreter tier FWIW: https://webkit.org/blog/9329/a-new-bytecode-format-for-javas...
The last time V8 had their own benchmark, they retired it right after we beat them on it and made a post saying that benchmarks are bad because people cheat on them.
Around that time I stopped seeing google.com claim that I should switch to Chrome “because it’s faster”.
So basically JSC is fast enough to have made V8 ragequit benchmarking. Hope that answers your question!
I've increased my vocabulary today.
In topic: I always wondered why chrome stopped that marketing spiel.
At least you're pressuring Mozilla and Google to step up their game on runtimes!
Comments around cheating are likely aimed at OEMS who ship Chrome derived browsers and spin up the clock frequency when they detect certain benchmarks are running. These look great in online reviews.
There is also the whole ART reboot, where Google made the mistake of not doing AOT the same way as Microsoft did for the Windows Store, by compiling on the device instead of the more beefy store cluster, so they ended up with a mix of fast interpreter written in straight Assembly, a first tier JIT with PGO, and an AOT compiler that takes PGO profiles and really optimizes the critical paths while the device is idle. This circle goes around every time the application is updated or PGO information gets invalidated.
Likewise .NET Native had a few issues with reflection, so .NET Core 3.0 is bringing mixed AOT/JIT into the mix, with further improvements planned for .NET Core 5.
And on the Java world, after a couple of decades with separate AOT (comercial) and JIT toolchains, also the more widespread JDKs are going with both.
So everything new is old again, given the AOT/JIT experiments from Smalltalk, Eiffel, Oberon and Lisp. :)
I would have expected the Meltdown/Spectre mitigations to penalize indirect branches, making direct threading relevant again. From that post, I suppose it isn't the case, but I'd love to know more about it.
Also, direct threading still means doing the same number of indirect branches as before, unless you implemented it as a tree of conditional branches. So direct threading doesn't change the Spectre situation one way or another.
In other words, it isn't practical to compile JS to WASM, and especially not to asm.js. The browser's JIT compilation of JS targets something completely different.
It would be great if Typescript hints could pass right along to the JITs as useful optimization factors, but it currently sounds like TC39 would prefer not to recreate the disasters of ES4 and are staying out of type hints for the forseeable future.
(Well-typed code should prevent most JIT bailouts, at least. Typescript linters could possibly give even better "shape" warnings than they currently do, such as catching the issue the React team recently found of bailouts in the V8 engine due to "shapes" being built with "small integers" being reallocated to doubles at runtime. However, such lint warnings would probably be JIT engine specific, and maybe premature optimization in 90%+ of usages.)
"Type maps" are an interesting idea. You could probably piggy back on/boostrap from WASM types.
We could hower add Interface and optional types as syntax sugar for runtime checks.
Good read. The above mentioned web apps are my biggest pain point at the moment with Firefox. I still use Gmail in Firefox, but it's much slower than running it on chromium. I just accept that, since Google makes all of that.
However, with Google Docs I actually switch over to a chromium browser, even the new Edge beta, because it is simply too slow in Firefox.
It looks like they've taken notice of that and are tackling it head on. Excellent work!
Allocating this additional struct is a waste of memory for a function that is only executed a handful of times, without ever actually using that information for optimizing.
A lot of code on the web is very cold (executed once or twice) and for such code the Baseline Interpreter would add some overhead (requires allocating a JitScript storing the IC data for example and we would then spend more time in IC code as well). It's possible this could be mitigated or fixed with additional work, but we need to keep the C++ interpreter anyway (not all platforms have a JIT backend and it's useful for differential testing) so it's not a priority right now.
A lot of code is run once, so the initial compilation cost is potentially more expensive than just the process of compilation, without even running the generated code, and if not that then compilation+execution is also longer than just interpreting.
There are also benefits for performance. If you haven’t run any of the code yet (through the interpreter), the baseline portion of the JIT has no knowledge of the code that is running, and so has to make a bunch of static guesses and (if you look at the old baseline JIT in JSC) include a lot of code for various common cases that may happen. Eg in the JSC case every arithmetic op include the entire code for both integer and floating point arithmetic inline. That bites you in a few ways: the guessing type info means that you have poorly chosen branch ordering (eg you put integer logic in the middle of the “fast” path for something that is floating point), and you simply generate more code which itself takes more time to produce, and also results in increased icache pressure which hurts runtime performance.
I haven’t read the entire article yet, but the JSC interpreter is written in a pseudo assembly so it can do an on stack replacement to switch into jotted code more or less anywhere during execution as the wonders of assembly means you can guarantee identical layout.
Javascript VM´s these days are fairly complex beasts with huge amount of man-hour and expertise. Also technically this would be a inferior solution as compared to what V8 did with its interpreter in Turbofan (and SpiderMonkey are doing now as presented in the article), by generating pure assembly through the turbofan backend (the same technique used by LuaJIT before with great success).
By the way lets not forget we are talking about Mozilla here, were a couple of more misguided projects could mean the abrupt end of the organization who is suffering to keep its market share in the browser wars.
There are a couple of things that could take some advantage for being re-coded in Rust, but modern super-powered javascript VM´s are hardly one of those things.
Of course, if in the sidelines someone craft a JS VM in Rust, and after IDK, 4 years, you have a mature enough JIT VM, maybe there will be a reason to move, but Mozilla itself investing its unsustainable, limited and in the brink of extinction funds on something that will require a lot of money and that in the end will get you basically the same perfomance as the old C++ jit, its a pretty bad move.
https://blog.mozilla.org/javascript/2017/10/20/holyjit-a-new...
The overall goal is to have Firefox recoded in Rust, why would a JavaScript interpreter be left out?
https://wiki.mozilla.org/Oxidation
That's the whole point of Oxidation.
Firefox is having a hard time to compete with Chrome, and they took too long pursuing other goals, and just remembering one key feature they took a lot of time to implement, was making Firefox a the multi-process browser as Chrome.
I mean, you would be ditching all this effort, rewriting it in Rust, spending key resources only to have some parity with the same browser you already had in C++, spending years, and loosing more market share, as Chrome can spend this time in optimization and features.
For the record, i think Rust is what will save Mozilla, but it must reinvent itself. Do the best they can with the firefox codebase they have, and use Rust for new projects.
Like, creating Cloud, backend system software, and reinvent itself like Ubuntu is doing right now.
They have to be very strategic and pragmatic right now. Two big moonshots, Firefox OS and Rust, and only one of them has paid out their time and resources.
If they want to bet in more moonshots, great, but they must do it in "blue ocean" places, being more innovative on where they should use Rust, were Rust can shine.
I just think that from a strategic (and even technical) point of view, they are just spending precious resources, while at the same time eroding even more their browser market share.
Otherwise Mozilla lives because Google allows it and they allow it because it's mostly irrelevant and it's making itself even more irrelevant through stupidity like the MrRobot mini-scandal.
To clarify: it's a proof of concept, not a full JIT for JS. If you want to follow that project, it lives here: https://github.com/nbp/holyjit.
You know what else is a MASSIVE time and money sink? C/C++.
Combining 2 big and nasty complex stuff you get something even bigger.
----
I don't say to blind rewrite. Is know to be:
> an exercize in vanity and why not say it, stupidity.
But this must take in account TIME. Right now, is not the time for a rewrite, but is better to have it planned.
----
I'm not naive saying this. This is my life (as a rewriter of codebases for several years and many projects). I'm moving a medium sized ERP project to Rust. In parts, too. Focusing in data exchange, yes. But if we don't do it, then the complexity behind will kill us.
Theres no gain in clear performance, unless theres a better algorithm being implemented, no clear gain in productivity, as C++ and Rust are both equaly complex beasts, and with not much gain in security, if you already implemented in "modern c++" and are using smart pointers, including in API´s and moves correctly.
The other gains in security/safety that you might have with Rust, are maybe lost if you think that the C++ codebase have been used and tested in every possible scenario, so a lot of bugs are corrected, and if you think that given this is a Jit VM you will have to use Rust´s unsafe{} in a lot of places, i still think, giving the context, that is not a smart thing to do, and it will be more like a trophy to Rust, but without a more pragmatic and realistic approach to the matter, not focusing properly on results.
Not much gain, you will end with a worse and more buggy JIT in the end, and will have to spend more years, only to get parity to the VM you already had in the first place.
Is like null. You can write null-safe code in any language... as long your developers become "compilers" and by discipline make sure EVERY LINE is null safe. But when your lang do it for you, is a problem that get solved.
C++ demand a lot of attention to details that are unnecessary in rust. This is where the gain come.
Note that not everything can be easily rewritten in Rust due to the existence of lots of C++ code using macros and templates. Getting such to interact with any other language than C++ is painful.
(I'm in the SpiderMonkey team)
I worry that every risk taken to improve Rust, might have a severe cost by alienating Firefox userbase, and with that Mozilla get into troubled waters.
But as you have clarified, inner pieces are being slowly replaced, which is not as bad as rewrite the whole thing from scratch in Rust, while at the same time, leaving the current C++ codebase without any improvement.
Anyway, from the enginnering perspective, kudo for you guys, for being able to make the browser work with all this complication going on under the hood.
Hope it all works out even with all the complication, challenges and risks taken, as we all need good players like Mozilla to lead us to a better future, as we rely more and more on technology to improve our daily lives.
As far as i know, the web rendering engine of Firefox in C++ were pretty old, coded in old c++ style. So in this particular case a rewrite would have some leverage.
The thing is, in the end, i dont know if this part C++, part Rust codebase wont start to create more problems than it solves.
Should the layout and rendering engine be rewritten in C++ or Rust? They decided to go with Rust, and now they will be forced to continue replacing C++ codebases with Rust, for consistency, workforce, etc..
In the end they will fight a lot to recode the browser, and meanwhile the competion can optimize, inovate and create more features.
Rust will gain a lot for sure, but not Firefox, not Mozilla. And with this Mozilla will be in a place where it will need to bet everything in Rust, as its only chance of survival.
End users dont care what technology go on their browsers, they care about perception, and its not clear that a browser will work better just because its in Rust as compared to C++ which is already a high performance language. (Maybe they will spend less resources in tests or in correcting bugs, but thats pretty much it)
Firefox is much better now than it was before? Yes, but my point is it could have been this better version of itself sooner, if they did not use Firefox to fight Rust´s cruzade to relevancy.
We are all employees, not owners. Decisions that look good on paper won't stop people from finding a new job if the consequences of that decision are more than you want to deal with. And won't the new person want to rewrite it anyway? Now we have a rewrite being done by a person who has no idea why all the weird code is so weird.
So the trick isn't rewrite or no rewrite, the trick is how do we make the rewrite give us things we couldn't have without it. Employee retention is important but as you say that's not enough for the board or the users.
And rewriting in phases avoids the worst aspects of rewrites, which are sometimes undertaken in bad faith (intentionally on unintentionally). Some groups I've seen seem to enjoy the fact that you get to write a lot of code without thinking too hard, and management doesn't pester you about deadlines too hard for the first six months. Those are not good reasons for a rewrite, and they usually end pretty badly. But by then the developers have been at the company long enough that the duration looks good on their resume.
I'll believe they have a fix when I see it with my own eyes, which probably won't be for another 6 months because switching my browser workflow isn't something I want to do every couple of weeks to try out a new nightly with big promises.
What I missed in this article is why the Baseline Interpreter is faster than the C++ interpreter. The code snippet for the load zero instruction looks like what a compiler should produce for a straightforward C++ switch case for that instruction. Except that the code uses a push instruction to store the value directly on the system stack, whereas the C++ interpreter would presumably use a more general store instruction into an array (in the heap, maybe) treated as the interpreter stack.
Is that the difference, or am I missing something else?
I found the explanation of what they're doing a little unclear though and it seems they might not be doing exactly what is described in the answer above.
As for whether this is "threaded", and exactly what kind of threading it is, there is widespread confusion and abuse of terminology. https://en.wikipedia.org/wiki/Threaded_code
That's part of it. The generated interpreter should be a bit faster for simple instructions because of the reason you give (also: things like debugger breakpoints have more overhead in the C++ Interpreter).
However, the bigger speedups are because the generated interpreter can use Inline Caches like the Baseline JIT. The C++ Interpreter does not have ICs.
On Windows it silently keeps running in the background most of the time if you have apps or notifications running.
I use ctrl-q as my shortcut key in tmux. I can't count how many times I accidentally sent that into the wrong window :) I consider showQuitWarning in Firefox a necessity.
IMO, no application ever should quit from one key combination without confirmation.
And it's so rare that I shut down the whole browser anyway, so it makes sense to me to make it hard to do accidentally.
Another possible workaround is to go to System Preferences > Keyboard > Shortcuts > App Shortcuts and create a new shortcut. You can specify that in the app Firefox, the menu item “Quit Firefox” should have the shortcut ⌥⌘Q. Then a normal ⌘Q should do nothing.
The real answer to potentially destructive moves is not to ask the user twice, but to let the user easily undo.
You can disable it though.
I've fat fingered Cmd-W and Cmd-Q too many times, and while it's easy to restore, it takes a couple minutes, a lot of bandwidth, and spins the CPU to 100% for a while. Which really sucks when you're on battery.
In Firefox we now have a generated interpreter + a Baseline JIT on top of a mostly shared code base. I think that's a pretty nice design/advantage.
Google doesn't need to plaster the world with Google Analytics if it can get most people to use a browser that phones home.
From around the time of the Windows 8 transition I used Microsoft Edge as much as possible. Firefox was at a low ebb then.
I switched back to Firefox when Microsoft announced it would use the Chromium rendering engine for Edge. At that point Firefox had improved performance a lot and I've mostly been happy with it.
The minus of it however is that many developers are choosing to only support Chrome. For instance I worked at a company that had developed a data analysis tool with a React front end and it didn't work with either Firefox or Edge (or Safari) so I had to install Chrome for work. I don't think there was a deep technical reason why that was, but rather they did not want to go through the effort to test on other browsers. Our customers weren't clamoring for wider browser compatibility so that was OK for the business.
From time to time I find public web pages that have problems w/ Firefox, although more frequently I find pages that don't like it that I block ads at the "hosts" level. Some sites now use trackers as part of the authentication/anti-fraud process and that can be a problem.
Believe it or not I hardly ever log into Google. I have a gmail account that I barely use, but when i do I IMAP into it with em client. I am really done with Adsense, Adwords, Analytics, and all that. If I am working for somebody that is using Google services I will use it, but otherwise I can go a month or two w/o logging into Google.
oh god, it's like identity politics but "vim vs emacs!" flavored
I don't want to have mess with a bunch of settings just to turn off anti-user features and tracking. I am willing to mess with a bunch of settings if it enhances the functionality of the application I'm using.
Open 'about:config' in Firefox and look at all of the ways Firefox's behavior can be configured. I run my own Firefox Sync instance, because Firefox is just that customizable. Google regularly removes customization options from Chrome. I used to be able to Cast non-HTTPS resources from Chrome, then I had to enable a setting buried in its experimental features to do so. Now the feature is "enabled" in the settings, but after Chrome auto-updated a few times, the feature doesn't work at all.
I can no longer install Chrome extensions from GitHub, even though I could a few weeks ago. Google decides to take extensions off of their Chrome Web Store, and then make it difficult to use extensions they don't approve of.
Firefox uses less memory and CPU than Chrome does, I'm on a MacBook, so anything that unnecessarily drains my battery is a pain to use.
Browser vendors should agree to make JS slow and safe again like it used to be, forcing web developers to make their pages smaller and better for users. For the unusual cases like browser-based games, WebAssembly is ok (it's much easier to verify the correctness of a WASM compiler), and it should be behind a dialog box that says something like "This web page would like to use extra battery power to play a game, is that ok?"
Do you have numbers to back that up?
There certainly have been 1 or more security holes in JITs, but AFAICT most of the browser vulnerabilities have more to with bad (new) APIs.
The level where a JIT operates really has nothing to do with the surface syntax of JS, so adding "syntactic sugar" features to JS should have very little impact on JITs. (I'm thinking of things like the class syntax, lexical scope for function literals, etc. Maybe there's a class of additions that I'm missing.)
What people think is the best choice of tiers to use is always evolving.
One factor against JIT's is that modern chips and OS want to set the NX (no execute) bit against the stack and the heap which at least forces attackers into return-oriented programming. To JIT you have to at least partially disable that behavior.
Hm hard to come up with a number that shows JS optimizations are hard, but you can peruse a collection of Javascript engine CVEs: https://github.com/tunz/js-vuln-db
Notice how many are JIT or optimization issues, or are in esoteric features like async generators or the spread operator.
It's interesting how many of those are labeled OOB. Does that mean that we're talking JIT flaws that allow OOB access to memory? Is it's actually tricking the JIT itself into allowing OOB access, or is it actually OOB'ing the JIT?
I wonder what the performance impact of all JIT code being forced to do bounds-checking would be...
What's the difference between the two? Many JavaScript exploits abuse the interaction between strange features of the language to get around bounds checks (often, because a length was checked but invalidated by later JavaScript executing in an unexpected way, or a bound not forseen as needing a check) leading to an out-of-bounds. And I'm assuming many of these are heap corruptions where someone messes with a length that lets them get out-of-bounds.
Not gonna happen.
There's one browser vendor in particular who has 2/3 of the browser market, 96% of the ad network market, 87% of mobile, and a similar lock on online office software, email, mapping/navigation, etc. etc. They have every incentive to use their commanding service in providing both the services and the means of access to those services to consolidate their control over the world's information resources. And, as the key way in which all these different components are implemented and interact with each other, JavaScript is their most effective means of maintaining that stranglehold.
Opinions on this matter may arise from the dichotomy Martin Fowler describes between an "enabling attitude" and a "directing attitude" in software development: https://martinfowler.com/bliki/SoftwareDevelopmentAttitude.h...
You're right that web apps have become extremely JS- and framework-heavy. Just like adding lanes to a freeway increases traffic, adding JS performance has increased demand for it. But faster JS execution does translate to more headroom for developers (regardless of whether they abuse it), which enables new scenarios that wouldn't be possible otherwise.
An enabling attitude will give top developers the freedom to rise higher than ever before; whereas a directing attitude helps to improve those who would perform poorly otherwise (by preventing stupid decisions) -- but places artificial blockades in the way of the best performers.
I found the emulator ran 4x faster on firefox than on chrome. The culprit was the main dispatch loop, a 256-entry switch statement. Chrome used a slow fall-back path because there were too many cases. The fix was to have "if (opcode < 128) { switch for first 128 cases} else { switch for other 128 cases }". It made FF a little bit slower, but greatly sped up on Chrome.
I also tried generating 256 functions and then dispatch to the right sub based on an array of function pointers, but it wasn't any faster than the switch statement.
But that was five year ago, and I'm sure the landscape is different now.
Web browsers are some of the worst-performing software we have today. Asking them to do more than display documents and web pages never seems to go well.
It already has a slim advantage of being 2x faster.
And Javascript has so many advantages in terms of handling. No compilation step needed at all. And since it has modules widely supported now, it is a joy to code in native Javascript without any libraries like React&Co.
Just look at how beautifully you can dynamically load code when it is needed in modern Javascript:
let calendar = await import('/modules/calendar.js');
calendar.askUserForDay("Checkin Date");I guess I am just an idealist screaming about how packet switched networks are unreliable and we should all use circuit switched networks.
Compiling is done by the compiler. So to the developer it is the same. No matter if it comiles to Javascript or Webassembly.
In the end, I don't think writing code for the web in languages other then Javascript will take off. Simply because Javascript will always evolve to fit this specific environment. And therefore will always be the best choice. While other languages will evolve to be the best fit for their niche.
I'm not talking so much about raw speed, it's more about latency. Things such as realtime audio in the browser, non-CSS-driven animation, 3D (or any kind of realtime graphics, really), tight UIs where feedback must be very fast to be useful, etc. In lower-level languages, you must sometimes go as far as to avoid all memory allocations in one critical path. It's very hard to do so in JavaScript, especially when you take into account the prevalent coding style and functional nature of the language.
As long as you have GC and a dynamic type system which requires JIT heuristics to achieve that 2x speedup, you will always have cases of pathological latency which degrade the experience. When you measure raw speed in benchmarks, you amortize all of the jitter.
Now, whether the market is such that it will be satisfied by apps with this behavior is another story.
After ART came into play, and its JIT started getting serious optimizations, doing regular Java math was faster than going over the JNI wall and FloatMath is now deprecated.
At least in python you can use other versions and it's a very similiar environment. But if you want to use mozillas spidermonkey without Firefox, it's hoops and bounds worse experience. I'd argue that v8 is far less of a lock in by comparison.
Given all that, why are we still creating entirely separate engines that are made differently, yet do the same.
Of course the git monoculture is bad. Have you seen how many people complain about git on Twitter?
assuming you know about Windows and OS X and are just talking about servers, there's still the BSDs and Solaris and AIX. a good deal of software is written to just assume a reasonably POSIX-compliant environment, precisely because linux is not the only server OS.
unix-like operating systems are something of a monoculture and that IS very bad, because OS design is basically stuck in 1973
>Is git bad?
yes and anyone who says otherwise is numb to the pain
V8/Blink/Chromium are not independent community projects, but firmly in the hands of Google. Chromium being the only viable implementation would put too much control in the hands of a single company (regardless of which company that is, Firefox being the only implementation would be just as bad).
It's redundant effort, but it also enforces consensus building and exchange of ideas.
EG Google would have happily stuck with PNacl, but (afaik) Mozilla pretty much forced their hand - with the result being Webassembly, a much better design.
Wasm was not what was promised. Mozilla and the other vendors just translated the wasm bytecode to js bytecode. All it did was skip a few steps. Yet the actual requirements for performance, simd, was ignored in its proposal. It has been a significant under delivery overall.
It does, so it’s necessary. Performance is not the only one result we care about.
It's nothing fundamental about WASM; in fact they state that the actual computations are slightly faster.
To name one reason: would we have asm.js/Wasm instead of (P)NaCl without Mozilla's work on asm.js optimizations in SpiderMonkey?
Did this somehow change?
JSC is even better in that regard - it’s API and ABI stable so you can just link to the[1] system install and use it [2].
[1] on Linux there are multiple (although technically it could be made to have a single lib for qt,gtk,wx...
[2] ok, actually using the C API is very very clunky :-/
The most (in)famous consumer of that is polkit :) but also GJS
Eg you’d ideally have
* libjavascriptcore - the actual engine, runtim, and c-api, etc
* libjavascriptcore-qt (only the bindings, it would link the root jsc lib)
* libjavascriptcore-gtk (same)
* etc
The problem is that because they talk directly to internal interfaces they need to update in lockstep.
On Mac the only frameworks that do that are the core webkit frameworks. Nothing else on the system can talk to the internals (Mac and iOS have fairly comprehensive support for distinct internal/project/public APIs). But the system webkit, webcore, jsc, etc all have to update and build in lockstep.
In an ideal world all the alternate language bindings would be built on top of the stable C API, but alas (as I said before) the C API is fairly clunky and also out of date wrt to modern JS features. Also there are fun performance things a given binding can achieve if it doesn’t need to go through some layer of abi stability limitations.
I recall there being a desire to make it easier for bindings to be done entirely through the API, but as said elsewhere the API is somewhat clunky. Of course any level of abstraction adds costs - for example by being tied to the innards of JSC the various bridges are able to directly bludgeon the tag bits in JSString (the jsc raw string type) so there’s zero copying.
It also theoretically means you can do automatic object bridging (see the objc bindings).
So it’s not “JSC has to have UI bindings” as much as “JSC can be built with bridging APIs for major embedding frameworks”.
There is a trade off to be made, and long term I’m sure everyone in the JSC team at Apple would rather they could pull the bridges out of core build, but API design is very hard when you are having to think about long term support, coupled with continued support for the existing APIs.