1package riscv23import"gno.land/p/moul/x/vm/vmkit/v0"45// Snapshot serializes the hart: registers, pc, status, and only the memory6// pages the guest has written.7//8
Functions
not supported for pure packages by the node (vm/qfuncs)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
// A 1 MiB address space serialized on every pause would make continuations
9// cost more than re-running, which is exactly the kill criterion vmkit set for
10// them. The dirty bitmap is what avoids it: a guest that has touched two pages
11// pauses in about 8 KiB regardless of how much memory it was given.
12func (m *Machine) Snapshot() []byte {
13if m.code == nil {
14 m.code = &code{}
15 }
16 w := vmkit.NewWriter(4096)
17 w.Uint32(snapMagic)
18 w.Byte(snapVersion)
19for i := 0; i < 32; i++ {
20 w.Uint32(m.reg[i])
21 }
22 w.Uint32(m.pc)
23 w.Byte(byte(m.status))
24 w.String(m.trap)
25 w.Int(int64(m.outLen))
26// The text segment's extent, so a restored hart knows which of its pages
27// are code and can predecode them again. The code itself is not written:
28// it is already in the memory pages, which WriteImage marked dirty.
29 w.Uint32(m.code.base)
30 w.Uint32(m.code.words)
31 m.mem.Snapshot(w)
32return w.Out()
33}
34
35// Restore loads a snapshot. The program image is not carried separately: it
36// lives in the memory pages, which were marked dirty when it was written, so a
37// restored hart has its code without the instance storing it twice.
38func (m *Machine) Restore(b []byte) error {
39 r := vmkit.NewReader(b)
40if r.Uint32() != snapMagic {
41return vmkit.ErrBadSnapshot
42 }
43if r.Byte() != snapVersion {
44return vmkit.ErrBadSnapshot
45 }
46var reg [32]uint32
47for i := 0; i < 32; i++ {
48 reg[i] = r.Uint32()
49 }
50 pc := r.Uint32()
51 status := vmkit.Status(r.Byte())
52 trap := r.String()
53 outLen := int(r.Int())
54 base := r.Uint32()
55 words := r.Uint32()
56if err := r.Err(); err != nil {
57return err
58 }
59// A text segment that does not fit in the address space is a snapshot this
60// machine did not write, and predecoding it would index past the memory.