Skip to content

Instantly share code, notes, and snippets.

@jcmoore
Last active November 21, 2015 15:16
Show Gist options
  • Save jcmoore/1fc557d421e81686a1b3 to your computer and use it in GitHub Desktop.
Save jcmoore/1fc557d421e81686a1b3 to your computer and use it in GitHub Desktop.
tube.js
// node --harmony --trace_opt --trace_deopt --allow-natives-syntax --trace-inlining tube.js
function crankShaft (method) {
return %OptimizeFunctionOnNextCall(method);
}
function printStatus(fn) {
switch(%GetOptimizationStatus(fn)) {
case 1: console.log("Function is optimized"); break;
case 2: console.log("Function is not optimized"); break;
case 3: console.log("Function is always optimized"); break;
case 4: console.log("Function is never optimized"); break;
case 6: console.log("Function is maybe deoptimized"); break;
}
}
var tube = (function () {
function Pipe (pipe, push, pull) {
this.opi = null;
this.val = null;
this.push = null;
this.pull = null;
this.push = push || null;
this.pull = pull || null;
}
Pipe.prototype.send = function (method, context) {
var pipe = this;
pipe.val = method ? method.call(context, pipe.val) : context;
pipe.push && pipe.push(pipe.val);
pipe.pull && pipe.pull(pipe.val);
return pipe.opi;
}
function make (upstream, push, pull) {
var pipe = new Pipe(upstream || null, push, pull);
return pipe.opi = function opi (directive, method, context) {
"use strict";
// var pipe = this; // preferable -- but opi.bind(new Pipe()) won't optimize
if (!arguments.length) {
return pipe.val;
}
switch (String(directive)) {
default: throw new Error("unhandled directive");
case "pipe": return make(pipe, method, context);
case "send": return pipe.send(method, context);
}
return null;
};
}
return function api (directive, method, context) {
switch (String(directive)) {
default: throw new Error("unhandled directive");
case "make": return make(null, method, context);
case "opt": crankShaft(Pipe.prototype.send); break;
case "check": printStatus(Pipe.prototype.send); break;
case "test": return new Pipe(null, null, null).send(method, context); }
return null;
};
}());
(function () {
var a = tube("make",
push => (console.log("push", push), push),
pull => (console.log("pull", pull), pull));
// 2 calls are needed to go from uninitialized -> pre-monomorphic -> monomorphic
a("send", null, {x:1});
console.log(a());
a("send", null, {y:2});
console.log(a());
a("send", null, {z:3});
console.log(a());
a("send", null, {i:7});
console.log(a());
a("send", null, {j:8});
console.log(a());
a("send", null, {k:9});
console.log(a());
tube("opt");
if (Math.round(Math.random())) {
console.log("opt out");
} else {
console.log("opt in");
tube("make",
push => (console.log("~>", push), push),
pull => (console.log("<~", pull), pull))
("send", null, {n: 5});
}
crankShaft(a);
//The next call
a("send", null, {w:4});
console.log(a());
tube("make",
push => (console.log(">>=", push), push),
pull => (console.log("<<=", pull), pull))
("send", null, {m: 6});
//Check
tube("check");
printStatus(a);
printStatus(tube("make",
push => (console.log("!", push), push),
pull => (console.log("?", pull), pull)));
tube("test", null, null);
tube("check");
printStatus(a);
a();
printStatus(a);
}());
@jcmoore
Copy link
Author

jcmoore commented Nov 21, 2015

stdout from a run that fails to optimize Pipe.prototype.send:

[deoptimize global object @ 0x1e11b25106e9]
push { x: 1 }
pull { x: 1 }
{ x: 1 }
push { y: 2 }
pull { y: 2 }
{ y: 2 }
push { z: 3 }
pull { z: 3 }
{ z: 3 }
push { i: 7 }
pull { i: 7 }
{ i: 7 }
push { j: 8 }
pull { j: 8 }
{ j: 8 }
push { k: 9 }
pull { k: 9 }
{ k: 9 }
opt out
Inlined Pipe.send called from opi.
[optimizing 0xf1e6bd21cf9 <JS Function opi (SharedFunctionInfo 0xf1e6bd21b89)> - took 0.309, 0.322, 0.163 ms]
push { w: 4 }
pull { w: 4 }
{ w: 4 }
>>= { m: 6 }
<<= { m: 6 }
Function is not optimized
Function is optimized

@jcmoore
Copy link
Author

jcmoore commented Nov 21, 2015

stdout from a run that successfully optimizes Pipe.prototype.send:

[deoptimize global object @ 0x3df9961106e9]
push { x: 1 }
pull { x: 1 }
{ x: 1 }
push { y: 2 }
pull { y: 2 }
{ y: 2 }
push { z: 3 }
pull { z: 3 }
{ z: 3 }
push { i: 7 }
pull { i: 7 }
{ i: 7 }
push { j: 8 }
pull { j: 8 }
{ j: 8 }
push { k: 9 }
pull { k: 9 }
{ k: 9 }
opt in
[optimizing 0x118f85221a49 <JS Function Pipe.send (SharedFunctionInfo 0x118f85220e19)> - took 0.096, 0.218, 0.146 ms]
~> { n: 5 }
<~ { n: 5 }
Inlined Pipe.send called from opi.
[optimizing 0x118f85221cf9 <JS Function opi (SharedFunctionInfo 0x118f85221b89)> - took 0.686, 0.516, 0.186 ms]
push { w: 4 }
pull { w: 4 }
{ w: 4 }
>>= { m: 6 }
<<= { m: 6 }
Function is optimized
Function is optimized

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment