@agoric/swingset-vat 0.32.3-upgrade-18-dev-6ddbef0.0 → 0.32.3-upgrade-19-dev-2a71f04.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
- /* eslint-disable no-use-before-define */
2
1
  import { Nat, isNat } from '@endo/nat';
3
2
  import { assert, Fail } from '@endo/errors';
3
+ import { naturalCompare } from '@agoric/internal/src/natural-sort.js';
4
+ import { makeDummySlogger, noopConsole } from '../slogger.js';
4
5
  import {
5
6
  initializeVatState,
6
7
  makeVatKeeper,
@@ -43,6 +44,7 @@ const enableKernelGC = true;
43
44
  * @typedef { import('../../types-external.js').SnapStore } SnapStore
44
45
  * @typedef { import('../../types-external.js').TranscriptStore } TranscriptStore
45
46
  * @typedef { import('../../types-external.js').VatKeeper } VatKeeper
47
+ * @typedef { Pick<VatKeeper, 'deleteCListEntry' | 'deleteSnapshots' | 'deleteTranscripts'> } VatUndertaker
46
48
  * @typedef { import('../../types-internal.js').InternalKernelOptions } InternalKernelOptions
47
49
  * @typedef { import('../../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
48
50
  * @import {PromiseRecord} from '../../types-internal.js';
@@ -329,7 +331,7 @@ export const DEFAULT_GC_KREFS_PER_BOYD = 20;
329
331
  /**
330
332
  * @param {SwingStoreKernelStorage} kernelStorage
331
333
  * @param {number | 'uninitialized'} expectedVersion
332
- * @param {KernelSlog} [kernelSlog]
334
+ * @param {KernelSlog} [kernelSlog] optional only for expectedVersion 'uninitialized'
333
335
  */
334
336
  export default function makeKernelKeeper(
335
337
  kernelStorage,
@@ -355,10 +357,13 @@ export default function makeKernelKeeper(
355
357
  if (versionString) {
356
358
  throw Error(`kernel DB already initialized (v${versionString})`);
357
359
  }
360
+ kernelSlog ||= makeDummySlogger({}, noopConsole);
358
361
  } else if (expectedVersion !== version) {
359
362
  throw Error(
360
363
  `kernel DB is too old: has version v${version}, but expected v${expectedVersion}`,
361
364
  );
365
+ } else if (!kernelSlog) {
366
+ throw Error('kernelSlog is required for an already-initialized kernel DB');
362
367
  } else {
363
368
  // DB is up-to-date, so populate any caches we use
364
369
  terminatedVats = JSON.parse(getRequired('vats.terminated'));
@@ -422,6 +427,8 @@ export default function makeKernelKeeper(
422
427
  const ephemeral = harden({
423
428
  /** @type { Map<string, VatKeeper> } */
424
429
  vatKeepers: new Map(),
430
+ /** @type { Map<string, VatUndertaker> } */
431
+ vatUndertakers: new Map(),
425
432
  deviceKeepers: new Map(), // deviceID -> deviceKeeper
426
433
  });
427
434
 
@@ -1044,7 +1051,7 @@ export default function makeKernelKeeper(
1044
1051
  // first or vref first), and delete the other one in the same
1045
1052
  // call, so we don't wind up with half an entry.
1046
1053
 
1047
- const vatKeeper = provideVatKeeper(vatID);
1054
+ const undertaker = provideVatUndertaker(vatID);
1048
1055
  const clistPrefix = `${vatID}.c.`;
1049
1056
  const exportPrefix = `${clistPrefix}o+`;
1050
1057
  const importPrefix = `${clistPrefix}o-`;
@@ -1092,7 +1099,7 @@ export default function makeKernelKeeper(
1092
1099
  // drop+retire
1093
1100
  const kref = kvStore.get(k) || Fail`getNextKey ensures get`;
1094
1101
  const vref = stripPrefix(clistPrefix, k);
1095
- vatKeeper.deleteCListEntry(kref, vref);
1102
+ undertaker.deleteCListEntry(kref, vref);
1096
1103
  // that will also delete both db keys
1097
1104
  work.imports += 1;
1098
1105
  remaining -= 1;
@@ -1109,7 +1116,7 @@ export default function makeKernelKeeper(
1109
1116
  for (const k of enumeratePrefixedKeys(kvStore, promisePrefix)) {
1110
1117
  const kref = kvStore.get(k) || Fail`getNextKey ensures get`;
1111
1118
  const vref = stripPrefix(clistPrefix, k);
1112
- vatKeeper.deleteCListEntry(kref, vref);
1119
+ undertaker.deleteCListEntry(kref, vref);
1113
1120
  // that will also delete both db keys
1114
1121
  work.promises += 1;
1115
1122
  remaining -= 1;
@@ -1131,7 +1138,7 @@ export default function makeKernelKeeper(
1131
1138
 
1132
1139
  // this will internally loop through 'budget' deletions
1133
1140
  remaining = budget.snapshots ?? budget.default;
1134
- const dsc = vatKeeper.deleteSnapshots(remaining);
1141
+ const dsc = undertaker.deleteSnapshots(remaining);
1135
1142
  work.snapshots += dsc.cleanups;
1136
1143
  remaining -= dsc.cleanups;
1137
1144
  if (remaining <= 0) {
@@ -1140,7 +1147,7 @@ export default function makeKernelKeeper(
1140
1147
 
1141
1148
  // same
1142
1149
  remaining = budget.transcripts ?? budget.default;
1143
- const dts = vatKeeper.deleteTranscripts(remaining);
1150
+ const dts = undertaker.deleteTranscripts(remaining);
1144
1151
  work.transcripts += dts.cleanups;
1145
1152
  remaining -= dts.cleanups;
1146
1153
  // last task, so increment cleanups, but dc.done is authoritative
@@ -1697,6 +1704,26 @@ export default function makeKernelKeeper(
1697
1704
  initializeVatState(kvStore, transcriptStore, vatID, source, options);
1698
1705
  }
1699
1706
 
1707
+ /** @type {import('./vatKeeper.js').VatKeeperPowers} */
1708
+ const vatKeeperPowers = {
1709
+ transcriptStore,
1710
+ kernelSlog,
1711
+ addKernelObject,
1712
+ addKernelPromiseForVat,
1713
+ kernelObjectExists,
1714
+ incrementRefCount,
1715
+ decrementRefCount,
1716
+ getObjectRefCount,
1717
+ setObjectRefCount,
1718
+ getReachableAndVatSlot,
1719
+ addMaybeFreeKref,
1720
+ incStat,
1721
+ decStat,
1722
+ getCrankNumber,
1723
+ scheduleReap,
1724
+ snapStore,
1725
+ };
1726
+
1700
1727
  function provideVatKeeper(vatID) {
1701
1728
  insistVatID(vatID);
1702
1729
  const found = ephemeral.vatKeepers.get(vatID);
@@ -1704,30 +1731,36 @@ export default function makeKernelKeeper(
1704
1731
  return found;
1705
1732
  }
1706
1733
  assert(kvStore.has(`${vatID}.o.nextID`), `${vatID} was not initialized`);
1707
- const vk = makeVatKeeper(
1708
- kvStore,
1709
- transcriptStore,
1710
- kernelSlog,
1711
- vatID,
1712
- addKernelObject,
1713
- addKernelPromiseForVat,
1714
- kernelObjectExists,
1715
- incrementRefCount,
1716
- decrementRefCount,
1717
- getObjectRefCount,
1718
- setObjectRefCount,
1719
- getReachableAndVatSlot,
1720
- addMaybeFreeKref,
1721
- incStat,
1722
- decStat,
1723
- getCrankNumber,
1724
- scheduleReap,
1725
- snapStore,
1726
- );
1734
+ const vk = makeVatKeeper(vatID, kvStore, vatKeeperPowers);
1727
1735
  ephemeral.vatKeepers.set(vatID, vk);
1728
1736
  return vk;
1729
1737
  }
1730
1738
 
1739
+ /**
1740
+ * Produce an attenuated vatKeeper for slow vat termination (and that
1741
+ * therefore does not insist on liveness, unlike provideVatKeeper).
1742
+ *
1743
+ * @param {string} vatID
1744
+ */
1745
+ function provideVatUndertaker(vatID) {
1746
+ insistVatID(vatID);
1747
+ const found = ephemeral.vatUndertakers.get(vatID);
1748
+ if (found !== undefined) {
1749
+ return found;
1750
+ }
1751
+ const { deleteCListEntry, deleteSnapshots, deleteTranscripts } =
1752
+ ephemeral.vatKeepers.get(vatID) ||
1753
+ makeVatKeeper(vatID, kvStore, vatKeeperPowers);
1754
+ /** @type {VatUndertaker} */
1755
+ const undertaker = harden({
1756
+ deleteCListEntry,
1757
+ deleteSnapshots,
1758
+ deleteTranscripts,
1759
+ });
1760
+ ephemeral.vatUndertakers.set(vatID, undertaker);
1761
+ return undertaker;
1762
+ }
1763
+
1731
1764
  function vatIsAlive(vatID) {
1732
1765
  insistVatID(vatID);
1733
1766
  return kvStore.has(`${vatID}.o.nextID`) && !terminatedVats.includes(vatID);
@@ -1858,39 +1891,12 @@ export default function makeKernelKeeper(
1858
1891
  }
1859
1892
  }
1860
1893
 
1861
- function compareNumbers(a, b) {
1862
- return Number(a - b);
1863
- }
1864
-
1865
- function compareStrings(a, b) {
1866
- // natural-sort strings having a shared prefix followed by digits
1867
- // (e.g., 'ko42' and 'ko100')
1868
- const [_a, aPrefix, aDigits] = /^(\D+)(\d+)$/.exec(a) || [];
1869
- if (aPrefix) {
1870
- const [_b, bPrefix, bDigits] = /^(\D+)(\d+)$/.exec(b) || [];
1871
- if (bPrefix === aPrefix) {
1872
- return compareNumbers(aDigits, bDigits);
1873
- }
1874
- }
1875
-
1876
- // otherwise use the default string ordering
1877
- if (a > b) {
1878
- return 1;
1879
- }
1880
- if (a < b) {
1881
- return -1;
1882
- }
1883
- return 0;
1884
- }
1885
-
1894
+ // Perform an element-by-element natural sort.
1886
1895
  kernelTable.sort(
1887
1896
  (a, b) =>
1888
- compareStrings(a[0], b[0]) ||
1889
- compareStrings(a[1], b[1]) ||
1890
- compareNumbers(a[2], b[2]) ||
1891
- compareStrings(a[3], b[3]) ||
1892
- compareNumbers(a[4], b[4]) ||
1893
- compareNumbers(a[5], b[5]) ||
1897
+ naturalCompare(a[0], b[0]) ||
1898
+ naturalCompare(a[1], b[1]) ||
1899
+ naturalCompare(a[2], b[2]) ||
1894
1900
  0,
1895
1901
  );
1896
1902
 
@@ -1903,7 +1909,7 @@ export default function makeKernelKeeper(
1903
1909
  promises.push({ id: kpid, ...getKernelPromise(kpid) });
1904
1910
  }
1905
1911
  }
1906
- promises.sort((a, b) => compareStrings(a.id, b.id));
1912
+ promises.sort((a, b) => naturalCompare(a.id, b.id));
1907
1913
 
1908
1914
  const objects = [];
1909
1915
  const nextObjectID = Nat(BigInt(getRequired('ko.nextID')));
@@ -84,49 +84,53 @@ export function initializeVatState(
84
84
  }
85
85
 
86
86
  /**
87
- * Produce a vat keeper for a vat.
87
+ * @typedef {object} VatKeeperPowers
88
+ * @property {TranscriptStore} transcriptStore Accompanying transcript store, for the transcripts
89
+ * @property {KernelSlog} kernelSlog
90
+ * @property {*} addKernelObject Kernel function to add a new object to the kernel's mapping tables.
91
+ * @property {*} addKernelPromiseForVat Kernel function to add a new promise to the kernel's mapping tables.
92
+ * @property {(kernelSlot: string) => boolean} kernelObjectExists
93
+ * @property {*} incrementRefCount
94
+ * @property {*} decrementRefCount
95
+ * @property {(kernelSlot: string) => {reachable: number, recognizable: number}} getObjectRefCount
96
+ * @property {(kernelSlot: string, o: { reachable: number, recognizable: number }) => void} setObjectRefCount
97
+ * @property {(vatID: string, kernelSlot: string) => {isReachable: boolean, vatSlot: string}} getReachableAndVatSlot
98
+ * @property {(kernelSlot: string) => void} addMaybeFreeKref
99
+ * @property {*} incStat
100
+ * @property {*} decStat
101
+ * @property {*} getCrankNumber
102
+ * @property {*} scheduleReap
103
+ * @property {SnapStore} snapStore
104
+ */
105
+
106
+ /**
107
+ * Produce a "vat keeper" for the kernel state of a vat.
88
108
  *
89
- * @param {KVStore} kvStore The keyValue store in which the persistent state will be kept
90
- * @param {TranscriptStore} transcriptStore Accompanying transcript store, for the transcripts
91
- * @param {*} kernelSlog
92
109
  * @param {string} vatID The vat ID string of the vat in question
93
- * @param {*} addKernelObject Kernel function to add a new object to the kernel's
94
- * mapping tables.
95
- * @param {*} addKernelPromiseForVat Kernel function to add a new promise to the
96
- * kernel's mapping tables.
97
- * @param {(kernelSlot: string) => boolean} kernelObjectExists
98
- * @param {*} incrementRefCount
99
- * @param {*} decrementRefCount
100
- * @param {(kernelSlot: string) => {reachable: number, recognizable: number}} getObjectRefCount
101
- * @param {(kernelSlot: string, o: { reachable: number, recognizable: number }) => void} setObjectRefCount
102
- * @param {(vatID: string, kernelSlot: string) => {isReachable: boolean, vatSlot: string}} getReachableAndVatSlot
103
- * @param {(kernelSlot: string) => void} addMaybeFreeKref
104
- * @param {*} incStat
105
- * @param {*} decStat
106
- * @param {*} getCrankNumber
107
- * @param {*} scheduleReap
108
- * @param {SnapStore} [snapStore]
109
- * returns an object to hold and access the kernel's state for the given vat
110
+ * @param {KVStore} kvStore The keyValue store in which the persistent state will be kept
111
+ * @param {VatKeeperPowers} powers
110
112
  */
111
113
  export function makeVatKeeper(
112
- kvStore,
113
- transcriptStore,
114
- kernelSlog,
115
114
  vatID,
116
- addKernelObject,
117
- addKernelPromiseForVat,
118
- kernelObjectExists,
119
- incrementRefCount,
120
- decrementRefCount,
121
- getObjectRefCount,
122
- setObjectRefCount,
123
- getReachableAndVatSlot,
124
- addMaybeFreeKref,
125
- incStat,
126
- decStat,
127
- getCrankNumber,
128
- scheduleReap,
129
- snapStore = undefined,
115
+ kvStore,
116
+ {
117
+ transcriptStore,
118
+ kernelSlog,
119
+ addKernelObject,
120
+ addKernelPromiseForVat,
121
+ kernelObjectExists,
122
+ incrementRefCount,
123
+ decrementRefCount,
124
+ getObjectRefCount,
125
+ setObjectRefCount,
126
+ getReachableAndVatSlot,
127
+ addMaybeFreeKref,
128
+ incStat,
129
+ decStat,
130
+ getCrankNumber,
131
+ scheduleReap,
132
+ snapStore,
133
+ },
130
134
  ) {
131
135
  insistVatID(vatID);
132
136
 
@@ -407,15 +411,13 @@ export function makeVatKeeper(
407
411
  // update any necessary refcounts consistently
408
412
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
409
413
  kvStore.set(vatKey, kernelSlot);
410
- if (kernelSlog) {
411
- kernelSlog.changeCList(
412
- vatID,
413
- getCrankNumber(),
414
- 'export',
415
- kernelSlot,
416
- vatSlot,
417
- );
418
- }
414
+ kernelSlog.changeCList(
415
+ vatID,
416
+ getCrankNumber(),
417
+ 'export',
418
+ kernelSlot,
419
+ vatSlot,
420
+ );
419
421
  kdebug(`Add mapping v->k ${kernelKey}<=>${vatKey}`);
420
422
  } else {
421
423
  // the vat didn't allocate it, and the kernel didn't allocate it
@@ -482,15 +484,13 @@ export function makeVatKeeper(
482
484
  incStat('clistEntries');
483
485
  kvStore.set(vatKey, kernelSlot);
484
486
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
485
- if (kernelSlog) {
486
- kernelSlog.changeCList(
487
- vatID,
488
- getCrankNumber(),
489
- 'import',
490
- kernelSlot,
491
- vatSlot,
492
- );
493
- }
487
+ kernelSlog.changeCList(
488
+ vatID,
489
+ getCrankNumber(),
490
+ 'import',
491
+ kernelSlot,
492
+ vatSlot,
493
+ );
494
494
  kdebug(`Add mapping k->v ${kernelKey}<=>${vatKey}`);
495
495
  }
496
496
 
@@ -533,15 +533,13 @@ export function makeVatKeeper(
533
533
  const vatKey = `${vatID}.c.${vatSlot}`;
534
534
  assert(kvStore.has(kernelKey));
535
535
  kdebug(`Delete mapping ${kernelKey}<=>${vatKey}`);
536
- if (kernelSlog) {
537
- kernelSlog.changeCList(
538
- vatID,
539
- getCrankNumber(),
540
- 'drop',
541
- kernelSlot,
542
- vatSlot,
543
- );
544
- }
536
+ kernelSlog.changeCList(
537
+ vatID,
538
+ getCrankNumber(),
539
+ 'drop',
540
+ kernelSlot,
541
+ vatSlot,
542
+ );
545
543
  const isExport = allocatedByVat;
546
544
  // We tolerate the object kref not being present in the kernel object
547
545
  // table, either because we're being called during the translation of
@@ -673,13 +671,7 @@ export function makeVatKeeper(
673
671
  restartWorker,
674
672
  );
675
673
 
676
- const {
677
- hash: snapshotID,
678
- uncompressedSize,
679
- dbSaveSeconds,
680
- compressedSize,
681
- compressSeconds,
682
- } = info;
674
+ const { hash: snapshotID } = info;
683
675
 
684
676
  // push a save-snapshot transcript entry
685
677
  addToTranscript(makeSaveSnapshotItem(snapshotID));
@@ -691,18 +683,6 @@ export function makeVatKeeper(
691
683
  // always starts with an initialize-worker or load-snapshot
692
684
  // pseudo-delivery
693
685
  addToTranscript(makeLoadSnapshotItem(snapshotID));
694
-
695
- kernelSlog.write({
696
- type: 'heap-snapshot-save',
697
- vatID,
698
- snapshotID,
699
- uncompressedSize,
700
- dbSaveSeconds,
701
- compressedSize,
702
- compressSeconds,
703
- endPosition,
704
- restartWorker,
705
- });
706
686
  }
707
687
 
708
688
  /**
@@ -4,7 +4,7 @@ import { makeLocalVatManagerFactory } from './manager-local.js';
4
4
  import { makeNodeSubprocessFactory } from './manager-subprocess-node.js';
5
5
  import { makeXsSubprocessFactory } from './manager-subprocess-xsnap.js';
6
6
 
7
- export function makeVatManagerFactory({
7
+ export function makeVatManagerMaker({
8
8
  allVatPowers,
9
9
  kernelKeeper,
10
10
  vatEndowments,
@@ -18,14 +18,12 @@ export function makeVatManagerFactory({
18
18
  vatEndowments,
19
19
  gcTools,
20
20
  });
21
-
22
21
  const nodeSubprocessFactory = makeNodeSubprocessFactory({
23
22
  startSubprocessWorker: startSubprocessWorkerNode,
24
23
  kernelKeeper,
25
24
  kernelSlog,
26
25
  testLog: allVatPowers.testLog,
27
26
  });
28
-
29
27
  const xsWorkerFactory = makeXsSubprocessFactory({
30
28
  startXSnap,
31
29
  kernelKeeper,
@@ -69,58 +67,41 @@ export function makeVatManagerFactory({
69
67
  * @param {import('@agoric/swingset-liveslots').LiveSlotsOptions} options.liveSlotsOptions
70
68
  * @returns { Promise<import('../../types-internal.js').VatManager> }
71
69
  */
72
- async function vatManagerFactory(
73
- vatID,
74
- { managerOptions, liveSlotsOptions },
75
- ) {
70
+ async function makeVatManager(vatID, options) {
71
+ const { managerOptions, liveSlotsOptions } = options;
76
72
  validateManagerOptions(managerOptions);
77
73
  const { workerOptions, enableSetup } = managerOptions;
78
74
  const { type } = workerOptions;
79
75
 
80
- if (type !== 'local' && 'setup' in managerOptions) {
81
- console.warn(`TODO: stop using setup() with ${type}`);
82
- }
83
- if (enableSetup) {
84
- if (managerOptions.setup) {
85
- return localFactory.createFromSetup(vatID, managerOptions);
86
- } else {
87
- return localFactory.createFromBundle(
88
- vatID,
89
- managerOptions.bundle,
90
- managerOptions,
91
- liveSlotsOptions,
92
- );
93
- }
94
- } else if (type === 'local') {
95
- return localFactory.createFromBundle(
96
- vatID,
97
- managerOptions.bundle,
98
- managerOptions,
99
- liveSlotsOptions,
100
- );
76
+ if (type !== 'local' && (enableSetup || 'setup' in managerOptions)) {
77
+ console.warn(`TODO: stop using enableSetup and setup() with ${type}`);
101
78
  }
102
79
 
103
- if (type === 'node-subprocess') {
104
- return nodeSubprocessFactory.createFromBundle(
105
- vatID,
106
- managerOptions.bundle,
107
- managerOptions,
108
- liveSlotsOptions,
109
- );
80
+ if (enableSetup && managerOptions.setup) {
81
+ return localFactory.createFromSetup(vatID, managerOptions);
110
82
  }
111
83
 
112
- if (type === 'xsnap') {
113
- assert(managerOptions.bundle, 'xsnap requires Bundle');
114
- return xsWorkerFactory.createFromBundle(
115
- vatID,
116
- managerOptions.bundle,
117
- managerOptions,
118
- liveSlotsOptions,
119
- );
84
+ /** @type {Pick<typeof xsWorkerFactory, 'createFromBundle'>} */
85
+ let factory;
86
+ if (enableSetup || type === 'local') {
87
+ factory = localFactory;
88
+ } else if (type === 'node-subprocess') {
89
+ factory = nodeSubprocessFactory;
90
+ } else if (type === 'xsnap') {
91
+ assert(managerOptions.bundle, 'worker type xsnap requires a bundle');
92
+ factory = xsWorkerFactory;
93
+ } else {
94
+ throw Error(`unknown vat worker type ${type}`);
120
95
  }
121
96
 
122
- throw Error(`unknown type ${type}, not 'local' or 'xsnap'`);
97
+ return factory.createFromBundle(
98
+ vatID,
99
+ // @ts-expect-error managerOptions.bundle might be undefined
100
+ managerOptions.bundle,
101
+ managerOptions,
102
+ liveSlotsOptions,
103
+ );
123
104
  }
124
105
 
125
- return harden(vatManagerFactory);
106
+ return harden(makeVatManager);
126
107
  }
@@ -128,8 +128,10 @@ export function makeXsSubprocessFactory({
128
128
 
129
129
  const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
130
130
  const snapshotInfo = vatKeeper.getSnapshotInfo();
131
+ let uncompressedSizeLoaded = null;
131
132
  if (snapshotInfo) {
132
133
  kernelSlog.write({ type: 'heap-snapshot-load', vatID, ...snapshotInfo });
134
+ uncompressedSizeLoaded = snapshotInfo.uncompressedSize;
133
135
  }
134
136
 
135
137
  // `startXSnap` adds `nameDisplayArg` as a dummy argument so that 'ps'
@@ -240,9 +242,31 @@ export function makeXsSubprocessFactory({
240
242
  async function makeSnapshot(snapPos, snapStore, restartWorker) {
241
243
  const snapshotDescription = `${vatID}-${snapPos}`;
242
244
  const snapshotStream = worker.makeSnapshotStream(snapshotDescription);
245
+ const saveSnapshot = async saveStream => {
246
+ const results = await snapStore.saveSnapshot(
247
+ vatID,
248
+ snapPos,
249
+ saveStream,
250
+ );
251
+ const { hash: snapshotID, ...metrics } = results;
252
+ const uncompressedSizeDelta =
253
+ uncompressedSizeLoaded &&
254
+ metrics.uncompressedSize - uncompressedSizeLoaded;
255
+ uncompressedSizeLoaded = results.uncompressedSize;
256
+ kernelSlog.write({
257
+ type: 'heap-snapshot-save',
258
+ vatID,
259
+ snapshotID,
260
+ endPosition: snapPos,
261
+ ...metrics,
262
+ uncompressedSizeDelta,
263
+ restartWorker,
264
+ });
265
+ return results;
266
+ };
243
267
 
244
268
  if (!restartWorker) {
245
- return snapStore.saveSnapshot(vatID, snapPos, snapshotStream);
269
+ return saveSnapshot(snapshotStream);
246
270
  }
247
271
 
248
272
  /** @type {AsyncGenerator<Uint8Array, void, void>[]} */
@@ -268,7 +292,7 @@ export function makeXsSubprocessFactory({
268
292
  snapshotDescription,
269
293
  },
270
294
  }),
271
- snapStore.saveSnapshot(vatID, snapPos, snapStoreSaveStream),
295
+ saveSnapshot(snapStoreSaveStream),
272
296
  ]);
273
297
  await closeP;
274
298
 
@@ -9,7 +9,7 @@ export function makeVatRootObjectSlot() {
9
9
  export function makeVatLoader(stuff) {
10
10
  const {
11
11
  overrideVatManagerOptions = {},
12
- vatManagerFactory,
12
+ makeVatManager,
13
13
  kernelSlog,
14
14
  makeSourcedConsole,
15
15
  kernelKeeper,
@@ -127,7 +127,7 @@ export function makeVatLoader(stuff) {
127
127
  };
128
128
 
129
129
  const finish = starting && kernelSlog.startup(vatID);
130
- const manager = await vatManagerFactory(vatID, {
130
+ const manager = await makeVatManager(vatID, {
131
131
  managerOptions,
132
132
  liveSlotsOptions,
133
133
  });
@@ -150,7 +150,7 @@ export function makeVatLoader(stuff) {
150
150
  ...overrideVatManagerOptions,
151
151
  };
152
152
  const liveSlotsOptions = {};
153
- const manager = await vatManagerFactory(vatID, {
153
+ const manager = await makeVatManager(vatID, {
154
154
  managerOptions,
155
155
  liveSlotsOptions,
156
156
  });