RESOLVED FIXED 158318
Implement Air::allocateStack() in ES6 to see how much of a bad idea that is
https://bugs.webkit.org/show_bug.cgi?id=158318
Summary Implement Air::allocateStack() in ES6 to see how much of a bad idea that is
Filip Pizlo
Reported 2016-06-02 14:39:24 PDT
We would never actually meta-circulate our engine, because why, but it's useful to see how the kind of code we write would fare if it was written in ES6. I want to know: - Will it work at all? - Will it run without crashing? - How many times slower will it be than C++? These are useful questions to answer, for science.
Attachments
gotta start by dumping Air to a JS data definition (6.12 KB, patch)
2016-06-02 14:41 PDT, Filip Pizlo
no flags
the C++ side may be written (17.44 KB, patch)
2016-06-02 15:20 PDT, Filip Pizlo
no flags
moar (68.96 KB, patch)
2016-06-03 11:33 PDT, Filip Pizlo
no flags
so much fun (79.42 KB, patch)
2016-06-03 12:19 PDT, Filip Pizlo
no flags
a bit more (82.93 KB, patch)
2016-06-03 13:22 PDT, Filip Pizlo
no flags
it grows (106.59 KB, patch)
2016-06-06 13:56 PDT, Filip Pizlo
no flags
a bit more (118.73 KB, patch)
2016-06-06 16:04 PDT, Filip Pizlo
no flags
getting there (157.65 KB, patch)
2016-06-06 20:00 PDT, Filip Pizlo
no flags
added customs (163.35 KB, patch)
2016-06-06 20:37 PDT, Filip Pizlo
no flags
getting pretty close (249.97 KB, patch)
2016-06-07 12:11 PDT, Filip Pizlo
no flags
almost done (258.28 KB, patch)
2016-06-07 12:47 PDT, Filip Pizlo
no flags
the patch (541.28 KB, patch)
2016-06-07 13:54 PDT, Filip Pizlo
saam: review+
almost the patch (541.70 KB, patch)
2016-06-07 14:19 PDT, Filip Pizlo
no flags
Filip Pizlo
Comment 1 2016-06-02 14:41:23 PDT
Created attachment 280369 [details] gotta start by dumping Air to a JS data definition
Filip Pizlo
Comment 2 2016-06-02 15:20:15 PDT
Created attachment 280371 [details] the C++ side may be written Yucky!
Filip Pizlo
Comment 3 2016-06-03 11:33:39 PDT
Filip Pizlo
Comment 4 2016-06-03 12:19:30 PDT
Created attachment 280452 [details] so much fun
Filip Pizlo
Comment 5 2016-06-03 13:22:20 PDT
Created attachment 280456 [details] a bit more
Filip Pizlo
Comment 6 2016-06-06 13:56:20 PDT
Created attachment 280629 [details] it grows Intriguingly, I found some slop in the C++ implementation of Air by rewriting it. This also includes changes to remove dead code and consolidate duplicated code.
Filip Pizlo
Comment 7 2016-06-06 16:04:42 PDT
Created attachment 280642 [details] a bit more
Filip Pizlo
Comment 8 2016-06-06 20:00:28 PDT
Created attachment 280664 [details] getting there
Filip Pizlo
Comment 9 2016-06-06 20:37:01 PDT
Created attachment 280666 [details] added customs
Filip Pizlo
Comment 10 2016-06-07 12:11:59 PDT
Created attachment 280730 [details] getting pretty close
Filip Pizlo
Comment 11 2016-06-07 12:47:47 PDT
Created attachment 280733 [details] almost done
Filip Pizlo
Comment 12 2016-06-07 13:54:49 PDT
Created attachment 280735 [details] the patch
WebKit Commit Bot
Comment 13 2016-06-07 13:57:44 PDT
Attachment 280735 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/b3/air/AirInstInlines.h:43: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:93: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:117: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:194: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:198: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:204: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirArgInlines.h:143: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirArgInlines.h:158: Place brace on its own line for function definitions. [whitespace/braces] [4] Total errors found: 8 in 48 files If any of these errors are false positives, please file a bug against check-webkit-style.
Saam Barati
Comment 14 2016-06-07 14:16:47 PDT
Comment on attachment 280735 [details] the patch View in context: https://bugs.webkit.org/attachment.cgi?id=280735&action=review I'm not going to read every line, but LGTM > PerformanceTests/ChangeLog:21 > + - JSAir's largest hot function, which is anonymous, so we call it by its hash (ACLj8C). Maybe it's worth giving the anonymous function a name? > PerformanceTests/JSAir/benchmark.js:1 > +"use strict"; I think it's nicer for this to go after copyright. It's less likely to be glanced over Same goes for in all other files. > PerformanceTests/JSAir/opcode.js:736 > + break; > + break; Many duplicate breaks > PerformanceTests/JSAir/payload-gbemu-executeIteration.js:1 > +"use strict"; Should we generate a copyright? > Source/JavaScriptCore/b3/air/AirDumpAsJS.h:37 > +// This is a joke. Various operations on Air are interesting from a benchmarking standpoint. We can "This is a joke." => "This is used for benchmarking." > Source/WTF/wtf/PrintStream.h:75 > + void println(const Types&... values) I will actually use this a lot
Saam Barati
Comment 15 2016-06-07 14:18:42 PDT
Comment on attachment 280735 [details] the patch View in context: https://bugs.webkit.org/attachment.cgi?id=280735&action=review > PerformanceTests/ChangeLog:33 > + - Symbol. > + - for-of. > + - arrow functions. > + - Map/Set. > + - let/const. > + - classes. It's worth opening a bug to write a benchmark that uses generators.
Filip Pizlo
Comment 16 2016-06-07 14:19:45 PDT
Created attachment 280737 [details] almost the patch Uploading this to check EWS, but I still need to address Saam's comments.
WebKit Commit Bot
Comment 17 2016-06-07 14:21:35 PDT
Attachment 280737 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/b3/air/AirInstInlines.h:43: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:93: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:117: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:194: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:198: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp:204: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirArgInlines.h:143: Place brace on its own line for function definitions. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/b3/air/AirArgInlines.h:158: Place brace on its own line for function definitions. [whitespace/braces] [4] Total errors found: 8 in 49 files If any of these errors are false positives, please file a bug against check-webkit-style.
Filip Pizlo
Comment 18 2016-06-07 14:23:46 PDT
(In reply to comment #14) > Comment on attachment 280735 [details] > the patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=280735&action=review > > I'm not going to read every line, but LGTM > > > PerformanceTests/ChangeLog:21 > > + - JSAir's largest hot function, which is anonymous, so we call it by its hash (ACLj8C). > > Maybe it's worth giving the anonymous function a name? I'll try to check this. It's probably an arrow function. > > > PerformanceTests/JSAir/benchmark.js:1 > > +"use strict"; > > I think it's nicer for this to go after copyright. It's less likely to be > glanced over > Same goes for in all other files. I wasn't sure if that worked or not. I'll fix this. > > > PerformanceTests/JSAir/opcode.js:736 > > + break; > > + break; > > Many duplicate breaks Yeah, this is generated code. The code generator isn't that smart. It does the same thing when generating C++ code, and we make the compiler happy by wrapping the breaks inside some horror. > > > PerformanceTests/JSAir/payload-gbemu-executeIteration.js:1 > > +"use strict"; > > Should we generate a copyright? Hmmm. I don't know how to copyright it to. I think that saying that it's generated code conveys the right message. > > > Source/JavaScriptCore/b3/air/AirDumpAsJS.h:37 > > +// This is a joke. Various operations on Air are interesting from a benchmarking standpoint. We can > > "This is a joke." => "This is used for benchmarking." Right. :-) > > > Source/WTF/wtf/PrintStream.h:75 > > + void println(const Types&... values) > > I will actually use this a lot
Joseph Pecoraro
Comment 19 2016-06-07 15:00:12 PDT
Comment on attachment 280737 [details] almost the patch View in context: https://bugs.webkit.org/attachment.cgi?id=280737&action=review Neat! I pointed out some places where you could use a few more ES6 features / syntax, since that seemed to be a goal. > PerformanceTests/JSAir/arg.js:83 > + switch (role) > + { Weird style. > PerformanceTests/JSAir/basic_block.js:76 > + get: function(target, property) { Style: With ES6 shorthand style you could write these as: get(target, property) { ... }, set(target, property, value) { ... } You use this pattern in other places. > PerformanceTests/JSAir/code.js:41 > + addBlock(frequency) > + { > + if (frequency == null) > + frequency = 1; You use this pattern a bunch. If you want to use more ES6 features you could test default parameter values: addBlock(frequency=1) > PerformanceTests/JSAir/code.js:49 > + let result = addIndexed(this._stackSlots, StackSlot, byteSize, kind); > + return result; Drop the temporary variable and make this a tail call? > PerformanceTests/JSAir/code.js:55 > + let result = addIndexed(this["_" + symbolName(type).toLowerCase() + "Tmps"], Tmp, type); > + return result; Drop the temporary variable and make this a tail call? > PerformanceTests/JSAir/code.js:96 > + if (this._frameSize) > + result += "Frame size: " + this._frameSize + "\n"; > + if (this._callArgAreaSize) > + result += "Call arg area size: " + this._callArgAreaSize + "\n"; If you want to test more ES6 features, you could use template strings and interpolation in a lot of these toString methods and other places: if (this._frameSize) result += `Frame size: ${this._frameSize}\n`; if (this._callArgAreaSize) result += `Call arg area size: ${this._callArgAreaSize}\n`; > PerformanceTests/JSAir/custom.js:56 > + for (let i = 0; i < inst.args.length; ++i) { > + inst.visitArg( > + i, func, inst.patchArgData[i].role, inst.patchArgData[i].type, > + inst.patchArgData[i].width); > + } You could make use of ES6 destructuring here: let {role, type, width} = inst.patchArgData[i]; inst.visitArg(i, func, role, type, width); > PerformanceTests/JSAir/inst.js:130 > + return "" + symbolName(this._opcode) + " " + this._args.join(", "); The "" + at the start seems unnecessary. symbolName appears to always return a string. > PerformanceTests/JSAir/opcode.js:143 > + case Nop: > + break; > + break; A lot of these seem to have duplicate breaks. Might be worth cleaning up in the generator, but ultimately harmless. > PerformanceTests/JSAir/test.html:28 > + document.getElementById("result-summary").innerHTML = "That took " + result + " ms."; You could use `textContent` or `innerText` instead of `innerHTML`: <http://caniuse.com/#search=textContent> > PerformanceTests/JSAir/util.js:34 > +function addIndexed(list, cons, ...args) > +{ > + let result = new cons(list.length, ...args); You have this pattern in a few places. It reminds me of bug 158438. > PerformanceTests/JSAir/util.js:170 > +else if (preciseTime) This should probably be "if (this.preciseTime)" otherwise you will get a ReferenceError in environments that do not have `global.performance` and no preciseTime global, which I bet would be the case in node/v8. > PerformanceTests/JSAir/util.js:173 > +else > + currentTime = function() { return 0 + new Date(); }; When I run this in the console I get: js> (0 + new Date()) "0Tue Jun 07 2016 14:34:10 GMT-0700 (PDT)" You should probably just do: Date.now() Or: +new Date > Source/JavaScriptCore/jsc.cpp:2007 > + if (nameValue.toWTFString(globalObject->globalExec()) == "SyntaxError" Awesome!
Filip Pizlo
Comment 20 2016-06-07 15:09:43 PDT
(In reply to comment #19) > Comment on attachment 280737 [details] > almost the patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=280737&action=review > > Neat! I pointed out some places where you could use a few more ES6 features > / syntax, since that seemed to be a goal. > > > PerformanceTests/JSAir/arg.js:83 > > + switch (role) > > + { > > Weird style. Ooops! Fixed. > > > PerformanceTests/JSAir/basic_block.js:76 > > + get: function(target, property) { > > Style: With ES6 shorthand style you could write these as: > > get(target, property) { > ... > }, > > set(target, property, value) { > ... > } > > You use this pattern in other places. Fixed! > > > PerformanceTests/JSAir/code.js:41 > > + addBlock(frequency) > > + { > > + if (frequency == null) > > + frequency = 1; > > You use this pattern a bunch. If you want to use more ES6 features you could > test default parameter values: > > addBlock(frequency=1) Filed: https://bugs.webkit.org/show_bug.cgi?id=158497 > > > PerformanceTests/JSAir/code.js:49 > > + let result = addIndexed(this._stackSlots, StackSlot, byteSize, kind); > > + return result; > > Drop the temporary variable and make this a tail call? I wanted to see where I got into addIndexed() from, so I wrote it this way to avoid the tail call. I like that I can control PTC. > > > PerformanceTests/JSAir/code.js:55 > > + let result = addIndexed(this["_" + symbolName(type).toLowerCase() + "Tmps"], Tmp, type); > > + return result; > > Drop the temporary variable and make this a tail call? Ditto. > > > PerformanceTests/JSAir/code.js:96 > > + if (this._frameSize) > > + result += "Frame size: " + this._frameSize + "\n"; > > + if (this._callArgAreaSize) > > + result += "Call arg area size: " + this._callArgAreaSize + "\n"; > > If you want to test more ES6 features, you could use template strings and > interpolation in a lot of these toString methods and other places: > > if (this._frameSize) > result += `Frame size: ${this._frameSize}\n`; > if (this._callArgAreaSize) > result += `Call arg area size: ${this._callArgAreaSize}\n`; Filed: https://bugs.webkit.org/show_bug.cgi?id=158497 > > > PerformanceTests/JSAir/custom.js:56 > > + for (let i = 0; i < inst.args.length; ++i) { > > + inst.visitArg( > > + i, func, inst.patchArgData[i].role, inst.patchArgData[i].type, > > + inst.patchArgData[i].width); > > + } > > You could make use of ES6 destructuring here: > > let {role, type, width} = inst.patchArgData[i]; > inst.visitArg(i, func, role, type, width); Ditto. > > > PerformanceTests/JSAir/inst.js:130 > > + return "" + symbolName(this._opcode) + " " + this._args.join(", "); > > The "" + at the start seems unnecessary. symbolName appears to always return > a string. Yeah, this is an old style of mine. I guess that this should use interpolation. > > > PerformanceTests/JSAir/opcode.js:143 > > + case Nop: > > + break; > > + break; > > A lot of these seem to have duplicate breaks. Might be worth cleaning up in > the generator, but ultimately harmless. It's hard to avoid this given the complex logic of the generator. When it generates C++, it makes similar mistakes, and we have crazy macros for disabling compiler warnings for this purpose. > > > PerformanceTests/JSAir/test.html:28 > > + document.getElementById("result-summary").innerHTML = "That took " + result + " ms."; > > You could use `textContent` or `innerText` instead of `innerHTML`: > <http://caniuse.com/#search=textContent> I changed to use innerText, but how is that different? > > > PerformanceTests/JSAir/util.js:34 > > +function addIndexed(list, cons, ...args) > > +{ > > + let result = new cons(list.length, ...args); > > You have this pattern in a few places. It reminds me of bug 158438. Should I avoid it? > > > PerformanceTests/JSAir/util.js:170 > > +else if (preciseTime) > > This should probably be "if (this.preciseTime)" otherwise you will get a > ReferenceError in environments that do not have `global.performance` and no > preciseTime global, which I bet would be the case in node/v8. Oh right, I'm in strict mode. Fixed. > > > PerformanceTests/JSAir/util.js:173 > > +else > > + currentTime = function() { return 0 + new Date(); }; > > When I run this in the console I get: > > js> (0 + new Date()) > "0Tue Jun 07 2016 14:34:10 GMT-0700 (PDT)" > > You should probably just do: > > Date.now() > > Or: > > +new Date Fixed! > > > Source/JavaScriptCore/jsc.cpp:2007 > > + if (nameValue.toWTFString(globalObject->globalExec()) == "SyntaxError" > > Awesome!
Joseph Pecoraro
Comment 21 2016-06-07 15:18:39 PDT
> > > PerformanceTests/JSAir/util.js:34 > > > +function addIndexed(list, cons, ...args) > > > +{ > > > + let result = new cons(list.length, ...args); > > > > You have this pattern in a few places. It reminds me of bug 158438. > > Should I avoid it? Keep it! I was hoping to give encouragement for someone to peek at the bug, which I'm guessing this, and a few other places in this code that use this pattern, may be hitting. =)
Filip Pizlo
Comment 22 2016-06-07 18:35:00 PDT
(In reply to comment #18) > (In reply to comment #14) > > Comment on attachment 280735 [details] > > the patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=280735&action=review > > > > I'm not going to read every line, but LGTM > > > > > PerformanceTests/ChangeLog:21 > > > + - JSAir's largest hot function, which is anonymous, so we call it by its hash (ACLj8C). > > > > Maybe it's worth giving the anonymous function a name? > > I'll try to check this. It's probably an arrow function. Meh. It's a really stupid closure: function (arg, role, type, width) => { return arg.forEach(thing, role, type, width, func); } It ends up being huge because we inline arg.forEach(). > > > > > > PerformanceTests/JSAir/benchmark.js:1 > > > +"use strict"; > > > > I think it's nicer for this to go after copyright. It's less likely to be > > glanced over > > Same goes for in all other files. > > I wasn't sure if that worked or not. I'll fix this. Done. > > > > > > PerformanceTests/JSAir/opcode.js:736 > > > + break; > > > + break; > > > > Many duplicate breaks > > Yeah, this is generated code. The code generator isn't that smart. It does > the same thing when generating C++ code, and we make the compiler happy by > wrapping the breaks inside some horror. > > > > > > PerformanceTests/JSAir/payload-gbemu-executeIteration.js:1 > > > +"use strict"; > > > > Should we generate a copyright? > > Hmmm. I don't know how to copyright it to. I think that saying that it's > generated code conveys the right message. > > > > > > Source/JavaScriptCore/b3/air/AirDumpAsJS.h:37 > > > +// This is a joke. Various operations on Air are interesting from a benchmarking standpoint. We can > > > > "This is a joke." => "This is used for benchmarking." > > Right. :-) Fixed. > > > > > > Source/WTF/wtf/PrintStream.h:75 > > > + void println(const Types&... values) > > > > I will actually use this a lot
Filip Pizlo
Comment 23 2016-06-07 18:44:19 PDT
Csaba Osztrogonác
Comment 24 2016-06-09 07:42:22 PDT
(In reply to comment #23) > Landed in http://trac.webkit.org/changeset/201783 The new JSAir test made performance bots fail: Running JSAir/test.html (76 of 152) ERROR: layer at (0,0) size 800x600
Filip Pizlo
Comment 25 2016-06-09 10:32:28 PDT
(In reply to comment #24) > (In reply to comment #23) > > Landed in http://trac.webkit.org/changeset/201783 > > The new JSAir test made performance bots fail: > > Running JSAir/test.html (76 of 152) > ERROR: layer at (0,0) size 800x600 Why did the performance bots run this? Are they just looking for every .html file in every directory?
Csaba Osztrogonác
Comment 26 2016-06-09 11:20:43 PDT
(In reply to comment #25) > (In reply to comment #24) > > (In reply to comment #23) > > > Landed in http://trac.webkit.org/changeset/201783 > > > > The new JSAir test made performance bots fail: > > > > Running JSAir/test.html (76 of 152) > > ERROR: layer at (0,0) size 800x600 > > Why did the performance bots run this? Are they just looking for every > .html file in every directory? Yes, it runs all tests in PerformanceTests directory, except ones in Skipped file.
Filip Pizlo
Comment 27 2016-06-09 12:23:40 PDT
(In reply to comment #26) > (In reply to comment #25) > > (In reply to comment #24) > > > (In reply to comment #23) > > > > Landed in http://trac.webkit.org/changeset/201783 > > > > > > The new JSAir test made performance bots fail: > > > > > > Running JSAir/test.html (76 of 152) > > > ERROR: layer at (0,0) size 800x600 > > > > Why did the performance bots run this? Are they just looking for every > > .html file in every directory? > > Yes, it runs all tests in PerformanceTests directory, except ones in Skipped > file. Should be fixed: http://trac.webkit.org/changeset/201878
Note You need to log in before you can comment on or make changes to this bug.