Skip to content

Commit

Permalink
chore: provide GC tools (WeakRef/FinalizationRegistry) to makeLiveSlots
Browse files Browse the repository at this point in the history
These two authorities are not part of SES, so they must be pulled from the
globals of the Start Compartment and ferried through the kernel to the vat
manager factory that calls makeLiveSlots.

This gives the outer layer of the vat (liveslots) access to nondeterminism.
We rely upon liveslots to not share this power with the user-level ocap-style
"vat code". Liveslots must never allow user-level code to observe behavior
that depends upon GC activity, because that activity is not part of the
specified input to the vat.

refs #1872
  • Loading branch information
warner committed Oct 26, 2020
1 parent 54eea62 commit 5afcfeb
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 13 deletions.
4 changes: 3 additions & 1 deletion packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global Compartment */
/* global Compartment WeakRef FinalizationRegistry */

import fs from 'fs';
import path from 'path';
Expand Down Expand Up @@ -183,6 +183,8 @@ export async function makeSwingsetController(
startSubprocessWorkerNode,
startSubprocessWorkerXS,
writeSlogObject,
WeakRef,
FinalizationRegistry,
};

const kernelOptions = { verbose };
Expand Down
4 changes: 4 additions & 0 deletions packages/SwingSet/src/kernel/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export default function buildKernel(
startSubprocessWorkerNode,
startSubprocessWorkerXS,
writeSlogObject,
WeakRef,
FinalizationRegistry,
} = kernelEndowments;
deviceEndowments = { ...deviceEndowments }; // copy so we can modify
const { verbose } = kernelOptions;
Expand Down Expand Up @@ -529,6 +531,7 @@ export default function buildKernel(
}
}

const gcTools = harden({ WeakRef, FinalizationRegistry });
const vatManagerFactory = makeVatManagerFactory({
allVatPowers,
kernelKeeper,
Expand All @@ -540,6 +543,7 @@ export default function buildKernel(
makeNodeWorker,
startSubprocessWorkerNode,
startSubprocessWorkerXS,
gcTools,
});

function buildVatSyscallHandler(vatID, translators) {
Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/src/kernel/vatManager/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function makeVatManagerFactory({
makeNodeWorker,
startSubprocessWorkerNode,
startSubprocessWorkerXS,
gcTools,
}) {
const localFactory = makeLocalVatManagerFactory({
allVatPowers,
Expand All @@ -22,6 +23,7 @@ export function makeVatManagerFactory({
meterManager,
transformMetering,
waitUntilQuiescent,
gcTools,
});

const nodeWorkerFactory = makeNodeWorkerVatManagerFactory({
Expand Down
3 changes: 2 additions & 1 deletion packages/SwingSet/src/kernel/vatManager/localVatManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export function makeLocalVatManagerFactory(tools) {
meterManager,
transformMetering,
waitUntilQuiescent,
gcTools,
} = tools;

const { makeGetMeter, refillAllMeters, stopGlobalMeter } = meterManager;
Expand Down Expand Up @@ -107,7 +108,7 @@ export function makeLocalVatManagerFactory(tools) {

// we might or might not use this, depending upon whether the vat exports
// 'buildRootObject' or a default 'setup' function
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters);
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters, gcTools);

let meterRecord = null;
if (metered) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// this file is loaded at the start of a new Worker, which makes it a new JS
// environment (with it's own Realm), so we must install-ses too.
/* global WeakRef FinalizationRegistry */
import '@agoric/install-ses';
import { parentPort } from 'worker_threads';
import anylogger from 'anylogger';
Expand Down Expand Up @@ -113,7 +114,8 @@ parentPort.on('message', ([type, ...margs]) => {
makeMarshal,
testLog,
};
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters);
const gcTools = harden({ WeakRef, FinalizationRegistry });
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters, gcTools);

const endowments = {
...ls.vatGlobals,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// this file is loaded at the start of a new subprocess
/* global WeakRef FinalizationRegistry */
import '@agoric/install-ses';

import anylogger from 'anylogger';
Expand Down Expand Up @@ -133,7 +134,8 @@ fromParent.on('data', ([type, ...margs]) => {
makeMarshal,
testLog,
};
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters);
const gcTools = harden({ WeakRef, FinalizationRegistry });
const ls = makeLiveSlots(syscall, vatID, vatPowers, vatParameters, gcTools);

const endowments = {
...ls.vatGlobals,
Expand Down
3 changes: 3 additions & 0 deletions packages/SwingSet/test/test-kernel.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global WeakRef FinalizationRegistry */
import '@agoric/install-ses';
import test from 'ava';
import anylogger from 'anylogger';
Expand Down Expand Up @@ -49,6 +50,8 @@ function makeEndowments() {
hostStorage: initSwingStore().storage,
runEndOfCrank: () => {},
makeConsole,
WeakRef,
FinalizationRegistry,
};
}

Expand Down
10 changes: 9 additions & 1 deletion packages/SwingSet/test/test-liveslots.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global WeakRef FinalizationRegistry */
import '@agoric/install-ses';
import test from 'ava';
import { E } from '@agoric/eventual-send';
Expand Down Expand Up @@ -37,7 +38,14 @@ function buildSyscall() {
}

function makeDispatch(syscall, build) {
const { setBuildRootObject, dispatch } = makeLiveSlots(syscall, 'vatA');
const gcTools = harden({ WeakRef, FinalizationRegistry });
const { setBuildRootObject, dispatch } = makeLiveSlots(
syscall,
'vatA',
{},
{},
gcTools,
);
setBuildRootObject(build);
return dispatch;
}
Expand Down
15 changes: 9 additions & 6 deletions packages/SwingSet/test/test-marshal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global WeakRef FinalizationRegistry */
import '@agoric/install-ses';
import test from 'ava';
import { makePromiseKit } from '@agoric/promise-kit';
Expand All @@ -6,14 +7,16 @@ import { makeMarshaller } from '../src/kernel/liveSlots';

import { buildVatController } from '../src/index';

const gcTools = harden({ WeakRef, FinalizationRegistry });

async function prep() {
const config = {};
const controller = await buildVatController(config);
await controller.run();
}

test('serialize exports', t => {
const { m } = makeMarshaller();
const { m } = makeMarshaller(undefined, gcTools);
const ser = val => m.serialize(val);
const o1 = harden({});
const o2 = harden({
Expand All @@ -38,7 +41,7 @@ test('serialize exports', t => {

test('deserialize imports', async t => {
await prep();
const { m } = makeMarshaller();
const { m } = makeMarshaller(undefined, gcTools);
const a = m.unserialize({
body: '{"@qclass":"slot","index":0}',
slots: ['o-1'],
Expand All @@ -63,7 +66,7 @@ test('deserialize imports', async t => {
});

test('deserialize exports', t => {
const { m } = makeMarshaller();
const { m } = makeMarshaller(undefined, gcTools);
const o1 = harden({});
m.serialize(o1); // allocates slot=1
const a = m.unserialize({
Expand All @@ -75,7 +78,7 @@ test('deserialize exports', t => {

test('serialize imports', async t => {
await prep();
const { m } = makeMarshaller();
const { m } = makeMarshaller(undefined, gcTools);
const a = m.unserialize({
body: '{"@qclass":"slot","index":0}',
slots: ['o-1'],
Expand All @@ -94,7 +97,7 @@ test('serialize promise', async t => {
},
};

const { m } = makeMarshaller(syscall);
const { m } = makeMarshaller(syscall, gcTools);
const { promise, resolve } = makePromiseKit();
t.deepEqual(m.serialize(promise), {
body: '{"@qclass":"slot","index":0}',
Expand Down Expand Up @@ -130,7 +133,7 @@ test('unserialize promise', async t => {
},
};

const { m } = makeMarshaller(syscall);
const { m } = makeMarshaller(syscall, gcTools);
const p = m.unserialize({
body: '{"@qclass":"slot","index":0}',
slots: ['p-1'],
Expand Down
3 changes: 3 additions & 0 deletions packages/SwingSet/test/test-vpid-kernel.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global WeakRef FinalizationRegistry */
// eslint-disable-next-line no-redeclare

import '@agoric/install-ses';
Expand Down Expand Up @@ -36,6 +37,8 @@ function makeEndowments() {
hostStorage: initSwingStore().storage,
runEndOfCrank: () => {},
makeConsole,
WeakRef,
FinalizationRegistry,
};
}

Expand Down
11 changes: 9 additions & 2 deletions packages/SwingSet/test/test-vpid-liveslots.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// eslint-disable-next-line no-redeclare
/* global setImmediate */
/* global setImmediate WeakRef FinalizationRegistry */

import '@agoric/install-ses';
import test from 'ava';
Expand Down Expand Up @@ -190,7 +190,14 @@ function resolutionOf(vpid, mode, targets) {
}

function makeDispatch(syscall, build) {
const { setBuildRootObject, dispatch } = makeLiveSlots(syscall, 'vatA');
const gcTools = harden({ WeakRef, FinalizationRegistry });
const { setBuildRootObject, dispatch } = makeLiveSlots(
syscall,
'vatA',
{},
{},
gcTools,
);
setBuildRootObject(build);
return dispatch;
}
Expand Down

0 comments on commit 5afcfeb

Please sign in to comment.