7 ms·
The Emterpreter: Run asm.js code before it can be parsed
- mmastrac 12y agoHot damn, that's exciting. I prefer the asm.js approach over PNaCl because it lets browsers gradually move over to the standard rather than forcing a flag day. This solves the big issue, namely parsing that big, hot mess of raw JS. I hope we'll eventually see a proper bytecode spec with bidirectional assembly/disassembly w.r.t. JS (ie: more a transformation than an assembly spec) evolve from this effort, but it's obviously something that needs to happen after asm.js has had its time to bake. This, of course, assumes that browsers don't get AOT/background compilation to the point where it's no longer necessary to consider a bytecode spec.
- Kronopath 12y agoI actually really like the sound of this, not because of the stated benefits (though those are nice), but because it sounds like this would actually create a really good upgrade path to implementing a proper bytecode into browsers. I mean, with asm.js and the copious amounts of compile-to-Javascript languages available these days, Javascript is already becoming a de facto bytecode for the web. But it's always been a weird and uncomfortable hack done for the sake of backwards compatibility: a higher-level language hijacked to work as a compile target, simply because it's the only thing supported by browsers. If projects like this Emterpreter catch on, though, it allows for a smooth path to proper bytecode: for backwards compatibility, you have the Emterpreter read and execute the bytecode, but in other, more modern browsers you have the browser execute the bytecode directly. I think this would be an overall better approach than what we have now.
- hesdeadjim 12y agoYea I'm crossing my fingers that asm.js eventually leads to a real bytecode VM in browsers and Javascript simply becomes a language that targets it. For large applications compiling to asm.js (such as Unity3D) this experiment could provide significant gains in load time. Considering games usually spend their initial time presenting a menu, background loading of the fast-path makes a ton of sense.
- beagle3 12y agoOther than load time (which the emterpreter already makes great advances on), what other advantages does a bytecode carry? I don't see "load time" as a good enough reason for a revolution of this magnitude. Do you?
- jdmichal 12y agoBinary sizes, which would even further improve startup times, along with reducing network usage (and thereby hosting costs). GZip works just as good on binaries as it does on JavaScript.
- beagle3 12y agoThere are two things here: 1. [citation needed] and a [specific bytecode] needed. Details are everything: an uncompressed .dex file is comparable to a gzipped compile jvm class file; Also, with a specific bytecode in mind, if you compared minified+gzipped gs to gzipped bytecode, I suspect the difference will be small. 2. Regardless, the benefit of binary size is already provided, yesterday, with the emterpreter, without requiring any buy in from any browser vendor. So, again - what's the benefit, other than startup time (which might be solved in other ways) of a universal browser bytecode?
- iopq 12y agoIf you read the article, it downloads the full sized binary later. So actually the size with the emterpreter is higher
- beagle3 12y agoI commented on another thread, that I believe a future version of the emterpreter will generate the full JS back from the bytecode, thus eliminating that problem - it will increase the emterpreter size by a few tens of Ks, but that will probably by cached everywhere through CDNs. And even if it never does - it's politically close to impossible to agree on a universal bytecode, so it is extremely unlikely to happen. (Google already tried with PNaCl - if they can't pull it, I doubt anyone else can)
- estava 12y agoThe thing for now is that the asm.js "family" is riding on LLVM's back. More and more it's the LLVM that is becoming that VM people have longed for. It looks like LLVM is inching towards the JavaScript VM with every year that goes by. I read that Apple is using it for further JavaScript optimizations on the browser. LLVM already powers WebKit underneath right? So as things stand right now we have 2 popular "VMs" people really use. One is JavaScript since it's going nowhere. And the other is LLVM that is "free as in beer" for companies all over. JavaScript was secluded to the client. And LLVM was secluded to the backend. Now they are going to be marrying and having lots of children. :-)
- deleted 12y ago[deleted]
- astrodust 12y agoasm.js code doesn't have to be shipped in pure JavaScript form. It could come as byte code that's "uncompiled" into asm.js code before being thrown at the JavaScript runtime. A smart compiler could recognize the ordering priority and load in chunks sequentially, with hot code rolled in first, less frequently exercised methods last.
- stcredzero 12y agoNow they are going to be marrying and having lots of children. :-) Here's to hybrid vigor! So free software/open source is analogous to an open society without any arbitrary marriage restrictions, whereas closed source proprietary software tends to cause aristocratic inbreeding? I suspect that bastards also fit into the analogy somewhere.
- adrianm 12y agoLLVM is not a VM by any stretch of the imagination. It is an intermediate language for compilers whose primary utility is to provide a common target for code generation and optimization. LLVM's name is a misnomer.
- IshKebab 12y agoYou're thinking of that email that someone sent on a mailing list a while back about how LLVM isn't really a bytecode because it includes architecture-specific codes. It was a stupid email - you can make LLVM into an architecture-agnostic bytecode by disallowing those codes. Don't believe me?... https://developer.chrome.com/native-client/reference/pnacl-bitcode-abi https://developer.chrome.com/native-client/reference/pnacl-b...
- beagle3 12y ago> create a really good upgrade path to implementing a proper bytecode into browsers. I think that's very unlikely to happen. Instead, what will happen will be exactly "emterpreter"ing: There will be multiple bytescodes, and they will all ship with their own interpreters/compilers. If the emterpreter, instead of executing the bytecode, would generate JS code for it (and feed it into the JIT compiler if there is one), you'll get the best of all worlds -- bytecode format, top performance, perfect backwards compatibility. I suspect that's kripken's next move. Given that this is the case, why would someone want to shackle themselves to a specific bytecode format, which is practically impossible to get universally accepted? (This argument is supported by PNaCl; The technical problem is small; the political problem is huge). Work on JS optimization by all vendors is already extremely impressive and is not going to stop even if everyone agreed on some bytecode. Why not capitalize on it? What does a specific bytecode buy you beyond slightly shorter load times (which the emterpreter already gives a way to greatly reduce), and not having to pull the (essentially universally cached) emterpreter code? Because these two things, while nice, are not enough support for the revolution that a proper bytecode is.
- vidarh 12y agoAs with asm.js it wouldn't need to be universally accepted: It can "sneak in the back door" by continuing to work fine in browers that "just" supports standard javascript. If code using this method clearly labels the bytecode and interpreter and the part that background loads the "real thing", then implementations can opt to add whatever optimisations they like to speed it up as it stabilises . Doesn't matter if the bytecode changes, as long as it's labelled properly so the optimised versions falls back to just interpreting the JS if it comes across a version (of the interpreter/bytecode as a whole, or just a single opcode) it doesn't understand (or that the implementer hasn't seen a need to optimise). If the interpreter is guaranteed to retain a certain structure, it could be very easy to just "unroll" the interpreter loop and selectively JIT portions of the bytecode based on hotspots. You can optimise that a lot in a non-bytecode specific way by annotating the interpreter loop with assertions that grants extra guarantees (immutable bytecode; markers to indicate which code is only interpreter scaffolding; decoding hints; if you also tack on "labels" for each instructions, implementations can special case on individual instructions that "settle" while still handling new instructions/changes by inlining the interpreter code. > What does a specific bytecode buy you beyond slightly shorter load times (which the emterpreter already gives a way to greatly reduce) The full speed from the start; note the substantially lower speed for the first little part. And the example codebase is small compared to some of the things people want to run. I think we sort-of agree. I don't necessarily think there's a reason to specify a standard bytecode, exactly because this approach could conceivably be extended to effectively give us a "mostly standard" bytecode with the freedom to continue to change the format without a lengthy committee approach, because there's a demonstrably viable fallback.
- TazeTSchnitzel 12y ago> I actually really like the sound of this, not because of the stated benefits (though those are nice), but because it sounds like this would actually create a really good upgrade path to implementing a proper bytecode into browsers. We already have a proper bytecode with several high-performance implementations that's supported on virtually every platform, which works as an excellent compilation target for both dynamic and static languages. It's called JavaScript. Now you might say JS is bloated! But that's only if it's not gzipped or minified. Make a "proper bytecode" and you gain absolutely nothing except losing the wide support JS enjoys.
- hetman 12y agoExcept you gain better startup speed which was kind of the premise of this article.
- TazeTSchnitzel 12y agoTrue, that's maybe the only case where there's an improvement. But it's a one-time cost (the browser can cache the compiled version), and switching to bytecode is not necessarily the only way to improve performance. For example, a JS parser specially optimised for asm.js.
- zimbatm 12y agoNote that cache is not always a solution. Cache is a terrible answer for first-time user experience. A lot of stuff on the web is loaded outside of the cache too for various reasons. Caches gets flushed.
- hetman 12y agoMy suspicion is that it will never be possible to parse asm.js as quickly as bytecode simply because it is structurally different. However, a quick search does suggest there are still some improvements possible in Firefox to speed things up somewhat.
- esailija 12y ago
- leeoniya 12y agoa bit OT, but one thing i always wondered is, can't we extract inferred type information from the JIT after running plain JS code through 1M cycles and then compile that to an asm.js variant?
- munificent 12y agoThis is effectively what JavaScript VMs already do and have done for years. They compile to unoptimized machine code that has a bunch of hooks to monitor the types that flow through the code. After a while, if a chunk of code is identified as "hot", a second-stage compilation kicks in. The code is recompiled to optimized machine code that takes advantage of the types that it previously saw the code use (with fallbacks in case those assumptions later fail).
- leeoniya 12y agoyes i understand that. my question is, can that inferred type info be used to output the optimized bytecode as asm.js so that it can be included right away. like statically compressed .gz assets (pre-optimized). it would effectively make a js -> asm.js compiler
- aardvark179 12y agoPossibly, but the types by a VM are rarely guaranteed to be completely accurate (some traps will be included in optimised code to capture the cases where types may not be as expected). They may only be true for the particular input data, other other libraries used, or stuff like that. Using previous runs to inform the JIT of expected types is entirely reasonable though, and think various JS implementations already do this.
- leeoniya 12y ago> some traps will be included in optimised code to capture the cases where types may not be as expected none of that should matter. if the resulting JIT'd code is faster with the traps than the plain js without them, so be it.
- flohofwoe 12y agoI think this is the first emscripten feature which I don't "get", e.g. not fully understanding the motivation behind it :) Firefox AOT compile time is great, and nothing at all compared to the time it takes to download the code. The real art lies in getting the actual emscripten compiled executable small, not because of emscripten, but because of C++'s tendency to bloat the executable size if one isn't really careful. Also, clang and emscripten's code generation passes have very aggressive dead code elimination, but there can be wrong decisions on the game engine architecture-level which can cause the inclusion of code that might never be called. A native executable that's several dozen MByte's big is a bad thing on any platform, it just doesn't appear as such a problem if it is a part of a 50 GByte game download. To come to and end, I think an emscripten client of up to 5 MByte (gzipped) doesn't really require a fix like emterpreter for its startup time(?), and it's perfectly possible to fit a full 3D game client into such a size with a little care about size optimization. [edit: fixed a formulation which sounded like code bloat can be blamed on emscripten instead of user-code]
- estava 12y agoI believe asm.js has been trying to counter concerns people might have when considering using it. Also, it could be that some companies may be trying to join efforts in trying to further the asm.js adoption, like Microsoft adding more support for asm.js. So it could be that they are planning ahead much more now. The asm.js effort could be seen as moving on from a prototype to an actual feature companies may depend on in the soon future. Also, what makes people more cautious about performance concerns is that mobile network and hardware are still catching up to what people have on the desktop. And since about 8 years ago, mobile has been a big opportunity for many companies, which means that the desktop has been taken for a ride by the mobile devices and that is not going to stop.
- andrewchambers 12y agoImo a stackbased bytecode has far better code density, which is probably pretty good for browsers.
- CHY872 12y ago
- im3w1l 12y agoAfter we have evicted Java from our browsers and turned Javascript into the new Java, what have we gained?
- jerf 12y agoIt isn't the new Java, it's the new JVM, and the answer is, "choice".
- reasonish 12y agoChoice? In what sense? The JVM is a ridiculously good VM, with tons of languages that compile to it. Why are we reinventing the wheel?
- stcredzero 12y agoThere is a tendency for history to repeat itself in programming, since, as Alan Kay put it, programming is "not quite a field" as it lacks a proper sense of its own history. So going by this, I predict that VM vulnerabilities are going to creep into the JS ecosystem, put there in the name of optimization, much like the "Use After Free" vulnerabilities in the JVM for Android. I sincerely hope I will be wrong!
- jerf 12y agoChoice of language to compile into the VM. As for why not the Java VM, my guess is that the browsers are staggeringly enormous piles of C++ code and trying to integrate a Java VM into it would probably be insanely difficult, and anything other than pure 100% integration, too slow to use. It is probably literally easier to continue with the already-integrated JS VM and improve it up to JVM-esque quality than to try to graft the JVM into the browsers that exist today. Or somebody would have already have tried since nothing would have prevented JS from already running on the JVM, if that were feasible; asm.js is actually independent of this question when it comes down to it.
- icedchai 12y ago
- jerf 12y agoAs I sometimes see wmf say, "as predicted by prophecy:" https://news.ycombinator.com/item?id=6923758 https://news.ycombinator.com/item?id=6923758
- hobo_mark 12y agoAlso, https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript https://www.destroyallsoftware.com/talks/the-birth-and-death...
- jerf 12y agoI actually acknowledged that in the version of this I posted 4 days ago: https://news.ycombinator.com/item?id=9071064 https://news.ycombinator.com/item?id=9071064 However, he has JS hanging on for longer than I bet on... once asm.js gets a good DOM binding I expect the explosion of language diversity to take about two years, tops, and for it to rapidly become clear that JS is now just another way of accessing the DOM. I think there's more pressure built up there than people realize, because right now there's no point in thinking about it, but once it's possible, kablooie. Node's value proposition, IMHO, is in some sense correct, but backwards; it's not that we want to write in Javascript on the server, it's that we want "client language = server language"... and once there's no longer a technical handcuff pinning the client side of that equation to Javascript, it will not take that long for it to no longer be Javascript. It is not an impressive language, even within its own 1990s-style dynamic language niche. (I think this is not because it's "bad", but because it has been developed in this really terrible multiple-vendors-that-actively-don't-want-to-cooperate way for most of its lifetime. It's gotten past that, I think, but during those decades all the other scripting languages were marching right along. None of the other languages could have survived such a process and gotten to where they are today, either.)
- Touche 12y agoGC-ed languages are going to have to include the GC which I doubt can compete with JavaScript. No one wants to write CRUD apps and manually manage memory. I don't see asm.js being used outside of games.
- AshleysBrain 12y agoThis is very cool, and great to read more interesting research from Mozilla. However in this article I notice something curious: normal asm.js kicks off and shortly after reaches top speed by around 700ms. emterpreter gets going by 200ms, but takes another 1200ms to reach top speed by 1400ms. Why is it not another 700ms? Isn't it just doing the same work as asm.js but in the background while running with emterpreter? Non-blacklisted emterpreter looks slow enough (5fps ish on that graph?) to simply not be useful for some use cases, like a game engine - it's not going to be remotely playable like that. Therefore emterpret => asm.js actually significantly increases the startup time. Playable by 1400ms is worse than playable by 700ms. But I guess this is all preliminary and improvable though!
- azakai 12y agoThere are a few reasons why full speed is reached later when starting up in the emterpreter and swapping in asm.js later: * Compiling asm.js can use multiple CPU cores, so doing just that is faster than doing it while the emterpreter is running on (at least) one core. * I believe, but am not sure, that compiling on a background thread is done at lower priority than stuff on the main thread. * Swapping asm.js code in can only be done in between frames. At 10fps for example, that means around a 100ms delay just for that, and possibly more depending on the state of the browser's event queue.
- AndrewDucker 12y agoSo, how long until someone gets the JVM or CLR running inside the browser using asm.js - and then reopens the world of running Java/C# in the browser. Only this time without plugins.
- TazeTSchnitzel 12y agoWhy waste time and bytes on an extra VM, when you can just compile Java or CLR bytecode to JavaScript?
- AndrewDucker 12y agoBecause the behaviour of the JS VM and the CLR VM is very different?
- rafaelferreira 12y agoQuite similar to tiered compilation on the JVM
- kelvin0 12y agoYeah, maybe if we could compile to some byte code and simply download a VM to compile once and run everywhere ... hmmm where have I seen this before?
- GeorgeHahn 12y agoIs it straightforward to reference a separate compiled library from an Emscripten binary? Seems that caching commonly shared dependencies could be a good way to cut down on size and parse/compile time.
- al2o3cr 12y ago"Oh wow, wouldn't it be great if browsers had a bytecode interpreter in them?" Two words: "Java applets".