[HN Gopher] ChowJS: An AOT JavaScript engine for game consoles
___________________________________________________________________
ChowJS: An AOT JavaScript engine for game consoles
Author : matpow2
Score : 110 points
Date : 2021-09-16 12:02 UTC (10 hours ago)
(HTM) web link (mp2.dk)
(TXT) w3m dump (mp2.dk)
| supermatt wrote:
| Just wondering aloud: Due to issues like no JIT on iOS, do
| platforms like react-native use AOT JS compilation? If not, why
| not?
| joshum97 wrote:
| Here's the relevant section: > In most cases, React Native will
| use JavaScriptCore, the JavaScript engine that powers Safari.
| Note that on iOS, JavaScriptCore does not use JIT due to the
| absence of writable executable memory in iOS apps.
| kiliancs wrote:
| Since recently, it's possible to use Hermes
| https://reactnative.dev/blog/2021/03/12/version-0.64
| whizzter wrote:
| iirc the Hermes has AOT'd bytecode but not real native
| execution, from what I read they couldn't get the
| performance up enough to offset the size cost vs their
| bytecode and for many regular React-native apps absolute
| performance isn't as important as not being waaay too
| bloated.
| ridiculous_fish wrote:
| I am reading correctly that this makes deliberately unsound
| optimizations? For example it seems to assume that `console.log`
| or `print` will never change, and there's no deopt check?
|
| _edit:_ I missed the section titled "Configurable
| optimizations" where it addresses this.
| whizzter wrote:
| Not 100% on how they do everything but remember that this is
| mostly a tool for porting JS games, soundness isn't a top
| priority really, rather running real-world game code is and
| that code doesn't always do too much funky stuff.
|
| As such I'd guess that they have an initial pass that just
| looks for bad patterns (eval,etc) and totally ignores
| optimizing those, next up you look for other things (like
| writes to named properties, if nobody ever writes to a .log
| property it's probably fairly safe since the main task is AOT
| compiling code). There's probably a switch-es to enable a safer
| mode for various things where a fast-path is the default but
| fallbacks would work,etc.
| ridiculous_fish wrote:
| Agreed, there's a lot of optimizations you can unlock if you
| ignore JS misfeatures like modifying Array.prototype. But
| it's important for compilers to be precise about the
| semantics they implement. I just saw the section about
| enabling checks for when the assumptions are violated, that's
| a good thing to have.
| puppet-master wrote:
| Is this open source?
| eyelidlessness wrote:
| This is super interesting, and something I've been thinking about
| from a different (non-game) angle: build tools. It's cool that
| ESBuild/SWC (and coming soon Bun[1]) exist as fast native
| compilers. But most of the rest of the JS tooling world is
| written in JS, and often performs expensive (and frequently
| redundant) parsing to AST.
|
| This code is often very static, its biggest performance hit is
| usually cold start before the JIT. And it's increasingly common
| that the code is written in TypeScript, which has tons of static
| analysis potential.
|
| It would make a ton of sense to have a generalized AOT compiler
| for these tools. And it would be good for the ecosystem, allowing
| higher build performance overall while preserving portability
| between underlying bundlers.
|
| I know there's a get in touch section (which I'll avail myself
| of), but if the author's reading I'd be curious if this is a use
| case you're considering.
|
| 1: https://bun.sh/
| Leszek wrote:
| This is very cool. The splitting of logic between startup/warmup
| and execution is crucial here, to be able to get all that type
| inference and those speculative optimisations without hitting the
| limits of static analysis of the JS code. I wonder if the
| speculative optimisations could be further strengthened by taking
| advantage of e.g. Typescript type annotations.
| Leszek wrote:
| Though, I don't see any discussion here on failed speculation /
| deoptimisation, and I do see discussion of disabling individual
| optimisation passes. I guess the generated optimized code
| assumes that all the speculative types collected during startup
| stay stable? This makes sense in a highly controlled
| environment like a game engine, though it makes the project
| less amenable for general purpose use (which is fine).
| sillycross wrote:
| Interesting post. Seems similar to the approach of HPHPC for PHP,
| where the code is first run offline in a simulated environment to
| collect type information, and then use these speculations to
| generate static-typed code ahead-of-time.
|
| Would be interested to see a performance comparison with V8 JIT
| (instead of V8 interpreter).
| divs1210 wrote:
| AFAIK Graal native-image also does something similar.
| chrisseaton wrote:
| For Java, yes. They're working on JavaScript and Ruby etc,
| but not sure it's quite there yet.
| sillycross wrote:
| Java is static-typed already and only has a low degree of
| dynamism, so the importance of doing so is much less (only to
| reduce the initialization time I believe).
| chrisseaton wrote:
| There's a lot of interfaces and virtual calls in Java. Not
| sure if you're considering that dynamic or not, but I would
| would. Graal does some pretty intense whole-universe
| points-to analysis which enables monomorphisation,
| devirtualisation, scalar replacement, etc.
| CountHackulus wrote:
| Java is yes, but the JVM runs other things and things like
| JRuby use the JVM bytecode for invoke_dynamic. There were a
| few things rewritten to use that bytecode from what I
| remember but it's been a while since I've worked in that
| area.
| whizzter wrote:
| Fun to see, I literally wrote my thesis on the same subject a
| bunch of years ago (Sadly didn't have an excellent option like
| QuickJS as a base things on back then).
|
| First off, unlike many AOT JS compilers that has gotten exposure
| in the past this one actually seems realistic. The performance
| numbers don't see overly fantastic so they actually DO seem to
| implement JS properly rather than some overly optimisic JS-alike
| thing (the fact that they have QuickJS as an underlying base is
| also a plus).
|
| So for porting this is probably a pretty good choice and should
| produce something working, the bad part is that even if
| performance is better than a plain interpreter it'll suffer
| compared to what you can get with a proper JIT unless you tune
| your code heavily for the constraints of a compiler like this. I
| hope they have some seamless option for moving code to C/C++ (so
| you can run some perf critical stuff in C via WASM on the web and
| have an easy way to move the code to regular native code on the
| ported platform).
| [deleted]
| jarrell_mark wrote:
| Agreed, being able to compile to webassembly would be really
| nice.
| fabiospampinato wrote:
| Super cool! I don't really work on anything that needs to be
| executed in a no-JIT environment, but I wonder if something like
| this could be useful in a regular browser environment too.
|
| Like there must be a way to throw enough compute at the problem
| and get back faster code, I'm thinking with an AOT step code
| could be faster on cold executions and perhaps warm up faster too
| and/or have a bit lower memory usage? Perhaps TS types could be
| leveraged too. IMO that's an under explored area.
| fwsgonzo wrote:
| Very interesting and thanks for doing this! This is exactly what
| I need for a special case in an environment where changing page
| tables is not allowed. Static executables with AOT optimized code
| is preferred, for performance reasons. Thanks for doing this!
|
| Is there a way to interface with the C API from JavaScript now? I
| am very familiar with QuickJS already so I know that providing
| functionality is very easy already, but I was wondering since you
| compile to machine code if it would make sense to allow doing it
| the other way too?
|
| Another peculiar thing on my wishlist is the ability to have a
| leaky GC. That is, a GC that doesn't do anything at all. In my
| special environment there's a phase where the whole environment
| is run at the highest performance possible and then immediately
| dropped. What actually happens is the env is reset to an
| "initialized" state after processing ends.
|
| Also, does it support Linux? I think that it does because many
| consoles are "based" on that these days, although perhaps that is
| abstracted away.
| gavinray wrote:
| I'm also curious about C API access from JS.
|
| One thing I was hopeful about when I first read of Deno was
| ability to interop with native code by making FFI/bindings
| available in Rust, and then package to a native binary.
|
| That didn't pan out, and I don't blame them, but I'm still
| hoping to be able to write native executables/shared libs in
| TypeScript and use C FFI.
| reilly3000 wrote:
| This is way outside the realm of my expertise, but I'm
| curious how a FFI would be better than just calling
| child_process.exec for accessing a C binary. I suppose that
| may not be efficient inside of a game loop, but I don't
| understand why, so long as it was done within a promise.
| nvmletsdoit wrote:
| Technically cool.
|
| JS should be erased from the earth, tho. ( Expecially for gaming
| :'D )
| capableweb wrote:
| That people can comment on random stuff on the internet is
| technically cool.
|
| But your post is so low quality that I'm wondering that maybe
| we shouldn't be able to.
|
| Try to actually write your point of view instead of just
| farting out words with your keyboards. Let's debate and talk
| JS, if that's what you want, but right now you're not setting
| things up for debate, your are trying to start a flame war.
| [deleted]
___________________________________________________________________
(page generated 2021-09-16 23:01 UTC)