00:48 | <Richard Gibson> | ljharb: I have a not-yet-committed version of what you're looking for; the ultimate fallback really is memory allocations. Simplified version:
const enqueueTask = callback => {
const id = setTimeout(callback);
return () => clearTimeout(id);
};
const gcWatches = new FinalizationRegistry(([callback, data]) => void callback(data));
const whenCollected = (target, data = undefined) =>
new Promise(resolve => gcWatches.register(target, [resolve, data]));
const watchGC = (target, data = undefined) => {
const collected = whenCollected(target, data);
let retained = true;
collected.then(() => { retained = false; });
// Return a new promise that waits for GC plus a turn (in case the GC promise
// of the new sentinel object fulfills before that of the target) and then
// fulfills with the then-current retention status of the target.
const isRetained = () => whenCollected({}).then().then(() => retained);
return { collected, isRetained };
};
const forceCollectionP = (async () => {
let garbageScale = 2 ** 16;
const tryTriggerGC = () => void new Uint8Array(garbageScale);
const forceGC = async (patience = 1000) => {
const sentinelCollectedP = whenCollected({});
// Wait a turn to clear the stack, then add pressure in a sequence of prompt jobs.
await null;
let reject;
const pressureP = new Promise((...resolvers) => { reject = resolvers[1]; });
void pressureP.catch(() => {});
let jobCount = 0;
let abortNextJob = () => {};
const abort = () => {
abortNextJob();
reject();
patience = 0;
};
(function startNextJob() {
if (!(jobCount < patience)) return reject(Error(`failed to GC after ${jobCount} attempts`));
tryTriggerGC();
jobCount++;
abortNextJob = enqueueTask(startNextJob);
})();
await Promise.race([sentinelCollectedP, pressureP]);
abort();
// Try to tune garbageScale for forcing GC in one job.
if (jobCount > 1 && garbageScale > 0 && garbageScale < 2 ** 28) garbageScale *= 2;
return { jobCount };
};
// Run sanity checks before releasing the function.
await forceGC();
const weakmap = new WeakMap();
let { fastKeyWatch, slowKeyWatch, slowKey } = (() => {
const fastKey = {};
const slowKey = {};
weakmap.set(fastKey, 'fast-gc sanity check');
weakmap.set(slowKey, 'slow-gc sanity check');
const fastKeyWatch = watchGC(fastKey);
const slowKeyWatch = watchGC(slowKey);
return { fastKeyWatch, slowKeyWatch, slowKey };
})();
const fastKeyRetainedP = fastKeyWatch.isRetained();
const slowKeyRetainedP = slowKeyWatch.isRetained();
await forceGC();
if (await fastKeyRetainedP) throw Error('fast-gc key was not collected!');
if (!(await slowKeyRetainedP)) throw Error('slow-gc key was collected early!');
const slowKeyStillRetainedP = slowKeyWatch.isRetained();
slowKey = null;
await forceGC();
if (await slowKeyStillRetainedP) throw Error('slow-gc key was not collected!');
return forceGC;
})();
const forceGC = await forceCollectionP;
|
03:05 | <Domenic> | Bikeshedding help requested for an error type that includes properties with how much X is available, versus how much X you requested: https://github.com/whatwg/webidl/issues/1463 |
20:29 | <Matthew Dean> | Hi all! |
20:30 | <Matthew Dean> | How would one submit a proposal to TC39? |
20:30 | <Michael Ficarra> | https://github.com/tc39/ecma262/blob/main/CONTRIBUTING.md |
20:32 | <Matthew Dean> | 🤔 I've been going through that, and I see that proposals are separate repos... but... you can't make a PR to submit a whole repo, can you? |
20:32 | <Matthew Dean> | It's related to: https://github.com/matthew-dean/proposal-hash-comments |
20:32 | <Michael Ficarra> | yes, proposals are self-contained repos |
20:32 | <Michael Ficarra> | they don't become PRs until much later in the process |
20:33 | <Matthew Dean> | How would I move this under tc39 though? |
20:34 | <Michael Ficarra> | from the CONTRIBUTING.md document,
If you have a new proposal you want to get into the language, you first need a TC39 "champion": a member of the committee who will make the case for the proposal at in-person TC39 meetings and help it move through the process. If you are a TC39 member, you can be a champion; otherwise, find a TC39 member to work with for this (e.g., through the TC39 discussion group or the Matrix chat room). Proposals may have multiple champions (a "champion group").
|
20:34 | <Matthew Dean> | ah ok |
20:34 | <Matthew Dean> | So I have to find my champion a la Game of Thrones-style? |
20:35 | <Michael Ficarra> | so you'll need to convince at least one delegate that it's worthwhile, and once it has been presented, it will be moved within the TC39 org |
20:35 | <Matthew Dean> | got it |
20:35 | <Michael Ficarra> | not familiar with the GoT process, but you can find champions both on here or on Discourse |
20:36 | <Michael Ficarra> | Discourse is probably better since it's less synchronous and less ephemeral |
20:36 | <Matthew Dean> | The Game of Thrones was a dumb joke reference to an episode |
20:38 | <Matthew Dean> | But anyway, thanks for the help! |
20:43 | <Michael Ficarra> | no problem |