5 ms·
I've brought this up before, but I wonder if a "JS constraint spec" could be added to the JS standard that guarantees against this sort of (already uncommon) dy
by brundolf 6y ago
I've brought this up before, but I wonder if a "JS constraint spec" could be added to the JS standard that guarantees against this sort of (already uncommon) dynamic behavior in certain cases, so that code can be more aggressively optimized when possible
If you're already using TypeScript to constrain your code, why couldn't it generate interpreter/compiler hints?
These could take the form of a language-agnostic metadata file, similar to source maps, that optionally ships alongside the JS bundle
Edit: Several people have misunderstood, so I must not have articulated this well. What I meant was not a new/stricter subset of JS that forbids certain dynamic behaviors across the board. What I'm talking about is having TypeScript (or otherwise), which knows things at compile-time about how specific pieces of code are and are not called, manifest this information in a way that V8 can digest and act on directly, for that specific codebase. V8 already tries to guess this information and uses it to decide which things to optimize and how, but it's treating the JS bundle as a black box even though in many cases, an earlier stage of the pipeline already had this information on-hand and threw it away.
In addition to being more granular, this (like TypeScript itself) would allow parts of a codebase to continue being fully dynamic while other parts are well-constrained.
- matsemann 6y agoThere's already "use strict" that does some of this to enable optimizations and other stuff. Maybe it should be even stricter or something similar could be used. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- brundolf 6y agoRight but I'm talking about very specific hints for one codebase "Function X will only ever take two arguments, they will be of types Y and Z" "This object will only ever have these properties; it will never have properties created or deleted" "This prototype will never be modified at runtime"
- hajile 6y agoIt still has to verify that those assertions are true in practice. Any random person at the console can call a function and pass whatever they like. The only real way to make that work would be a new `<script type="typed-module" />` variant that implemented a subset of JS in a typed environment. My guess is that this could happen in the future, but everyone is watching Typescript as a testing ground to find exactly what works, what doesn't, and what works, but isn't desirable.
- brundolf 6y agoThere's already a mechanism for bailing out when optimization assumptions are violated; they could be made more eagerly but retain the ability to degrade
- crazypython 6y ago> "This object will only ever have these properties; it will never have properties created or deleted" Already in JavaScript: Object.seal(object) > "This prototype will never be modified at runtime" Already in JavaScript: Object.freeze(myPrototype)
- phpnode 6y agoThe V8 team experimented with "Strong Mode" which was approximately this - a fast subset of JS [0]. The experiment was ended [1] [0] https://docs.google.com/document/d/1Qk0qC4s_XNCLemj42FqfsRLp49nDQMZ1y7fwf5YjaI4/view https://docs.google.com/document/d/1Qk0qC4s_XNCLemj42FqfsRLp... [1] https://groups.google.com/g/strengthen-js/c/ojj3TDxbHpQ/m/5ENNAiUzEgAJ https://groups.google.com/g/strengthen-js/c/ojj3TDxbHpQ/m/5E...
- brundolf 6y agoFrom a quick glance this looks like a further subsetting a la strict mode, which isn't really what I meant I clarified in another thread, but what I meant to convey is a way of giving very specific hints about specific pieces of one codebase: "Function X will only ever take two arguments, they will be of types Y and Z" "This object will only ever have these properties; it will never have properties created or deleted" "This prototype will never be modified at runtime" This could guarantee ahead-of-time that certain optimizations - packing an object as a struct instead of a hashmap, for example - can be done, so that V8 doesn't have to spend time speculating about whether or not to JIT something
- k__ 6y agoIsn't that what asm.js did?
- brundolf 6y agoMaybe from a certain perspective. But it worked by conforming the bundle to a particular subset of JS that the authors knew to be optimized, instead of expressing information to the interpreter outright. That seems like a comparatively limited channel for communication.
- jacobolus 6y agoFrom what I understand, in Safari at least they tried to make many of the optimizations general. So if you use asm.js-style type indications in your code even without following the full spec, you might see some performance benefit. I have sometimes found a speedup when adding apparently an superfluous |0.
- DDSDev 6y agoIn general I think this is an interesting idea, but I feel like this has a lot of overlap with asm.js and WebAssembly. With this standard we would have standard dynamic JavaScript as the world knows it today, a restricted subset ('constraint spec') that is still designed for human readability/writability, and then asm.js/WebAssembly, which would not be written directly but instead would be an output of code written in other languages. Programmers will want interoperability between all of these paths, and that is a lot of complexity for these engines to manage.
- deleted 6y ago[deleted]
- Zababa 6y agoThis may be a bit of a reach, but there's AssemblyScript [1], which is a compiler from a strict variant of TypeScript to WebAssembly. Since technically V8 is also a WebAssembly engine, porting some part of your codebase from JS/TS to AssemblyScript could improve your performance. [1]: https://www.assemblyscript.org/ https://www.assemblyscript.org/
- astrange 6y agoDoes V8 actually run compiler optimizations on WebAssembly? I thought it came pre-optimized and it just executed it. My impression of WASM was it's ok but it's not very expressive for an assembly language - at least it has integers though. gcc.godbolt.org doesn't give you any library functions for it, even memcpy(), so I couldn't do a lot of testing.
- Zababa 6y agoI think it does. Here's an article introducing Liftoff [1] with the relevant parts: > With Liftoff and TurboFan, V8 now has two compilation tiers for WebAssembly: Liftoff as the baseline compiler for fast startup and TurboFan as optimizing compiler for maximum performance. > Immediately after Liftoff compilation of a module finished, the WebAssembly engine starts background threads to generate optimized code for the module. [1]: https://v8.dev/blog/liftoff https://v8.dev/blog/liftoff
- RReverser 6y ago> already uncommon It's definitely not uncommon though. Just to provide one example: how often do you use all the arguments to `.map` callback? Usually you'd write something like `arr.map(x => x + 1)`. However, to spell out all the arguments you'd have to write `arr.map((x, i, arr) => x + 1)`. And there's tons of other functions like that in stdlib or 3rd-party libs that people use without passing or accepting all the args. That's why this optimisation is so useful.
- skrebbel 6y agoThis is exactly the kind of thing that TypeScript generated JS could help optimize. Because tsc can see that this `map` call is, in fact, Array.prototype.map, it can deduce that the lambda will get sent three values. It could generate dummy arguments for that in the JS output. It could just as easily generate a hint to the same effect in some constraint file as the GP suggests.
- ash_gti 6y agoI think this is what WASM is meant to achieve. It allows for much more precise semantics without needing to parse an AST.
- WorldMaker 6y agoRegarding your update: I think there is some interest in passing TS type annotations on to the JS VM/JIT, but my impression is still that TC39 is rather shy on the subject after the still not entirely healed scars of ES4. I know I would love to see TS type annotations made syntactically valid if semantically ignored (ala Python's type annotations PEPs), simply to make sure valid TS runs in the browser without a build step to better unify the "subset". It wouldn't be a far shot from there to seeing at least some small type annotation hints support in JS engines. Though I definitely understand the concerns and wariness that anything done there would be very engine-specific and in danger of lock in for the web. I heard there were some V8-specific prototype attempts from some of the Deno developers, but I don't recall how far those attempts got or if they had anything in the way of results.