@agoric/swingset-vat 0.33.0-upgrade-19-dev-0754752.0 → 0.33.0-upgrade-18a-dev-4ee0508.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,127 +1,120 @@
1
1
  import { q } from '@endo/errors';
2
- import { makeLimitedConsole } from '@agoric/internal/src/ses-utils.js';
3
-
4
- /** @import {LimitedConsole} from '@agoric/internal/src/js-utils.js'; */
5
2
 
6
3
  const IDLE = 'idle';
7
4
  const STARTUP = 'startup';
8
5
  const DELIVERY = 'delivery';
9
6
 
10
- const noopFinisher = harden(() => {});
11
-
12
- /** @typedef {(...finishArgs: unknown[]) => unknown} AnyFinisher */
13
- /** @typedef {Partial<Record<Exclude<keyof KernelSlog, 'write'>, (methodName: string, args: unknown[], finisher: AnyFinisher) => unknown>>} SlogWrappers */
14
-
15
- /**
16
- * Support composition of asynchronous callbacks that are invoked at the start
17
- * of an operation and return either a non-function result or a "finisher"
18
- * function to be invoked upon operation completion.
19
- * This maker accepts a collection of wrapper functions that receive the same
20
- * arguments as the method they wrap, along with the result of that method
21
- * (e.g., its finisher), and are expected to return a finisher of their own that
22
- * will invoke that wrapped finisher.
23
- *
24
- * @param {SlogWrappers} wrappers
25
- */
26
- function makeFinishersKit(wrappers) {
27
- const unused = new Set(Object.keys(wrappers));
7
+ function makeCallbackRegistry(callbacks) {
8
+ const todo = new Set(Object.keys(callbacks));
28
9
  return harden({
29
10
  /**
30
- * Robustly wrap a method if a wrapper is defined.
11
+ * Robustly wrap a method with a callbacks[method] function, if defined. We
12
+ * incur no runtime overhead if the given callback method isn't defined.
31
13
  *
32
- * @template {(...args: unknown[]) => (Finisher | unknown)} F
33
- * @template {AnyFinisher} [Finisher=AnyFinisher]
34
- * @param {string} method name
35
- * @param {F} impl the original implementation
36
- * @returns {F} the wrapped method
14
+ * @param {string} method wrap with callbacks[method]
15
+ * @param {(...args: Array<unknown>) => unknown} impl the original
16
+ * implementation of the method
17
+ * @returns {(...args: Array<unknown>) => unknown} the wrapped method if the
18
+ * callback is defined, or original method if not
37
19
  */
38
- wrap(method, impl) {
39
- unused.delete(method);
40
- const wrapper = wrappers[method];
41
-
42
- // If there is no registered wrapper, return the implementation directly.
43
- if (!wrapper) return impl;
20
+ registerCallback(method, impl) {
21
+ todo.delete(method);
22
+ const cb = callbacks[method];
23
+ if (!cb) {
24
+ // No registered callback, just use the implementation directly.
25
+ // console.error('no registered callback for', method);
26
+ return impl;
27
+ }
44
28
 
45
- const wrapped = (...args) => {
46
- const maybeFinisher = /** @type {Finisher} */ (impl(...args));
29
+ return (...args) => {
30
+ // Invoke the implementation first.
31
+ const ret = impl(...args);
47
32
  try {
48
- // Allow the callback to observe the call synchronously, and replace
49
- // the implementation's finisher function, but not to throw an exception.
50
- const wrapperFinisher = wrapper(method, args, maybeFinisher);
51
- if (typeof maybeFinisher !== 'function') return wrapperFinisher;
52
-
53
- // We wrap the finisher in the callback's return value.
54
- return (...finishArgs) => {
55
- try {
56
- return /** @type {Finisher} */ (wrapperFinisher)(...finishArgs);
57
- } catch (e) {
58
- console.error(`${method} wrapper finisher failed:`, e);
59
- return maybeFinisher(...finishArgs);
60
- }
61
- };
33
+ // Allow the callback to observe the call synchronously, and affect
34
+ // the finisher function, but not to throw an exception.
35
+ const cbRet = cb(method, args, ret);
36
+ if (typeof ret === 'function') {
37
+ // We wrap the finisher in the callback's return value.
38
+ return (...finishArgs) => {
39
+ try {
40
+ return cbRet(...finishArgs);
41
+ } catch (e) {
42
+ console.error(
43
+ `failed to call registered ${method}.finish function:`,
44
+ e,
45
+ );
46
+ }
47
+ return ret(...args);
48
+ };
49
+ }
50
+ // We just return the callback's return value.
51
+ return cbRet;
62
52
  } catch (e) {
63
- console.error(`${method} wrapper failed:`, e);
64
- return maybeFinisher;
53
+ console.error('failed to call registered', method, 'callback:', e);
65
54
  }
55
+ return ret;
66
56
  };
67
- return /** @type {F} */ (wrapped);
68
57
  },
69
58
  /**
70
- * Declare that all wrapping is done.
59
+ * Declare that all the methods have been registered.
71
60
  *
72
- * @param {string} msg message to display if there are unused wrappers
61
+ * @param {string} errorUnusedMsg message to display if there are callback
62
+ * names that don't correspond to a registration
73
63
  */
74
- done(msg = 'Unused wrappers') {
75
- if (!unused.size) return;
76
- console.warn(msg, ...[...unused.keys()].sort().map(q));
64
+ doneRegistering(errorUnusedMsg = `Unrecognized callback names:`) {
65
+ const cbNames = [...todo.keys()];
66
+ if (!cbNames.length) {
67
+ return;
68
+ }
69
+ console.warn(errorUnusedMsg, cbNames.map(q).sort().join(', '));
77
70
  },
78
71
  });
79
72
  }
80
73
 
81
- export const badConsole = makeLimitedConsole(level => () => {
82
- throw Error(`unexpected use of badConsole.${level}`);
83
- });
84
- export const noopConsole = makeLimitedConsole(_level => () => {});
85
-
86
74
  /**
87
- * @param {SlogWrappers} slogCallbacks
88
- * @param {LimitedConsole} [dummyConsole]
75
+ * @param {*} slogCallbacks
76
+ * @param {Pick<Console, 'debug'|'log'|'info'|'warn'|'error'>} dummyConsole
89
77
  * @returns {KernelSlog}
90
78
  */
91
- export function makeDummySlogger(slogCallbacks, dummyConsole = badConsole) {
92
- const { wrap, done } = makeFinishersKit(slogCallbacks);
79
+ export function makeDummySlogger(slogCallbacks, dummyConsole) {
80
+ const { registerCallback: reg, doneRegistering } =
81
+ makeCallbackRegistry(slogCallbacks);
93
82
  const dummySlogger = harden({
94
- provideVatSlogger: wrap('provideVatSlogger', () => {
95
- return harden({ vatSlog: { delivery: () => noopFinisher } });
96
- }),
97
- vatConsole: wrap('vatConsole', () => dummyConsole),
98
- startup: wrap('startup', () => noopFinisher),
99
- replayVatTranscript: wrap('replayVatTranscript', () => noopFinisher),
100
- delivery: wrap('delivery', () => noopFinisher),
101
- syscall: wrap('syscall', () => noopFinisher),
102
- changeCList: wrap('changeCList', () => noopFinisher),
103
- terminateVat: wrap('terminateVat', () => noopFinisher),
104
- write: noopFinisher,
83
+ provideVatSlogger: reg('provideVatSlogger', () =>
84
+ harden({
85
+ vatSlog: {
86
+ delivery: () => () => 0,
87
+ },
88
+ }),
89
+ ),
90
+ vatConsole: reg('vatConsole', () => dummyConsole),
91
+ startup: reg('startup', () => () => 0), // returns nop finish() function
92
+ replayVatTranscript: reg('replayVatTranscript', () => () => 0),
93
+ delivery: reg('delivery', () => () => 0),
94
+ syscall: reg('syscall', () => () => 0),
95
+ changeCList: reg('changeCList', () => () => 0),
96
+ terminateVat: reg('terminateVat', () => () => 0),
97
+ write: () => 0,
105
98
  });
106
- done('Unused makeDummySlogger slogCallbacks method names');
99
+ doneRegistering(`Unrecognized makeDummySlogger slogCallbacks names:`);
100
+ // @ts-expect-error xxx
107
101
  return dummySlogger;
108
102
  }
109
103
 
110
104
  /**
111
- * @param {SlogWrappers} slogCallbacks
112
- * @param {(obj: object) => void} [writeObj]
105
+ * @param {*} slogCallbacks
106
+ * @param {*} writeObj
113
107
  * @returns {KernelSlog}
114
108
  */
115
109
  export function makeSlogger(slogCallbacks, writeObj) {
116
- const safeWrite = writeObj
117
- ? obj => {
118
- try {
119
- writeObj(obj);
120
- } catch (err) {
121
- console.error('WARNING: slogger write error', err);
122
- }
123
- }
124
- : () => {};
110
+ const safeWrite = e => {
111
+ try {
112
+ writeObj(e);
113
+ } catch (err) {
114
+ console.error('WARNING: slogger write error', err);
115
+ }
116
+ };
117
+ const write = writeObj ? safeWrite : () => 0;
125
118
 
126
119
  const vatSlogs = new Map(); // vatID -> vatSlog
127
120
 
@@ -137,33 +130,36 @@ export function makeSlogger(slogCallbacks, writeObj) {
137
130
  console.error(
138
131
  `WARNING: slogger state confused: vat ${vatID} in ${state}, not ${exp}: ${msg}`,
139
132
  );
140
- safeWrite({ type: 'slogger-confused', vatID, state, exp, msg });
133
+ write({ type: 'slogger-confused', vatID, state, exp, msg });
141
134
  }
142
135
  }
143
136
 
144
137
  function vatConsole(sourcedConsole) {
145
- return makeLimitedConsole(level => (source, ...args) => {
146
- // Don't duplicate stale output.
147
- if (replay) return;
148
-
149
- // Write to the console, then to the slog.
150
- sourcedConsole[level](source, ...args);
151
- // TODO: Just use "liveslots" rather than "ls"?
152
- if (source === 'ls') source = 'liveslots';
153
- const when = { state, crankNum, vatID, deliveryNum };
154
- safeWrite({ type: 'console', source, ...when, level, args });
155
- });
138
+ const vc = {};
139
+ for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
140
+ vc[level] = (sourceTag, ...args) => {
141
+ if (replay) {
142
+ // Don't duplicate stale console output.
143
+ return;
144
+ }
145
+ sourcedConsole[level](sourceTag, ...args);
146
+ const when = { state, crankNum, vatID, deliveryNum };
147
+ const source = sourceTag === 'ls' ? 'liveslots' : sourceTag;
148
+ write({ type: 'console', source, ...when, level, args });
149
+ };
150
+ }
151
+ return harden(vc);
156
152
  }
157
153
 
158
154
  function startup() {
159
155
  // provide a context for console calls during startup
160
156
  checkOldState(IDLE, 'did startup get called twice?');
161
157
  state = STARTUP;
162
- safeWrite({ type: 'vat-startup-start', vatID });
158
+ write({ type: 'vat-startup-start', vatID });
163
159
  function finish() {
164
160
  checkOldState(STARTUP, 'startup-finish called twice?');
165
161
  state = IDLE;
166
- safeWrite({ type: 'vat-startup-finish', vatID });
162
+ write({ type: 'vat-startup-finish', vatID });
167
163
  }
168
164
  return harden(finish);
169
165
  }
@@ -176,13 +172,13 @@ export function makeSlogger(slogCallbacks, writeObj) {
176
172
  deliveryNum = newDeliveryNum;
177
173
  replay = inReplay;
178
174
  const when = { crankNum, vatID, deliveryNum, replay };
179
- safeWrite({ type: 'deliver', ...when, kd, vd });
175
+ write({ type: 'deliver', ...when, kd, vd });
180
176
  syscallNum = 0;
181
177
 
182
178
  // dr: deliveryResult
183
179
  function finish(dr) {
184
180
  checkOldState(DELIVERY, 'delivery-finish called twice?');
185
- safeWrite({ type: 'deliver-result', ...when, dr });
181
+ write({ type: 'deliver-result', ...when, dr });
186
182
  state = IDLE;
187
183
  }
188
184
  return harden(finish);
@@ -192,24 +188,24 @@ export function makeSlogger(slogCallbacks, writeObj) {
192
188
  function syscall(ksc, vsc) {
193
189
  checkOldState(DELIVERY, 'syscall invoked outside of delivery');
194
190
  const when = { crankNum, vatID, deliveryNum, syscallNum, replay };
195
- safeWrite({ type: 'syscall', ...when, ksc, vsc });
191
+ write({ type: 'syscall', ...when, ksc, vsc });
196
192
  syscallNum += 1;
197
193
 
198
194
  // ksr: kernelSyscallResult, vsr: vatSyscallResult
199
195
  function finish(ksr, vsr) {
200
196
  checkOldState(DELIVERY, 'syscall finished after delivery?');
201
- safeWrite({ type: 'syscall-result', ...when, ksr, vsr });
197
+ write({ type: 'syscall-result', ...when, ksr, vsr });
202
198
  }
203
199
  return harden(finish);
204
200
  }
205
201
 
206
202
  // mode: 'import' | 'export' | 'drop'
207
203
  function changeCList(crank, mode, kobj, vobj) {
208
- safeWrite({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
204
+ write({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
209
205
  }
210
206
 
211
207
  function terminateVat(shouldReject, info) {
212
- safeWrite({ type: 'terminate', vatID, shouldReject, info });
208
+ write({ type: 'terminate', vatID, shouldReject, info });
213
209
  }
214
210
 
215
211
  return harden({
@@ -237,7 +233,7 @@ export function makeSlogger(slogCallbacks, writeObj) {
237
233
  }
238
234
  const vatSlog = makeVatSlog(vatID);
239
235
  vatSlogs.set(vatID, vatSlog);
240
- safeWrite({
236
+ write({
241
237
  type: 'create-vat',
242
238
  vatID,
243
239
  dynamic,
@@ -251,42 +247,43 @@ export function makeSlogger(slogCallbacks, writeObj) {
251
247
  }
252
248
 
253
249
  function replayVatTranscript(vatID) {
254
- safeWrite({ type: 'replay-transcript-start', vatID });
250
+ write({ type: 'replay-transcript-start', vatID });
255
251
  function finish() {
256
- safeWrite({ type: 'replay-transcript-finish', vatID });
252
+ write({ type: 'replay-transcript-finish', vatID });
257
253
  }
258
254
  return harden(finish);
259
255
  }
260
256
 
261
257
  // function annotateVat(vatID, data) {
262
- // safeWrite({ type: 'annotate-vat', vatID, data });
258
+ // write({ type: 'annotate-vat', vatID, data });
263
259
  // }
264
260
 
265
- const { wrap, done } = makeFinishersKit(slogCallbacks);
261
+ const { registerCallback: reg, doneRegistering } =
262
+ makeCallbackRegistry(slogCallbacks);
266
263
  const slogger = harden({
267
- provideVatSlogger: wrap('provideVatSlogger', provideVatSlogger),
268
- vatConsole: wrap('vatConsole', (vatID, ...args) =>
264
+ provideVatSlogger: reg('provideVatSlogger', provideVatSlogger),
265
+ vatConsole: reg('vatConsole', (vatID, ...args) =>
269
266
  provideVatSlogger(vatID).vatSlog.vatConsole(...args),
270
267
  ),
271
- startup: wrap('startup', (vatID, ...args) =>
268
+ startup: reg('startup', (vatID, ...args) =>
272
269
  provideVatSlogger(vatID).vatSlog.startup(...args),
273
270
  ),
274
- // TODO: Remove this seemingly dead code.
275
271
  replayVatTranscript,
276
- delivery: wrap('delivery', (vatID, ...args) =>
272
+ delivery: reg('delivery', (vatID, ...args) =>
277
273
  provideVatSlogger(vatID).vatSlog.delivery(...args),
278
274
  ),
279
- syscall: wrap('syscall', (vatID, ...args) =>
275
+ syscall: reg('syscall', (vatID, ...args) =>
280
276
  provideVatSlogger(vatID).vatSlog.syscall(...args),
281
277
  ),
282
- changeCList: wrap('changeCList', (vatID, ...args) =>
278
+ changeCList: reg('changeCList', (vatID, ...args) =>
283
279
  provideVatSlogger(vatID).vatSlog.changeCList(...args),
284
280
  ),
285
- terminateVat: wrap('terminateVat', (vatID, ...args) =>
281
+ terminateVat: reg('terminateVat', (vatID, ...args) =>
286
282
  provideVatSlogger(vatID).vatSlog.terminateVat(...args),
287
283
  ),
288
- write: safeWrite,
284
+ write,
289
285
  });
290
- done('Unused makeSlogger slogCallbacks method names');
286
+ doneRegistering(`Unrecognized makeSlogger slogCallbacks names:`);
287
+ // @ts-expect-error xxx
291
288
  return slogger;
292
289
  }
@@ -1,7 +1,5 @@
1
1
  import { Nat, isNat } from '@endo/nat';
2
2
  import { assert, Fail } from '@endo/errors';
3
- import { naturalCompare } from '@agoric/internal/src/natural-sort.js';
4
- import { makeDummySlogger, noopConsole } from '../slogger.js';
5
3
  import {
6
4
  initializeVatState,
7
5
  makeVatKeeper,
@@ -331,7 +329,7 @@ export const DEFAULT_GC_KREFS_PER_BOYD = 20;
331
329
  /**
332
330
  * @param {SwingStoreKernelStorage} kernelStorage
333
331
  * @param {number | 'uninitialized'} expectedVersion
334
- * @param {KernelSlog} [kernelSlog] optional only for expectedVersion 'uninitialized'
332
+ * @param {KernelSlog} [kernelSlog]
335
333
  */
336
334
  export default function makeKernelKeeper(
337
335
  kernelStorage,
@@ -357,13 +355,10 @@ export default function makeKernelKeeper(
357
355
  if (versionString) {
358
356
  throw Error(`kernel DB already initialized (v${versionString})`);
359
357
  }
360
- kernelSlog ||= makeDummySlogger({}, noopConsole);
361
358
  } else if (expectedVersion !== version) {
362
359
  throw Error(
363
360
  `kernel DB is too old: has version v${version}, but expected v${expectedVersion}`,
364
361
  );
365
- } else if (!kernelSlog) {
366
- throw Error('kernelSlog is required for an already-initialized kernel DB');
367
362
  } else {
368
363
  // DB is up-to-date, so populate any caches we use
369
364
  terminatedVats = JSON.parse(getRequired('vats.terminated'));
@@ -1891,12 +1886,39 @@ export default function makeKernelKeeper(
1891
1886
  }
1892
1887
  }
1893
1888
 
1894
- // Perform an element-by-element natural sort.
1889
+ function compareNumbers(a, b) {
1890
+ return Number(a - b);
1891
+ }
1892
+
1893
+ function compareStrings(a, b) {
1894
+ // natural-sort strings having a shared prefix followed by digits
1895
+ // (e.g., 'ko42' and 'ko100')
1896
+ const [_a, aPrefix, aDigits] = /^(\D+)(\d+)$/.exec(a) || [];
1897
+ if (aPrefix) {
1898
+ const [_b, bPrefix, bDigits] = /^(\D+)(\d+)$/.exec(b) || [];
1899
+ if (bPrefix === aPrefix) {
1900
+ return compareNumbers(aDigits, bDigits);
1901
+ }
1902
+ }
1903
+
1904
+ // otherwise use the default string ordering
1905
+ if (a > b) {
1906
+ return 1;
1907
+ }
1908
+ if (a < b) {
1909
+ return -1;
1910
+ }
1911
+ return 0;
1912
+ }
1913
+
1895
1914
  kernelTable.sort(
1896
1915
  (a, b) =>
1897
- naturalCompare(a[0], b[0]) ||
1898
- naturalCompare(a[1], b[1]) ||
1899
- naturalCompare(a[2], b[2]) ||
1916
+ compareStrings(a[0], b[0]) ||
1917
+ compareStrings(a[1], b[1]) ||
1918
+ compareNumbers(a[2], b[2]) ||
1919
+ compareStrings(a[3], b[3]) ||
1920
+ compareNumbers(a[4], b[4]) ||
1921
+ compareNumbers(a[5], b[5]) ||
1900
1922
  0,
1901
1923
  );
1902
1924
 
@@ -1909,7 +1931,7 @@ export default function makeKernelKeeper(
1909
1931
  promises.push({ id: kpid, ...getKernelPromise(kpid) });
1910
1932
  }
1911
1933
  }
1912
- promises.sort((a, b) => naturalCompare(a.id, b.id));
1934
+ promises.sort((a, b) => compareStrings(a.id, b.id));
1913
1935
 
1914
1936
  const objects = [];
1915
1937
  const nextObjectID = Nat(BigInt(getRequired('ko.nextID')));
@@ -86,7 +86,7 @@ export function initializeVatState(
86
86
  /**
87
87
  * @typedef {object} VatKeeperPowers
88
88
  * @property {TranscriptStore} transcriptStore Accompanying transcript store, for the transcripts
89
- * @property {KernelSlog} kernelSlog
89
+ * @property {*} kernelSlog
90
90
  * @property {*} addKernelObject Kernel function to add a new object to the kernel's mapping tables.
91
91
  * @property {*} addKernelPromiseForVat Kernel function to add a new promise to the kernel's mapping tables.
92
92
  * @property {(kernelSlot: string) => boolean} kernelObjectExists
@@ -411,13 +411,15 @@ export function makeVatKeeper(
411
411
  // update any necessary refcounts consistently
412
412
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
413
413
  kvStore.set(vatKey, kernelSlot);
414
- kernelSlog.changeCList(
415
- vatID,
416
- getCrankNumber(),
417
- 'export',
418
- kernelSlot,
419
- vatSlot,
420
- );
414
+ if (kernelSlog) {
415
+ kernelSlog.changeCList(
416
+ vatID,
417
+ getCrankNumber(),
418
+ 'export',
419
+ kernelSlot,
420
+ vatSlot,
421
+ );
422
+ }
421
423
  kdebug(`Add mapping v->k ${kernelKey}<=>${vatKey}`);
422
424
  } else {
423
425
  // the vat didn't allocate it, and the kernel didn't allocate it
@@ -484,13 +486,15 @@ export function makeVatKeeper(
484
486
  incStat('clistEntries');
485
487
  kvStore.set(vatKey, kernelSlot);
486
488
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
487
- kernelSlog.changeCList(
488
- vatID,
489
- getCrankNumber(),
490
- 'import',
491
- kernelSlot,
492
- vatSlot,
493
- );
489
+ if (kernelSlog) {
490
+ kernelSlog.changeCList(
491
+ vatID,
492
+ getCrankNumber(),
493
+ 'import',
494
+ kernelSlot,
495
+ vatSlot,
496
+ );
497
+ }
494
498
  kdebug(`Add mapping k->v ${kernelKey}<=>${vatKey}`);
495
499
  }
496
500
 
@@ -533,13 +537,15 @@ export function makeVatKeeper(
533
537
  const vatKey = `${vatID}.c.${vatSlot}`;
534
538
  assert(kvStore.has(kernelKey));
535
539
  kdebug(`Delete mapping ${kernelKey}<=>${vatKey}`);
536
- kernelSlog.changeCList(
537
- vatID,
538
- getCrankNumber(),
539
- 'drop',
540
- kernelSlot,
541
- vatSlot,
542
- );
540
+ if (kernelSlog) {
541
+ kernelSlog.changeCList(
542
+ vatID,
543
+ getCrankNumber(),
544
+ 'drop',
545
+ kernelSlot,
546
+ vatSlot,
547
+ );
548
+ }
543
549
  const isExport = allocatedByVat;
544
550
  // We tolerate the object kref not being present in the kernel object
545
551
  // table, either because we're being called during the translation of
@@ -671,7 +677,13 @@ export function makeVatKeeper(
671
677
  restartWorker,
672
678
  );
673
679
 
674
- const { hash: snapshotID } = info;
680
+ const {
681
+ hash: snapshotID,
682
+ uncompressedSize,
683
+ dbSaveSeconds,
684
+ compressedSize,
685
+ compressSeconds,
686
+ } = info;
675
687
 
676
688
  // push a save-snapshot transcript entry
677
689
  addToTranscript(makeSaveSnapshotItem(snapshotID));
@@ -683,6 +695,18 @@ export function makeVatKeeper(
683
695
  // always starts with an initialize-worker or load-snapshot
684
696
  // pseudo-delivery
685
697
  addToTranscript(makeLoadSnapshotItem(snapshotID));
698
+
699
+ kernelSlog.write({
700
+ type: 'heap-snapshot-save',
701
+ vatID,
702
+ snapshotID,
703
+ uncompressedSize,
704
+ dbSaveSeconds,
705
+ compressedSize,
706
+ compressSeconds,
707
+ endPosition,
708
+ restartWorker,
709
+ });
686
710
  }
687
711
 
688
712
  /**
@@ -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 makeVatManagerMaker({
7
+ export function makeVatManagerFactory({
8
8
  allVatPowers,
9
9
  kernelKeeper,
10
10
  vatEndowments,
@@ -18,12 +18,14 @@ export function makeVatManagerMaker({
18
18
  vatEndowments,
19
19
  gcTools,
20
20
  });
21
+
21
22
  const nodeSubprocessFactory = makeNodeSubprocessFactory({
22
23
  startSubprocessWorker: startSubprocessWorkerNode,
23
24
  kernelKeeper,
24
25
  kernelSlog,
25
26
  testLog: allVatPowers.testLog,
26
27
  });
28
+
27
29
  const xsWorkerFactory = makeXsSubprocessFactory({
28
30
  startXSnap,
29
31
  kernelKeeper,
@@ -67,41 +69,58 @@ export function makeVatManagerMaker({
67
69
  * @param {import('@agoric/swingset-liveslots').LiveSlotsOptions} options.liveSlotsOptions
68
70
  * @returns { Promise<import('../../types-internal.js').VatManager> }
69
71
  */
70
- async function makeVatManager(vatID, options) {
71
- const { managerOptions, liveSlotsOptions } = options;
72
+ async function vatManagerFactory(
73
+ vatID,
74
+ { managerOptions, liveSlotsOptions },
75
+ ) {
72
76
  validateManagerOptions(managerOptions);
73
77
  const { workerOptions, enableSetup } = managerOptions;
74
78
  const { type } = workerOptions;
75
79
 
76
- if (type !== 'local' && (enableSetup || 'setup' in managerOptions)) {
77
- console.warn(`TODO: stop using enableSetup and setup() with ${type}`);
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
+ );
78
101
  }
79
102
 
80
- if (enableSetup && managerOptions.setup) {
81
- return localFactory.createFromSetup(vatID, managerOptions);
103
+ if (type === 'node-subprocess') {
104
+ return nodeSubprocessFactory.createFromBundle(
105
+ vatID,
106
+ managerOptions.bundle,
107
+ managerOptions,
108
+ liveSlotsOptions,
109
+ );
82
110
  }
83
111
 
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}`);
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
+ );
95
120
  }
96
121
 
97
- return factory.createFromBundle(
98
- vatID,
99
- // @ts-expect-error managerOptions.bundle might be undefined
100
- managerOptions.bundle,
101
- managerOptions,
102
- liveSlotsOptions,
103
- );
122
+ throw Error(`unknown type ${type}, not 'local' or 'xsnap'`);
104
123
  }
105
124
 
106
- return harden(makeVatManager);
125
+ return harden(vatManagerFactory);
107
126
  }