Replies: 1 comment
-
I haven't looked at state.js in detail yet, but here are some notes relevant to this topic:
Yes, that would be me :-) First, I sometimes get emails of people asking me if there's a way to upgrade their state file from Secondly, zstd compression is significant for the state images. For reference:
I use v86 with nodejs to automatically build and compress the state images, e.g: const s = await emulator.save_state();
await fs.writeFile(OUTPUT_FILE, new Uint8Array(s));
child_process.execFileSync("make", ["-C", path.dirname(OUTPUT_FILE), path.basename(OUTPUT_FILE) + ".zst"], { stdio: "inherit" }); Where the makefile does
That's fine, iff you keep the old state loading code around and fork based on the version in the state file. That way, old state images can still be used in new versions. Old versions of v86 won't be able to load the new state images, but I don't think that's a problem. All the other suggestions in proposal B sound very reasonable, and I would probably merge them. Just try to keep the format simple, please :-) |
Beta Was this translation helpful? Give feedback.
-
I want to propose a (possibly) breaking change to the way buffers are serialized in the save state format.
Problem: We are missing opportunities to produce radically smaller save state files because the current design assumes assumes blocks are sequential and disjoint (i.e. non-overlapping). Suppose there is a block of data that appears multiple times on disk as well as multiple times in memory. This situation is common! The current format can't express the idea that a single instance of this data in the save state file should get reused multiple times when restoring state.
Currently, our buffer info objects have
offset
andlength
fields that could allow them different buffer info objects to refer back to a shared range of data in the big buffer. However, the zstd path ofCPU.prototype.restore_state
makes some assumptions about sequential layout (it ignoresoffset
and does its own logic withfront_padding
to compute the offset instead).Proposals:
CPU.prototype.restore_state
to match what seem to be the intended semantics of theoffset
andlength
fields of buffer info objects (e.g. interpret the current implementation as buggy and just fix it). You might think this is totally unacceptable because it means that a state saved by in nominally version 6 format can't be decoded by another nominally version 6 (but older) implementation. However, consider that the current codebase (to my understanding) doesn't every actually output zstd-compressed save states. We'd be breaking support for decoding a format that we don't actually support for encoding anyway.Proposal A risks upsetting people, but do these people exist? Who relies on version 6 states with internal zstd compression?
Proposal B is very safe and forward-looking, but I also note that we haven't bumped the version number in several years. So, there's a risk of a different kind of disruption that people didn't expect.
Context: I'm making a generalization of savestates that I call savestreams (paralleling the relationship between screenshots and screen recording videos). One thing I'd really like to have is the ability to do block-based deduplication of V86 savestates. This requires more flexibility in block alignment and allowing blocks to be reused and accessed out of order.
Beta Was this translation helpful? Give feedback.
All reactions