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 7ecc184 commit 3569dd8
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 13 deletions.
3 changes: 3 additions & 0 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { makeMeteringTransformer } from '@agoric/transform-metering';
import { makeTransform } from '@agoric/transform-eventual-send';
import { locateWorkerBin } from '@agoric/xs-vat-worker';

import { WeakRef, FinalizationRegistry } from './weakref';
import { startSubprocessWorker } from './spawnSubprocessWorker';
import { waitUntilQuiescent } from './waitUntilQuiescent';
import { insistStorageAPI } from './storageAPI';
Expand Down Expand Up @@ -183,6 +184,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
Expand Up @@ -7,6 +7,7 @@ import anylogger from 'anylogger';
import { assert } from '@agoric/assert';
import { importBundle } from '@agoric/import-bundle';
import { Remotable, getInterfaceOf, makeMarshal } from '@agoric/marshal';
import { WeakRef, FinalizationRegistry } from '../../weakref';
import { waitUntilQuiescent } from '../../waitUntilQuiescent';
import { makeLiveSlots } from '../liveSlots';

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
Expand Up @@ -7,6 +7,7 @@ import fs from 'fs';
import { assert } from '@agoric/assert';
import { importBundle } from '@agoric/import-bundle';
import { Remotable, getInterfaceOf, makeMarshal } from '@agoric/marshal';
import { WeakRef, FinalizationRegistry } from '../../weakref';
import { arrayEncoderStream, arrayDecoderStream } from '../../worker-protocol';
import {
netstringEncoderStream,
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
Expand Up @@ -2,6 +2,7 @@ import '@agoric/install-ses';
import test from 'ava';
import anylogger from 'anylogger';
import { initSwingStore } from '@agoric/swing-store-simple';
import { WeakRef, FinalizationRegistry } from '../src/weakref';
import { waitUntilQuiescent } from '../src/waitUntilQuiescent';

import buildKernel from '../src/kernel/index';
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,6 +1,7 @@
import '@agoric/install-ses';
import test from 'ava';
import { E } from '@agoric/eventual-send';
import { WeakRef, FinalizationRegistry } from '../src/weakref';
import { waitUntilQuiescent } from '../src/waitUntilQuiescent';
import { makeLiveSlots } from '../src/kernel/liveSlots';

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
Expand Up @@ -2,18 +2,21 @@ import '@agoric/install-ses';
import test from 'ava';
import { makePromiseKit } from '@agoric/promise-kit';

import { WeakRef, FinalizationRegistry } from '../src/weakref';
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
5 changes: 3 additions & 2 deletions packages/SwingSet/test/test-vpid-kernel.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// eslint-disable-next-line no-redeclare

import '@agoric/install-ses';
import test from 'ava';
import anylogger from 'anylogger';
import { initSwingStore } from '@agoric/swing-store-simple';
import { WeakRef, FinalizationRegistry } from '../src/weakref';
import { waitUntilQuiescent } from '../src/waitUntilQuiescent';

import buildKernel from '../src/kernel/index';
Expand Down Expand Up @@ -36,6 +35,8 @@ function makeEndowments() {
hostStorage: initSwingStore().storage,
runEndOfCrank: () => {},
makeConsole,
WeakRef,
FinalizationRegistry,
};
}

Expand Down
10 changes: 9 additions & 1 deletion packages/SwingSet/test/test-vpid-liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import test from 'ava';

import { E } from '@agoric/eventual-send';
import { makePromiseKit } from '@agoric/promise-kit';
import { WeakRef, FinalizationRegistry } from '../src/weakref';
import { makeLiveSlots } from '../src/kernel/liveSlots';

const RETIRE_VPIDS = true;
Expand Down Expand Up @@ -190,7 +191,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 3569dd8

Please sign in to comment.