[v8 team proposal] JavaScript WeakRefs
marjakh opened this issue · comments
Session Title:
JavaScript WeakRefs
Session Abstract:
WeakRefs are an upcoming language feature (Stage 2 at the moment); I'll explain how weak references work and demo the feature in Google Chrome.
Spec draft: https://weakrefs.netlify.com/
Approximate Duration:
30 min
Your Name:*
Marja Hölttä
Your Twitter handle:*
marjakh
Requirements:
[ ] No
[X] Yes => Please share what do you need.
Projector + adapter for connecting my laptop: Debian Linux, HDMI.
(Last year it was only possible to use the projector if you were at the back of the room; that doesn't work well!)
Complexity:
[X] Advanced
[X] Intermediate
[ ] Beginner
Other information:
This session might not happen if I can't make it to the conference (there's no backup).
Hi Marja! Thank you very much for your talk at JS Kongress Deep-Track!
I want to experiment with WeakRefs, what version of V8/Chrome should I use and what flags should I turn on? Also I'd be very grateful if you can share your slides.
Hi, glad that you liked the talk :)
Chrome version: 74
Flags: "--js-flags=--harmony-weak-refs --expose-gc"
Here are the demos:
<html>
<head>
<script>
function log(msg) {
document.getElementById("log").innerHTML += msg + "<br>";
}
let wr;
let stored_resolve;
function demo() {
log("Starting");
}
function createWeakRef() {
let o = {hello: function() {log("Hello!");}};
wr = new WeakRef(o);
log("Created WeakRef");
// o goes out of scope
}
function peekWeakRef() {
if (wr.deref()) {
// GC can happen any time!
log("WeakRef is alive");
// KeepDuringJob -> ref kept alive.
wr.deref().hello();
} else {
log("WeakRef is dead");
}
// If we did this: let o = wr.deref(); that'd be a strong pointer to
// the object.
}
function doGC() {
log("Doing GC");
gc();
}
function peekAndGC() {
if (wr.deref()) {
log("WeakRef is alive");
log("Doing GC");
gc();
if (wr.deref()) {
log("WeakRef is still alive");
} else {
log("This should never happen!");
}
} else {
log("WeakRef is dead");
}
}
async function awaitCaveat() {
if (wr.deref()) {
log("WeakRef is alive, let's await...");
prom = new Promise(function(resolve) {
stored_resolve = resolve;
});
await prom;
// Not the same job anymore; KeepDuringJob doesn't help!
log("await returned");
if (wr.deref()) {
log("WeakRef is alive after await");
} else {
log("WeakRef died during await");
}
}
}
function doGCAndResolve() {
log("Doing GC");
gc();
log("Resolving promise");
stored_resolve();
}
</script>
</head>
<body onload="demo()">
<div>This is Google Chrome Dev (version 74) started with "--js-flags=--harmony-weak-refs --expose-gc"</div>
<div>Tell us what you think of weak refs! marja@chromium.org & gsathya@chromium.org</div>
<button onClick="createWeakRef()">Create WeakRef</button>
<button onClick="peekWeakRef()">Peek WeakRef</button>
<button onClick="doGC()">GC</button>
<button onClick="peekAndGC()">Peek and GC</button>
<button onClick="awaitCaveat()">Await</button>
<button onClick="doGCAndResolve()()">GC and resolve</button>
<br>
<br>
<div id="log"></div>
</body>
</html>
and
<html>
<head>
<script>
function log(msg) {
document.getElementById("log").innerHTML += msg + "<br>";
}
let fg;
let count = 0;
function demo() {
log("Starting");
let cleanup = function(iter) {
log("Cleanup");
for (h of iter) {
// Here we get the holdings, not the object. The object is
// already dead! Here we cannot resurrect it.
log("Got holdings: " + h);
}
}
fg = new FinalizationGroup(cleanup);
}
function createObjectAndRegister() {
let o = {};
let holdings = "object number " + ++count;
log("Created " + holdings);
fg.register(o, holdings);
// o goes out of scope
}
function doGC() {
log("Doing GC");
gc();
}
</script>
</head>
<body onload="demo()">
<div>This is Google Chrome Dev (version 74) started with "--js-flags=--harmony-weak-refs --expose-gc"</div>
<div>Tell us what you think of weak refs! marja@chromium.org & gsathya@chromium.org</div>
<button onClick="createObjectAndRegister()">Create object</button>
<button onClick="doGC()">GC</button>
<br>
<br>
<div id="log"></div>
</body>
</html>
Thank you, Marja!