Skip to content

Commit

Permalink
Merge pull request #7138 from Agoric/6693-vo-lru-cache
Browse files Browse the repository at this point in the history
rewrite VOM LRU cache
  • Loading branch information
mergify[bot] authored Apr 5, 2023
2 parents 826ecac + 99522ea commit 8e6a425
Show file tree
Hide file tree
Showing 42 changed files with 1,428 additions and 968 deletions.
1 change: 0 additions & 1 deletion packages/SwingSet/src/controller/initializeKernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
'managerType',
'enableDisavow',
'enableSetup',
'virtualObjectCacheSize',
'useTranscript',
'critical',
'reapInterval',
Expand Down
1 change: 0 additions & 1 deletion packages/SwingSet/src/kernel/vat-loader/manager-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export function makeVatManagerFactory({
'metered',
'enableDisavow',
'enableSetup',
'virtualObjectCacheSize',
'useTranscript',
'critical',
'reapInterval',
Expand Down
3 changes: 0 additions & 3 deletions packages/SwingSet/src/kernel/vat-loader/vat-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export function makeVatLoader(stuff) {
'enableDisavow',
'enableSetup',
'enablePipelining',
'virtualObjectCacheSize',
'useTranscript',
'critical',
'reapInterval',
Expand Down Expand Up @@ -92,7 +91,6 @@ export function makeVatLoader(stuff) {
enableSetup = false,
enableDisavow = false,
enablePipelining = false,
virtualObjectCacheSize,
useTranscript = true,
critical = false,
name,
Expand Down Expand Up @@ -128,7 +126,6 @@ export function makeVatLoader(stuff) {
...overrideVatManagerOptions,
};
const liveSlotsOptions = {
virtualObjectCacheSize,
enableDisavow,
relaxDurabilityRules: kernelKeeper.getRelaxDurabilityRules(),
};
Expand Down
1 change: 0 additions & 1 deletion packages/SwingSet/src/types-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ export {};
* waiting for the promises to be resolved. If false, such
* messages will be queued inside the kernel. Defaults to
* false.
* @property { number } [virtualObjectCacheSize]
* @property { boolean } [useTranscript]
* If true, saves a transcript of a vat's inbound deliveries and
* outbound syscalls so that the vat's internal state can be
Expand Down
1 change: 0 additions & 1 deletion packages/SwingSet/src/types-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export {};
* critical: boolean,
* enableDisavow: boolean,
* useTranscript: boolean,
* virtualObjectCacheSize: number,
* name: string,
* compareSyscalls?: (originalSyscall: {}, newSyscall: {}) => Error | undefined,
* sourcedConsole: Pick<Console, 'debug' | 'log' | 'info' | 'warn' | 'error'>,
Expand Down
6 changes: 0 additions & 6 deletions packages/SwingSet/src/vats/vat-admin/vat-vat-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,6 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
'invalid reapInterval value',
);
break;
case 'virtualObjectCacheSize':
assert(isNat(value), 'invalid virtualObjectCacheSize value');
break;
default:
assert.fail(`invalid option "${option}"`);
}
Expand Down Expand Up @@ -357,7 +354,6 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
vatParameters, // stripped out and re-added
enableSetup,
enablePipelining,
virtualObjectCacheSize,
useTranscript,
reapInterval,
critical, // converted from cap key to boolean
Expand Down Expand Up @@ -391,7 +387,6 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
}
assertType('enableSetup', enableSetup, 'boolean');
assertType('enablePipelining', enablePipelining, 'boolean');
assertType('virtualObjectCacheSize', virtualObjectCacheSize, 'number');
assertType('useTranscript', useTranscript, 'boolean');
assertType('reapInterval', reapInterval, 'number');

Expand Down Expand Up @@ -423,7 +418,6 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
vatParameters,
enableSetup,
enablePipelining,
virtualObjectCacheSize,
useTranscript,
reapInterval,
critical: isCriticalVat,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,11 @@ async function testChangeParameters(t) {
t.is(c1Status, 'fulfilled');
t.is(c1Result, 'invalid option "foo"');

const [c2Status, c2Result] = await run('change', [
{ virtualObjectCacheSize: -1 },
]);
t.is(c2Status, 'fulfilled');
t.is(c2Result, 'invalid virtualObjectCacheSize value');

const [c3Status, c3Result] = await run('change', [{ reapInterval: 'maybe' }]);
t.is(c3Status, 'fulfilled');
t.is(c3Result, 'invalid reapInterval value');

const [c4Status, c4Result] = await run('change', [
{ virtualObjectCacheSize: 100, reapInterval: 20 },
]);
const [c4Status, c4Result] = await run('change', [{ reapInterval: 20 }]);
t.is(c4Status, 'fulfilled');
t.is(c4Result, 'ok');
t.is(kvStore.get('v6.reapInterval'), '20');
Expand Down
8 changes: 0 additions & 8 deletions packages/SwingSet/test/upgrade/vat-ulrik-1.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const holderMethods = {
};
const makeVir = defineKind('virtual', initHolder, holderMethods);
const makeDur = defineDurableKind(durandalHandle, initHolder, holderMethods);
const makeDummy = defineKind('dummy', initHolder, holderMethods);

// TODO: explore 'export modRetains'
// eslint-disable-next-line no-unused-vars
Expand Down Expand Up @@ -115,13 +114,6 @@ const buildExports = (baggage, imp) => {
baggage.init('dur37', dur[37]);
baggage.init('imp38', imp[38]);

// we set virtualObjectCacheSize=0 to ensure all data writes are
// made promptly, But the cache will still retain the last
// Representative, which inhibits GC. So the last thing we do here
// should be to create/deserialize a throwaway object, to
// flush the last dur/vir/vc/dc from the cache.
makeDummy();

// we share dur1/vir2 with the test harness so it can glean the
// baserefs and interpolate the full vrefs for everything else
// without holding a GC pin on them
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ test.serial('replay does not resurrect dead vat', async t => {
const configPath = new URL('swingset-no-zombies.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';

const ss1 = initSwingStore();
{
Expand Down
7 changes: 7 additions & 0 deletions packages/SwingSet/test/vat-admin/terminate/test-terminate.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ async function doTerminateNonCritical(
const configPath = new URL('swingset-terminate.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const kernelStorage = initSwingStore().kernelStorage;
const controller = await buildVatController(config, [], {
...t.context.data,
Expand Down Expand Up @@ -104,6 +105,7 @@ async function doTerminateCritical(
const configPath = new URL('swingset-terminate.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const kernelStorage = initSwingStore().kernelStorage;
const controller = await buildVatController(config, [], {
...t.context.data,
Expand Down Expand Up @@ -374,6 +376,7 @@ test.serial('exit with presence', async t => {
const configPath = new URL('swingset-die-with-presence.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const controller = await buildVatController(config, [], t.context.data);
t.teardown(controller.shutdown);
await controller.run();
Expand All @@ -389,6 +392,7 @@ test.serial('dispatches to the dead do not harm kernel', async t => {
const configPath = new URL('swingset-speak-to-dead.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';

const ss1 = initSwingStore();
{
Expand Down Expand Up @@ -432,6 +436,7 @@ test.serial('invalid criticalVatKey causes vat creation to fail', async t => {
const configPath = new URL('swingset-bad-vat-key.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const controller = await buildVatController(config, [], t.context.data);
t.teardown(controller.shutdown);
await t.throwsAsync(() => controller.run(), {
Expand All @@ -443,6 +448,7 @@ test.serial('dead vat state removed', async t => {
const configPath = new URL('swingset-die-cleanly.json', import.meta.url)
.pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const { kernelStorage, debug } = initSwingStore();

const controller = await buildVatController(config, [], {
Expand Down Expand Up @@ -480,6 +486,7 @@ test.serial('terminate with presence', async t => {
import.meta.url,
).pathname;
const config = await loadSwingsetConfigFile(configPath);
config.defaultReapInterval = 'never';
const controller = await buildVatController(config, [], t.context.data);
t.teardown(controller.shutdown);
await controller.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ test('collection entry slots trigger doMoreGC', async t => {
bootstrap: { sourceSpec: bfile('bootstrap-collection-slots.js') },
target: {
sourceSpec: bfile('vat-collection-slots.js'),
creationOptions: {
virtualObjectCacheSize: 0,
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ test('VO property deletion is not short-circuited', async t => {
bootstrap: { sourceSpec: bfile('bootstrap-delete-stored-vo.js') },
target: {
sourceSpec: bfile('vat-delete-stored-vo.js'),
creationOptions: {
virtualObjectCacheSize: 0,
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ export function buildRootObject() {
async build() {
// build the target vat
const bcap = await E(vatAdmin).getNamedBundleCap('dri');
const options = {};
options.virtualObjectCacheSize = 0;
const res = await E(vatAdmin).createVat(bcap, options);
const res = await E(vatAdmin).createVat(bcap);
root = res.root;
await E(root).buildVir(sensor0, sensor1);
await E(root).ping();
Expand Down
31 changes: 18 additions & 13 deletions packages/SwingSet/test/virtualObjects/test-facet-retention.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,14 @@ import { kunser } from '../../src/lib/kmarshal.js';
// Representative objects). All facets of a given cohort/instance
// share the same 'context' object.

// Currently, we create the 'context' and 'state' objects via an LRU
// cache, so their lifetime is somewhat complicated, but still a
// deterministic function of userspace behavior.
// In any given crank, a new 'context'/'state' object pair is created
// the first time a VO method is invoked, and is given to all VO
// method invocations within that crank. They remain functional
// forever. The VOM discards the context/state pair at end-of-crank,
// and will make new ones in subsequent cranks (if they invoke VO
// methods again). Userspace might retain either one, and use them in
// a recognizer, but their lifetime is not related to VO GC behavior,
// so they do not provide a GC sensor, merely a crank sensor.

// The 'facets' cohort is a record, one property per facet. So a
// defineKindMulti with a pair of `incrementer` and `decrementer`
Expand Down Expand Up @@ -150,16 +155,16 @@ test('retention', async t => {
await go('multi', 'method', 'weakset', true);
await go('multi', 'proto', 'weakset', true);

// 'context' currently shares a lifetime with the facet cluster
await go('single', 'context', 'retain', true);
await go('multi', 'context', 'retain', true);
await go('single', 'context', 'weakset', true);
await go('multi', 'context', 'weakset', true);
// as does 'state'
await go('single', 'state', 'retain', true);
await go('multi', 'state', 'retain', true);
await go('single', 'state', 'weakset', true);
await go('multi', 'state', 'weakset', true);
// 'context' is remade on each crank
await go('single', 'context', 'retain', false);
await go('multi', 'context', 'retain', false);
await go('single', 'context', 'weakset', false);
await go('multi', 'context', 'weakset', false);
// as is 'state'
await go('single', 'state', 'retain', false);
await go('multi', 'state', 'retain', false);
await go('single', 'state', 'weakset', false);
await go('multi', 'state', 'weakset', false);

if (remaining.size) {
const missed = [...remaining].join(', ');
Expand Down
Loading

0 comments on commit 8e6a425

Please sign in to comment.