A snapshot contains everything needed to fully initialize a new Isolate, including language constants (e.g., the undefined value), internal bytecode handlers used by the interpreter, built-in objects (e.g., String), and the functions installed on built-in objects (e.g., String.prototype.replace) together with their executable Code objects.
This sounds suspiciously like the Smalltalk image. The Smalltalk undefined value was involved in some paradoxes, therefore it couldn't be completely defined/instantiated declaratively.
I wonder if the (de)serialization mechanism used here could be re-targeted in a manner resembling the Parcel technology developed for VisualWorks Smalltalk? Basically, the runtime state of an application could be serialized into a "parcel," which could then be rapidly deserialized and more or less directly injected into the runtime image.
> The Smalltalk undefined value was involved in some paradoxes
Could you elaborate on this? Or provide some references? This sounds interesteing but when I tried DDG and Google for "smalltalk undefined paradoxes" the results were not exactly satisfactory.
nil was the sole instance of the class UndefinedObject, which was a subclass of Object, whose superclass evaluated to nil.
Another paradox: Every instance has a Class. A Class is also an instance of a Class. That object also has a Class, and that instance of a Class also has a Class, and so on. It was turtles all the way down.
I have thought for awhile, and continue to think, that developers avoid "premature" optimization too fiercely. Yes, there are diminishing returns with optimization effort, but too often people interpret "avoid premature optimization" as "never optimize unless it feels slow, and even then only if it feels slow when it's the only thing running. Otherwise, blame everything else that is running first!"
"Zero cost abstraction" is like a sarcastic joke at this point in web development. If you pull up performance comparisons for web backends, a lot of the popular ones based on interpreted languages are absolutely abysmal when compared to c++ or Java code (Node is a good example). Many definitely have streamlined development workflows and have nice, high-level abstractions, but at a cost to performance. I don't mean that Node is useless or something, sometimes it makes sense, but it still forces you to compromise.
Front-end frameworks are even worse. A lot of older (but not "ancient") PCs are unusable on the modern web because of poorly-optimized JS or Adobe Flash (a decent portion of this issue is also due to the inherent inefficiency of JS and Flash as well). Fortunately, Google has been making strides with V8, Mozilla did awesome with Firefox "Quantum" and everyone is slowly ditching Flash, but performance still seems to be an ever-present issue.
I think that's pretty close to what they're doing, really. Though usually COW refers to doing things on a page by page basis, which probably would not be as effective (since it would copy entire pages, when only a little was needed, so unless you were careful to put related function close together, you'd copy a lot more of the heap than you really want).
You're probably right though. I bet they end up closer and closer to that. Possibly even sharing pages that can't be modified, like code objects. That's what the last sentence or two seems to allude to. Eventually, they'll pretty much be reinventing shared libraries for the JavaScript world. Not that that's a bad thing.
This sounds suspiciously like the Smalltalk image. The Smalltalk undefined value was involved in some paradoxes, therefore it couldn't be completely defined/instantiated declaratively.
I wonder if the (de)serialization mechanism used here could be re-targeted in a manner resembling the Parcel technology developed for VisualWorks Smalltalk? Basically, the runtime state of an application could be serialized into a "parcel," which could then be rapidly deserialized and more or less directly injected into the runtime image.