JIT vs Inline C/JS EspruinoCompiler?

Posted on
  • I'm not sure if here is good place or github issue is better place. I've noticed there is beginning of JIT feature merged in this commit

    There is also old closed issue here https://github.com/espruino/Espruino/iss­ues/73 describing some pluses/minuses.

    There is also the inline C and JS compiler https://github.com/gfwilliams/EspruinoCo­mpiler described here https://www.espruino.com/InlineC and https://www.espruino.com/Compilation

    When I saw the JIT is a Kickstarter goal I was curious how this could fit together.
    Looks like current implementation starts from scratch with doing the JIT directly on the device.

    I just wonder is it really needed to have this on the device? What is target device regarding available flash/ram/cpu speed for this? I'd guess even bangle 2 could be too slow and small for this to be an improvement - I fear the compiler would always be too simple and possibly slow.

    Couldn't the inline server based compiler be improved so that it would run as part of some minification phase? If we are talking only Bangle apps stored in repo maybe this could be done on the server somehow automatically so the loader would load already compiled bits to the device?

    I know it is not exactly JIT in the traditional sense but maybe it could offer very similar JIT like flexibility without bloating the device firmware and burning CPU time?

  • I think there are a few big drawbacks with server-based stuff:

    • It's heavily tied to the firmware version since it uses internal functions. Sometimes if you had uploaded apps they would just lock up the watch if you updated your firmware
    • It needs an internet connection, which people always complain about
    • It'll thrash my server :)
    • Trying to keep server + firmware versions in sync is going to be a real pain

    As you've noticed I've been trying multiple options, but so far none of them have been that great, and it's always felt like a bit of a hack. I've got a company using the Espruino firmware in some custom watches of theirs, and they're actually avoiding the JIT even though maybe they could do it because it's just an extra layer of difficulty. However the JIT compiler in the firmware seems promising to me... So far it only uses 4kB Flash and even now there's a 2x speed improvement.

    Normally Espruino is pretty slow, but there's no one big time hog. I guess roughly (this is just a guess) time is spent:

    • 30% Lexing the text itself
    • 15% Parsing
    • 40% Variable lookups
    • 15% MathsOp (actual maths operations)

    Even if we use GCC and some optimisation, we're still going to have the Variable Lookups and MathsOp in a lot of cases, so it may not actually be that fast.

    By contrast, if we use JIT on the device, we can actually get the address of built-in functions and can call them direct, so in many cases we can skip the expensive variable lookups. The JS compiler on the server does this in one or two small cases where the JS function is be exposed (eg digitalWrite) but it doesn't do it for many at all.

    The reality is that most of the code is just stringing together calls to built-in functions (jsvUnLock,jsvMathsOp,jspGetVariable...,­etc) so actually simple JIT on the device can do that pretty well. Obviously if we're at the point where we're really compiling the JS into C that's dealing with ints and doubles directly then GCC will be a lot faster, but I don't think in a lot of cases we're really going to be doing that.

  • Thanks for answer, looks like it might be still worth it then even if being simple. The variable/function address lookup and possibly other stuff known only at runtime cannot be done on server indeed.

  • Speeding up variable lookup (and jump address lookup/'calculations') promise the most. Was there ever a thought to have something (changed) in the source that updates when the variable has been looked up? Of course that works only when the code is in RAM and a in/re-direction table that makes GC transparent? So it is not really a JIT compiler but more so an accelerator that does a lot of good especially in loops - similar to what pre-tokenzing does. An accelerator is not JIT compiler nor main stream, but Espruino isn't either. Such an accelerator would be unique and - after all - fit the uniqueness of Espruino (JS engine).

  • Was there ever a thought to have something (changed) in the source that updates when the variable has been looked up?

    You mean to replace the variable name with something else like a token saying 'argument1' (for instance)?

    I had wondered about that, but actually part of me was thinking I could just have a cache for single-character variable names like a...z. Then minified code which uses those pretty much all the time would benefit greatly.

  • Was thinking more along the lines of adding a ref pointer to variables. Of course this is not footprint friendly, but preserves source.

    Your replacement approach triggered another thought: in dbs, often a local index is built to save space. In code it would be a symbol index to keep the name / preserve the source but having a space to replace it on first run w/ a pointer into variable value space, that holds the value but would also hold also a pointer back to the index entry / name.

    I'm sure you already have though of many things, wandered down alleys... and kept sticking to what Espruino interpreter has come to this day. So no urgency to this.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

JIT vs Inline C/JS EspruinoCompiler?

Posted by Avatar for fanoush @fanoush