denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
97.77k stars 5.38k forks source link

Discussion: export and load custom snapshot #1877

Open kevinkassimo opened 5 years ago

kevinkassimo commented 5 years ago

Background: v8 snapshots. Deno currently already uses snapshots for the TS compiler and main API for faster startup. We might be able to extend the behavior so that the users could create and load their own snapshots.

Something like

deno --snapshot ss.bin mod.ts
deno --use-snapshot ss.bin main.ts

Like AOT compilation in a way. Might be useful for developers who don't want to work with the Rust crate (and less overhead than using generated JS bundles)

ry commented 5 years ago

I think the major issue it to get multiple snapshot working (ie we have the internal Deno snapshot to load and then need to load the external one)... there’s a v8 gn flag called v8_multi_snapshots which can be turned on - maybe that’s all that needs to be done. I think the first step would be to get a demo working in libdeno_test first.

I’m generally in favor of this plan

afinch7 commented 5 years ago

I can't see why multiple snapshots would be needed unless you want to apply your snapshot over the existing deno one. You would likely need to regenerate your snapshots for new versions anyways, and as I found out working on getting deno running on arm, snapshots generated with one v8 binary don't always work with others.

kitsonk commented 4 years ago

This is still really hard, as we have been unable to successfully get ES module loading and snapshots working as well. This likely ends up in the "too hard" bin.

ghost commented 3 years ago

A snapshot would be more interesting into the compilation phase. If all the code, including the dependencies, is bundled into one single file for distribution, then snapshotting the bundled file might be possible independently of the ES module loading issue.

lrowe commented 2 years ago

I think it would be really useful to provide a snapshot facility for Workers. This would potentially allow for running individual requests in isolated workers efficiently. While I've not tried it, the Node isolated-vm native extension has some (caveated) snapshot support. https://github.com/laverdet/isolated-vm#new-ivmisolateoptions

stephenh commented 2 years ago

Disclaimer I'm sure this is too naive to be useful, but my "if I could wave a magic wand" dream would be to have deno auto-manage a "each time your dependencies change, you get a new v8 snapshot with all dependencies pre-loaded" feature.

Such that then running project-level commands like tests/scripts/etc. would automatically use this snapshot & not have to re-parse/re-eval every single *.js / *.ts file in my (invariably many) dependencies.

Per the reality of getting ES modules/etc. to work in V8 snapshots is just hard/likely impossible, that totally makes sense; my again probably too naive musing is that, since deno is rebooting the npm ecosystem anyway, could there be some restrictions added that this "auto-dependency snapshotting" feature only works if your dependencies agree to some ideally not-too-bad list of restrictions (i.e. around things they can do at module load time)...

With the idea that, if the auto-dependencies-snapshot feature made particularly large projects' ergonomics dramatically better, then the community/ecosystem might opt-in to the restrictions.

Granted, I really have no idea what I'm talking about, and it's probably either not really possible, or water-under-the-bridge at this point given the deno ecosystem is already way paste its original "reboot everything" phase.

Anyway, feel free to ignore me; thanks!

frank-dspeed commented 2 years ago

@stephenh i am implementing that at present i came to this issue because i wanted to watch the current state in deno.

it is a feature of my project called stealify/b8g which stands for big engine it is a v8 fork designed to run at ring 0 as kernel replacement and it implements snapshots as module system in fact a v8 snapshot is not as complex as most people think i am a long time v8 engineer i will backport that to deno as crate

it is in general not as hard to implement and incompatible as all think i will try to explain it more simple a snapshot is binary and so needs to get compiled on the same cpu architecture at last so x86_64 or x86 with x86 libs using 64bit pointers compatability. armv7 8 and so on i guess you get it.

the design of a snapshot is more simple then you think src/snapshot/snapshot.cc

 // Snapshot blob layout:
  // [0] number of contexts N
  // [1] rehashability
  // [2] checksum
  // [3] (128 bytes) version string
  // [4] offset to readonly
  // [5] offset to context 0
  // [6] offset to context 1
  // ...
  // ... offset to context N - 1
  // ... startup snapshot data
  // ... read-only snapshot data
  // ... context 0 snapshot data
  // ... context 1 snapshot data

We should keep it simple a snapshot contains contextes of N so we can load and create combined snapshots always in a single instance this is how i implemented the kernels capability based secure IPC via Handels it replaces in fact WASI and WASM.

I could expand a lot of more in here but i guess you should simply watch this issue and i will write it down to publish a crate for that functionality. As this would give nice Ecosystem for my os when i could use some Deno Modules without mich adaption or overhead.

To be short: you will be able to use stealify-b8g which exposes a deno compatible js api and allows you to compile JIT and AOT Snapshots Composed out of Any Source as a Snapshot can contain binary data external references and a lot of other magic that the most people are not aware of.

I would not build a whole secure kernel out of it if it would not be possible :)

Also you can see this in action via the so called v8 code stub assembler which gets used by the .tq torque language and gets then compiled to snapshots to supply builtIns in v8 :)

i should point out that i in fact use some rust components already connected via exposing them as external C

So stealify b8g is in general ECMAScript Compatible tooling for v8 and can be used by deno as deno offers the needed infrastructure (LLVM rust toolchain) and it runs ECMAScript.

i had not the need before but i will implement it on the base of dlopen 's api so that deno can use it more easy. when deno then ships libv8_monolith.so all should be fine thats everything needed. libv8 + shared objects + snapshots for fast loading times and composition as also isolation of capabilitys.

in Fact i use ECMAScript as glue code and Interface definition language as also flow definition language to compose Nativ Applications running on v8 managed heap even interacting with external references that get resolved on snapshot deserialisation as universal module system even on embedded hardware. It Replaces my whole linux and i now port it.