22 ms·
JIT-Less V8
- ape4 8y ago"V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++." from its home page. I didn't immediately know
- michaelcampbell 8y agoAnd?
- CGamesPlay 8y agoA common (and, in my opinion, legitimate) complaint about blog posts that appear here often is that the company publishing the post doesn't say what it is they are or are doing, and as a result, why anyone should care about the about the blog post.
- mark-r 8y agoI honestly don't blame you for not knowing, but there's a certain amount of assumed knowledge for readers of this site.
- la_fayette 8y agoThis means react native can use V8 on iOS? Does this have any consequences on performance or similar?
- mikepurvis 8y agoBoth the rationale and some first-level benchmarks are given in the article.
- oso2k 8y agoYes. Says so in blog post.
- sercand 8y agoI think JavascriptCore is more performant than V8. So, it is not necessary.
- schuay 8y agoThat is not yet clear. Early adopters have reported (jitless) V8 to be at least as fast as (jitless) JSC on Octane2 on a native iOS device.
- irrational 8y agoApple requires browsers on iOS to use the same rendering engine as Safari, but would it allow a browser to use a different JavaScript engine? Or is this a loophole that Apple didn't forsee that they will be closing in the future? Are the rendering engine and JavaScript engine so separated that you could use the Safari rendering engine, but a different JS engine?
- detaro 8y agoNo, the two are deeply linked and you don't have the kind of access you need to replace it.
- JelteF 8y agoAs far as I know Apple doesn't require browsers to use the same rendering engine as Safari. It's just that so far any rendering engine + JS engine required a JIT to make it performant. And because a JIT is not allowed because apps are not allowed to write to executable memory. That's why the 3rd party browsers all used the same rendering engine as Safari.
- kalleboo 8y agoThe app store rules disallow other rendering engines: 2.5.6 Apps that browse the web must use the appropriate WebKit framework and WebKit Javascript Before WKWebView, even the Safari-based UIWebView didn't JIT JavaScript. Chrome for iOS was released years before WKWebView was added, so a lack of JIT in their own JavaScript engine would not have made a difference.
- kalleboo 8y ago2.5.6 Apps that browse the web must use the appropriate WebKit framework and WebKit Javascript They thought of the loophole already
- est31 8y agoThere's a software-level rule that forbids JIT engines by never allowing apps to mark pages as executable. According to this rule, you could run Chrome on iOS now. But there's also a policy level rule: > 4.7 HTML5 Games, Bots, etc. > Apps may contain or run code that is not embedded in the binary (e.g. HTML5-based games, bots, etc.), as long as [...] the software [...] only uses capabilities available in a standard WebKit view (e.g. it must open and run natively in Safari without modifications or additional software); your app must use WebKit and JavaScript Core to run third party software and should not attempt to extend or expose native platform APIs to third party software https://developer.apple.com/app-store/review/guidelines/ https://developer.apple.com/app-store/review/guidelines/
- andy_ppp 8y agoDoes this avoid some of the issues with Spectre et al?
- olliej 8y agonope - unrelated security concerns.
- brlewis 8y agoThe information I was looking for, what kind of interpreter they mean, was in an Ignition article linked from the main article: https://v8.dev/blog/ignition-interpreter https://v8.dev/blog/ignition-interpreter "With Ignition, V8 compiles JavaScript functions to a concise bytecode, which is between 50% to 25% the size of the equivalent baseline machine code. This bytecode is then executed by a high-performance interpreter which yields execution speeds on real-world websites close to those of code generated by V8’s existing baseline compiler."
- Leszek 8y agoNote that the "existing" baseline compiler is now removed, and entirely replaced by the interpreter.
- cromwellian 8y agoFor very security sensitive embedded applications, this could be a huge boon, since it reduces attack area surface, both from the point of view of executable pages, to the simplicity of the interpreter vs full JIT. Granted, there are many JS interpreters already available, like Ducktape, that fulfill the same benefits, but the immediate upside of this is compatibility with the full Node/ES6+ ecosystem and Chrome Dev Tools. I have to say, Ducktape looks like it might have superior resource usage for very low memory situations.
- xuejie 8y agoDefinitely agree duktape is a decent attempt at low memory situation, but one additional point is that duktape is very slow compared to modern JavaScript engines. Hence I wonder if we can split ignition off v8 to create a standalone fast JavaScript interpreter at the cost of (possibly) more memory consumptions than duktape, that could prove to be useful in many scenarios.
- ricardobeat 8y ago“Very slow compared to” is still as fast, or faster than, many other dynamic language runtimes. In my case I saw a 2x-10x difference between V8 and Duktape, which is acceptable given the trade-offs.
- xuejie 8y agoAgreed, and I'm not saying duktape doesn't have a use case, I'm merely saying having a standalone ignition interpreter might enable different use cases.
- Leszek 8y agoIgnition is very tightly coupled to the rest of V8, starting with that fact that it uses inline caches and the object model to maintain performance, and finishing with it itself being written in "CSA", which is an assembler DSL that is passed through the TurboFan (optimizing compiler) backend to generate the machine code for the bytecode handlers (this has the interesting side-effect that porting V8 to a new platform requires porting the optimizing compiler). There's not really much that can be split off.
- bjourne 8y agoI'm skeptical of the claim of improved security. Theoretically, if there were some horrible bugs in the JIT, one could craft malicious input data causing the JIT to insert arbitrary code in the code heap. In practice, it doesn't seem possible. At least HotSpot has been JIT:ing code for decades and no one has been able to find such an exploit.
- justincormack 8y agoJIT spraying for ASLR defeat is a thing https://en.m.wikipedia.org/wiki/JIT_spraying https://en.m.wikipedia.org/wiki/JIT_spraying
- samps 8y agoSecurity bugs in HotSpot happen can and do happen. Check out the CVE list for the JRE: https://www.cvedetails.com/vulnerability-list.php?vendor_id=93&product_id=19117&version_id=0&page=1&hasexp=0&opdos=0&opec=0&opov=0&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0&cvssscoremax=0&year=0&month=0&cweid=0&order=1&trc=599&sha=e7bd4bdaede94939bbb984bced9c264b834fc20c https://www.cvedetails.com/vulnerability-list.php?vendor_id=...
- snek 8y agoYou can read more about the use cases and targeted user here: https://goo.gl/kRnhVe https://goo.gl/kRnhVe They mention Cobalt (to allow targeting playstation), react native, nativescript, pdfium, and chrome's proxy resolver.
- saagarjha 8y ago> Theoretically, if there were some horrible bugs in the JIT, one could craft malicious input data causing the JIT to insert arbitrary code in the code heap. In practice, it doesn't seem possible. This is very possible: just do a search for ${your favorite JIT} arbitrary code execution, and you'll almost certainly see a real-world vulnerability. > At least HotSpot has been JIT:ing code for decades and no one has been able to find such an exploit. Yeah, no. See for example https://www.syscan360.org/slides/2013_EN_ExploitYourJavaNativeVulnerabilitiesOnWin7JRE7InOneMinute_YukiChen.pdf https://www.syscan360.org/slides/2013_EN_ExploitYourJavaNati...
- samcday 8y agoFor a team that has been pushing the cutting edge of Javascript VM performance for many years, it must feel pretty weird to ship a feature that allows one to willingly regress performance so much!
- schuay 8y agoA fast V8 with jitting isn't going away. Jitless V8 is meant for embedders that either cannot or do not want to allocate executable memory at runtime. (Also, in many common real-world workloads the performance regression is minimal.)
- samcday 8y agoI was worried my original comment might be misunderstood, that's why I qualified it as "... allows one to >>willingly<< regress performance...". Looks like it still got misunderstood anyway ;)
- Klathmon 8y agoI believe this was also (at least partially) done for performance reasons! In general, compared to a JIT, an interpreter is faster to start executing code, and can more quickly (and efficiently!) execute code that will only run once. V8's "Ignition" started as a way to replace the "baseline" JIT in their engine. It can begin executing code while the optimizing compiler gets up to speed and analyzes what needs to be optimized and it can execute code that is extremely likely to only run once (like top level javascript). The bytecode representation they use for Ignition is also used by their optimizing compiler "TurboFan", which means that they throw away the actual source code after it's been converted to bytecode, saving quite a lot of memory! All together this means that the Ignition+TurboFan pipeline is faster to start executing, has lower resource usage, and is much simpler than the old stack of a "baseline" JIT (full-codegen) and their old optimizing compiler (crankshaft). Being able to disable the optimizing JIT entirely is just another bonus of the architecture!
- mark-r 8y agoJust another indication of Google trying to take over the world. There's a class of machines where Chrome can't run? We need to fix that, stat!
- mark-r 8y agoThe tone may be flippant, but I was serious. Google's M.O. is to expand their reach into as many corners of our lives as possible. Having devices that can't run Javascript on Chrome is an impediment to that goal, and so I'm sure the marching orders were to find a way to make it work. It is already acknowledged that some upcoming work will be done to improve areas that are still too slow.
- piannucci 8y agoHow bad of an idea would it be to create a ROP-based JIT engine for these platforms? You could hand-craft the gadgets and use the stack to reduce interpreter dispatch overhead.
- Scaevolus 8y agoThat's called "Subroutine threading"! :-) https://en.wikipedia.org/wiki/Threaded_code#Subroutine_threading https://en.wikipedia.org/wiki/Threaded_code#Subroutine_threa... V8's Ignition interpreter is implemented with "Direct threading", which is quite similar but (probably?) faster on modern processors-- it does an indirect jump to the next bytecode handler instead of a return: https://news.ycombinator.com/item?id=10034167 https://news.ycombinator.com/item?id=10034167 "The bytecode handlers are not intended to be called directly, instead each bytecode handler dispatches to the next bytecode. Bytecode dispatch is implemented as a tail call operation in TurboFan. The interpreter loads the next bytecode, indexes into the dispatch table to get the code object of the target bytecode handler, and then tail calls the code object to dispatch to the next bytecode handler."
- bastawhiz 8y agoI'm curious if the runtime flag to enable JITless mode could also be enabled at compile time, removing the JIT compiler from the binary entirely. That could be really useful for projects where memory comes at a premium (and performance is not a major concern), like micropython but for JavaScript. I assume this also doesn't support WASM when the JIT is disabled (or rather, when you can't write to executable memory), but if it did it could be a neat way to write decently performant software for tiny systems with just some JavaScript "glue".
- schuay 8y ago> I'm curious if the runtime flag to enable JITless mode could also be enabled at compile time, removing the JIT compiler from the binary entirely. That could be really useful for projects where memory comes at a premium (and performance is not a major concern), like micropython but for JavaScript. Theoretically yes, but this is not implemented. It should not be too hard to drastically reduce binary size with a build-time flag. > I assume this also doesn't support WASM when the JIT is disabled (or rather, when you can't write to executable memory), but if it did it could be a neat way to write decently performant software for tiny systems with just some JavaScript "glue". Correct, wasm is currently unsupported. Interpreted wasm is possible in the future, but would likely be very slow.
- bodyfour 8y ago> It should not be too hard to drastically reduce binary size with a build-time flag. And then how portable would the code be? Would this be a path to running node on CPUs without JIT support? Or does it still have to mess with the calling convention at an assembly level?
- amaranth 8y agoAccording to another comment in this thread [1] the interpreter is actually generated by the JIT at compile time so no, this wouldn't let you run V8 on a CPU that isn't currently supported. [1] https://news.ycombinator.com/item?id=19379305 https://news.ycombinator.com/item?id=19379305
- mises 8y agoI keep wondering what the deal is with JS on the backend? Why does everyone love it so much? Let's not forget the 10-day design, dynamic typing (and weakly typed, compared with python), slowness, null vs. undefined, etc. JS is a scripting language; they're supposed to be for controlling the behavior of applications (i.e. browsers), not writing applications in and of themselves. Not to mention the dependency hell, NPM insecurity, etc. I see the purpose for limited use in websites, but definitely not the PWA or backend stuff. Can someone who uses it happily on the backend talk about why they like it and why it's good?
- atoko 8y agoHow is it slow? [Citation needed] The async model is easy to use so you get good performance before even optimize it. It comes out of the box with good json serialization/parsing, so that’s one less dependency. Not really sure where you’re coming from.
- curtis 8y agoPeople were using Ruby and Python (and before that Perl and PHP) on the backend in many cases. I think it's likely that those are the kinds of projects which are using JS on the backend now, while the Java and C# people are continuing to do their backends in Java and C#. One of JavaScript's big advantages over Ruby and Python was performance, both because the standard runtime is faster (JITing JavaScript turned out to be a lot easier than JITing Ruby and Python) and because its fundamentally asynchronous nature was a better match for webservers. And although NPM sucks in a number of ways, I've always found it easier to use than Python's dependency management.
- efdee 8y agoAnecdotal, but as developer who has done mainly C# for the last decade-and-a-half, I've switched to Node.js for -a lot- of my non-enterprisey work.
- abstractcontrol 8y ago> JITing JavaScript turned out to be a lot easier than JITing Ruby and Python Why was this the case?
- gok 8y agoJIT-less should really be the default on the web. The security implications of RWX memory are just so bad, and the amount of time that an exotic JIT meaningfully improves behavior of real world web browsing (as opposed to JavaScript benchmarks) is limited. For the rare web app where a JIT is critical, a simple "Do you really trust this web page to perform a lot of computation?" dialog would mitigate a lot of zero-click/one-click attacks.
- jayshua 8y agoAnyone know how common attacks that take advantage of the JIT technology actually are?
- landr0id 8y agoIt's been used consistently to get initial code execution on the PlayStation 4, iOS (for attacks involving just following a web link), and probably used pretty consistently other nation-state attacks but I have no real data to back this up. The Pegasus spyware for instance utilized a JIT attack in JavaScriptCore in Safari for the initial stage.
- olliej 8y agothe RWX memory in JSC has frequently been used as the start of full remote code execution, but has become progressively harder to abuse over the years (via W^X and in newer hardware PAC).
- hashseed 8y agoV8 already employs W^X, i.e. memory pages allocated for V8's heap are either writable or executable, but not both at the same time.
- gok 8y agoWell, except for WebAssembly. But even then, it's still fundamentally possible to hijack control of whatever changes the pages from RW to RX.
- 8y ago
- childintime 8y agoI'd like to try this on the desktop. The difference in memory usage is probably an order of magnitude. That could make my 2GB laptop usable again. I doubt I'll see the difference on any site I care about (no facebook for example). I remember when Java could make the browser totally unusable for several minutes. An interpreter would have avoided that.
- coder543 8y agothe difference in memory usage is 1.7%, according to the article.
- mbel 8y agoFrom the article: > Memory consumption only changed slightly, with a median of 1.7% decrease of V8’s heap size for loading a representative set of websites. What makes you believe is should be anything significant? After all the JIT-compiled code cannot be that large.
- olliej 8y agoJIT code for JS is /huge/ at the lower optimization levels, dramatically larger than an interpreter's byte code by something in the order of 10x - many megs of code are generated by relatively small amounts of JS code.
- firethief 8y agoIt still runs the bloated JavaScript programs, just slower
- xsmasher 8y agoThe "without allocating executable memory at runtime" means "without using allocating pages that are marked as executable," not "without allocating memory."
- ptx 8y agoJava did use an interpreter - it didn't get a JIT compiler until version 1.2. Java is slow for many other reasons as well.
- hajile 8y agoWhat about Proper Tail Calls? Duktape and XS support them. JSC has had them for years now too. That's a big feature to accidentally miss. You switch and then inadvertently blow your stack every now and then because v8 decided to remove their already implemented tail calls for no good reason (Lest we go down the road again, the "alternative syntax" proposal was dropped, so there's zero excuses aside from a deliberate violation of the spec).
- danbolt 8y agoAs mentioned in the article, this is interesting for game developers that aren't allowed to run unsigned code (eg: JIT). JavaScript is very popular the programming zietgiest and likely to be a language non-programmers are exposed to via the web. Part of me wonders if game engines would take to integrating it instead of Lua if designers might be more familiar with it.
- writepub 8y agoTHIS is another reason to complain to EU regulators [1], regarding Apple's unfair trade practices. Never before in the history of computing, has a company so blatantly suppressed the competition and gotten away with murder. V8 should not be the one needing re-architecture to meet anti-competitive iOS App Store rules, the rules need to make common sense, and treat the competition fairly. [1]: https://techcrunch.com/2019/03/13/spotify-files-a-complaint-against-apple-with-the-european-commission-over-apple-tax-and-restrictive-rules https://techcrunch.com/2019/03/13/spotify-files-a-complaint-...
- roryokane 8y agoWrong thread – this should have been posted on https://news.ycombinator.com/item?id=19377322 https://news.ycombinator.com/item?id=19377322.
- tuxxy 8y agoWow, this is pretty neat. We might be able to finally run more safe cryptography in the browser with constant-time guarantees (there are other concerns with browser-based crypto though).