Diff
Modified: trunk/LayoutTests/ChangeLog (184259 => 184260)
--- trunk/LayoutTests/ChangeLog 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/LayoutTests/ChangeLog 2015-05-13 05:21:16 UTC (rev 184260)
@@ -1,3 +1,19 @@
+2015-05-12 Filip Pizlo <[email protected]>
+
+ js/dom/stack-trace.html fails with eager compilation
+ https://bugs.webkit.org/show_bug.cgi?id=144853
+
+ Reviewed by Benjamin Poulain.
+
+ Make a copy of the stack-trace test that only runs in run-jsc-stress-tests. Sadly, we don't
+ have a good way of having different expectation files for when a test runs in RJST versus
+ RWT. So, the approach I take is that I make a copy of the test just for RJST and I exclude
+ the .html file, which makes RWT overlook it. The test has different expectations in the
+ two harnesses because it does some small DOM things.
+
+ * js/script-tests/stack-trace.js: Added.
+ * js/stack-trace-expected.txt: Added.
+
2015-05-12 Joanmarie Diggs <[email protected]>
AX: [Win] REGRESSION(r184213) breaks aria-menubar-menuitems.html
Added: trunk/LayoutTests/js/script-tests/stack-trace.js (0 => 184260)
--- trunk/LayoutTests/js/script-tests/stack-trace.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/stack-trace.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,371 @@
+if (!this.alert) {
+ debug = print;
+ description = print;
+}
+
+description(
+'This test checks stack trace corectness in special cases.'
+);
+
+function stackTraceLineFor(stackTrace, frameIndex) {
+ var i = frameIndex;
+ var indexOfAt = stackTrace[i].indexOf('@')
+ var indexOfLastSlash = stackTrace[i].lastIndexOf('/');
+ if (indexOfLastSlash == -1)
+ indexOfLastSlash = indexOfAt
+ var functionName = stackTrace[i].substring(0, indexOfAt);
+ var fileName = stackTrace[i].substring(indexOfLastSlash + 1);
+ return functionName + " at " + fileName;
+}
+
+function printStack(stackTrace) {
+ debug("--> Stack Trace:")
+ stackTrace = stackTrace.split("\n");
+ var length = Math.min(stackTrace.length, 100);
+ for (var i = 0; i < length; i++)
+ debug(" " + i + " " + stackTraceLineFor(stackTrace, i));
+ debug('');
+}
+
+function dumpPattern(pattern) {
+ for (var i = 0; i < pattern.length; i++)
+ debug(" " + i + " " + pattern[i]);
+}
+
+function matchesPatternAtLine(pattern, patternIndex, traceLine) {
+ var patternLine = pattern[patternIndex];
+ return traceLine.slice(0, patternLine.length) == patternLine;
+}
+
+function matchPattern(pattern, traceLine) {
+ for (var i = 0; i < pattern.length; i++) {
+ if (matchesPatternAtLine(pattern, i, traceLine))
+ return i;
+ }
+ return -1;
+}
+
+function checkStackForPattern(stackTrace, pattern) {
+ stackTrace = stackTrace.split("\n");
+ var length = Math.min(stackTrace.length, 100);
+
+ // Get the match in the pattern for the first line:
+ var firstStackTraceLine = stackTraceLineFor(stackTrace, 0);
+ var patternIndex = matchPattern(pattern, firstStackTraceLine);
+ if (patternIndex < 0) {
+ debug("--> Stack Trace FAILED to match pattern:")
+ dumpPattern(pattern);
+ debug('');
+ return;
+ }
+
+ for (var i = 1; i < length; i++) {
+ patternIndex = ++patternIndex % pattern.length;
+ var traceLine = stackTraceLineFor(stackTrace, i);
+ if (!matchesPatternAtLine(pattern, patternIndex, traceLine)) {
+ debug("--> Stack Trace FAILED to match pattern:")
+ dumpPattern(pattern);
+ debug('');
+ return;
+ }
+ }
+
+ debug("--> Stack Trace matches pattern:")
+ dumpPattern(pattern);
+ debug('');
+}
+
+function hostThrower() { Element.prototype.appendChild.call({ }, [{ }]); }
+function callbacker(f) { [0].map(f); }
+function outer(errorName) { inner(errorName); }
+function inner(errorName) { throw new Error("Error in " + errorName); }
+function evaler(code) { eval(code); }
+function normalOuter() { normalInner(); }
+function normalInner() { if(thisVarDoesntExist) failIfTrue("shouldFailBeforeThis") };
+function scripterInner() { htmlInner(); }
+function scripterOuter() { htmlOuter(); }
+ // Expected functions in stack trace
+// Normal Case
+try { normalOuter() } catch (e) { printStack(e.stack) } // normalOuter -> normalInner
+
+// Eval Case
+try { evaler("inner('inner eval');"); } catch (e) { printStack(e.stack) } // evaler -> eval -> inner
+try { evaler("outer('outer eval');"); } catch (e) { printStack(e.stack) } // evaler -> eval -> outer -> inner
+
+// Function Callback Case
+try { callbacker(inner('inner map')); } catch (e) { printStack(e.stack); } // callbacker -> map -> inner
+try { callbacker(outer('outer map')); } catch (e) { printStack(e.stack); } // callbacker -> map -> outer -> inner
+
+// Host Code Case
+try { hostThrower(); } catch (e) { printStack(e.stack); } // hostThrower
+
+try { scripterInner(); } catch (e) { printStack(e.stack) } // program -> scripter -> inner
+try { scripterOuter(); } catch (e) { printStack(e.stack) } // program -> scripter -> outer -> inner
+
+function selfRecursive1() { selfRecursive1();
+}
+
+
+try { selfRecursive1(); } catch (e) { printStack(e.stack) } // selfRecursive1 -> selfRecursive1 -> selfRecursive1 -> selfRecursive1 ...
+
+function selfRecursive2() {
+ // A little work to make the DFG kick in
+ for (var i = 0; i < 10; i++) {
+ if (i == 9)
+ selfRecursive2();
+ }
+}
+
+try { selfRecursive2(); } catch (e) { printStack(e.stack) } // selfRecursive2 -> selfRecursive2 -> selfRecursive2 -> selfRecursive2 ...
+
+function selfRecursive3() {
+ eval("selfRecursive3()");
+}
+
+try {
+ selfRecursive3();
+} catch (e) {
+ var pattern = [
+ " at eval code",
+ "eval at [native code]",
+ "selfRecursive3 at stack-trace.js"
+ ];
+ checkStackForPattern(e.stack, pattern);
+}
+
+var callCount = 0;
+
+function throwError() {
+ throw new Error();
+}
+
+var object = {
+ get getter1() {
+ var o = {
+ valueOf: function() {
+ throwError()
+ }
+ };
+ +o;
+ },
+ get getter2() {
+ var o = {
+ valueOf: throwError
+ };
+ +o;
+ },
+ get getter3() {
+ var o1 = {
+ valueOf: throwError
+ };
+ var o2 = {
+ valueOf: function () {
+ throwError();
+ }
+ };
+ if (callCount == 9998)
+ +o1;
+ if (callCount == 9999)
+ +o2;
+ },
+ nonInlineable : function () {
+ if (0) return [arguments, function(){}];
+ ++callCount;
+ if (callCount == 1) {
+ this.getter1;
+ } else if (callCount == 2) {
+ this.getter2;
+ } else {
+ this.getter3;
+ }
+ },
+ inlineable : function () {
+ this.nonInlineable();
+ }
+}
+
+function yetAnotherInlinedCall(o) {
+ o.inlineable();
+}
+
+function makeInlinableCall(o) {
+ for (var i = 0; i < 10000; i++) {
+ new yetAnotherInlinedCall(o);
+ }
+}
+for (var k = 0; k < 4; k++) {
+ try {
+ function g() {
+ var j = 0;
+ for (var i = 0; i < 1000; i++) {
+ j++;
+ makeInlinableCall(object);
+ }
+ }
+ [1].map(g);
+ } catch (e) {
+ printStack(e.stack);
+ }
+}
+
+function h() {
+ if (callCount++ == 1000)
+ throw new Error();
+ if (callCount > 1000) {
+ [].map.apply(undefined, throwError);
+ }
+}
+
+function mapTest(a) {
+ a.map(h);
+}
+
+function mapTestDriver() {
+ var a = [1,2,3];
+ for (var i = 0; i < 2000; i++)
+ mapTest(a);
+}
+
+try {
+ callCount = 0;
+ mapTestDriver()
+} catch(e) {
+ printStack(e.stack);
+}
+
+try {
+ mapTestDriver()
+} catch(e) {
+ printStack(e.stack);
+}
+
+var dfgFunctionShouldThrow = false;
+function dfgFunction() {
+ if (dfgFunctionShouldThrow) {
+ dfgFunctionShouldThrow = false;
+ throwError();
+ }
+}
+
+for (var k = 0; k < 1000; k++)
+ dfgFunction();
+
+try {
+ dfgFunctionShouldThrow = true;
+ [1,2,3,4].map(dfgFunction);
+} catch (e) {
+ printStack(e.stack);
+}
+
+try {
+ var o = { };
+ o.__defineGetter__("g", dfgFunction);
+ function f(o) {
+ o.g;
+ }
+ for (var k = 0; k < 1000; k++)
+ f(o);
+
+ dfgFunctionShouldThrow = true;
+ f(o);
+
+} catch (e) {
+ printStack(e.stack);
+}
+
+var someValue = null;
+
+function callNonCallable() {
+ someValue();
+}
+
+for (var i = 0; i < 100; i++) {
+ try {
+ callNonCallable();
+ } catch (e) {
+ }
+}
+
+function dfgTest(f) {
+ dfgCount = 0;
+ while (dfgCount++ < 1000) {
+ try {
+ f();
+ } catch (e) {
+ printStack(e.stack)
+ return;
+ }
+ }
+}
+
+function inlineableThrow() {
+ if (dfgCount > 500) throw new Error();
+}
+
+var dfgThing = {
+ get willThrow() {
+ if (dfgCount > 500)
+ throw new Error();
+ },
+ get willThrowEventually() {
+ inlineableThrow();
+ },
+ willThrowFunc: function () { if (dfgCount > 500) throw new Error(); },
+ willThrowEventuallyFunc: function () { inlineableThrow(); }
+}
+dfgThing.__defineGetter__("hostWillThrow", hostThrower);
+
+function dfg1() {
+ dfgThing.willThrow
+}
+
+function dfg2() {
+ dfg1();
+}
+
+function dfg3() {
+ dfg2();
+}
+
+function dfg4() {
+ dfgThing.willThrowFunc();
+}
+
+function dfg5() {
+ dfg4();
+}
+
+function dfg6() {
+ dfg5();
+}
+
+function dfg7() {
+ dfgThing.willThrowEventually
+}
+
+function dfg8() {
+ dfg7();
+}
+
+function dfg9() {
+ dfg8();
+}
+
+function dfga() {
+ dfgThing.willThrowEventuallyFunc();
+}
+
+function dfgb() {
+ dfga();
+}
+
+function dfgc() {
+ dfgb();
+}
+
+dfgTest(dfg3)
+dfgTest(dfg6)
+dfgTest(dfg9)
+dfgTest(dfgc)
+
+successfullyParsed = true;
Added: trunk/LayoutTests/js/stack-trace-expected.txt (0 => 184260)
--- trunk/LayoutTests/js/stack-trace-expected.txt (rev 0)
+++ trunk/LayoutTests/js/stack-trace-expected.txt 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,362 @@
+This test checks stack trace corectness in special cases.
+--> Stack Trace:
+ 0 normalInner at stack-trace.js:84:47
+ 1 normalOuter at stack-trace.js:83:37
+ 2 global code at stack-trace.js:89:18
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:81:44
+ 1 at eval code
+ 2 eval at [native code]
+ 3 evaler at stack-trace.js:82:29
+ 4 global code at stack-trace.js:92:13
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:81:44
+ 1 outer at stack-trace.js:80:34
+ 2 at eval code
+ 3 eval at [native code]
+ 4 evaler at stack-trace.js:82:29
+ 5 global code at stack-trace.js:93:13
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:81:44
+ 1 global code at stack-trace.js:96:23
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:81:44
+ 1 outer at stack-trace.js:80:34
+ 2 global code at stack-trace.js:97:23
+
+--> Stack Trace:
+ 0 hostThrower at stack-trace.js:78:43
+ 1 global code at stack-trace.js:100:18
+
+--> Stack Trace:
+ 0 scripterInner at stack-trace.js:85:37
+ 1 global code at stack-trace.js:102:20
+
+--> Stack Trace:
+ 0 scripterOuter at stack-trace.js:86:37
+ 1 global code at stack-trace.js:103:20
+
+--> Stack Trace:
+ 0 selfRecursive1 at stack-trace.js:105:43
+ 1 selfRecursive1 at stack-trace.js:105:43
+ 2 selfRecursive1 at stack-trace.js:105:43
+ 3 selfRecursive1 at stack-trace.js:105:43
+ 4 selfRecursive1 at stack-trace.js:105:43
+ 5 selfRecursive1 at stack-trace.js:105:43
+ 6 selfRecursive1 at stack-trace.js:105:43
+ 7 selfRecursive1 at stack-trace.js:105:43
+ 8 selfRecursive1 at stack-trace.js:105:43
+ 9 selfRecursive1 at stack-trace.js:105:43
+ 10 selfRecursive1 at stack-trace.js:105:43
+ 11 selfRecursive1 at stack-trace.js:105:43
+ 12 selfRecursive1 at stack-trace.js:105:43
+ 13 selfRecursive1 at stack-trace.js:105:43
+ 14 selfRecursive1 at stack-trace.js:105:43
+ 15 selfRecursive1 at stack-trace.js:105:43
+ 16 selfRecursive1 at stack-trace.js:105:43
+ 17 selfRecursive1 at stack-trace.js:105:43
+ 18 selfRecursive1 at stack-trace.js:105:43
+ 19 selfRecursive1 at stack-trace.js:105:43
+ 20 selfRecursive1 at stack-trace.js:105:43
+ 21 selfRecursive1 at stack-trace.js:105:43
+ 22 selfRecursive1 at stack-trace.js:105:43
+ 23 selfRecursive1 at stack-trace.js:105:43
+ 24 selfRecursive1 at stack-trace.js:105:43
+ 25 selfRecursive1 at stack-trace.js:105:43
+ 26 selfRecursive1 at stack-trace.js:105:43
+ 27 selfRecursive1 at stack-trace.js:105:43
+ 28 selfRecursive1 at stack-trace.js:105:43
+ 29 selfRecursive1 at stack-trace.js:105:43
+ 30 selfRecursive1 at stack-trace.js:105:43
+ 31 selfRecursive1 at stack-trace.js:105:43
+ 32 selfRecursive1 at stack-trace.js:105:43
+ 33 selfRecursive1 at stack-trace.js:105:43
+ 34 selfRecursive1 at stack-trace.js:105:43
+ 35 selfRecursive1 at stack-trace.js:105:43
+ 36 selfRecursive1 at stack-trace.js:105:43
+ 37 selfRecursive1 at stack-trace.js:105:43
+ 38 selfRecursive1 at stack-trace.js:105:43
+ 39 selfRecursive1 at stack-trace.js:105:43
+ 40 selfRecursive1 at stack-trace.js:105:43
+ 41 selfRecursive1 at stack-trace.js:105:43
+ 42 selfRecursive1 at stack-trace.js:105:43
+ 43 selfRecursive1 at stack-trace.js:105:43
+ 44 selfRecursive1 at stack-trace.js:105:43
+ 45 selfRecursive1 at stack-trace.js:105:43
+ 46 selfRecursive1 at stack-trace.js:105:43
+ 47 selfRecursive1 at stack-trace.js:105:43
+ 48 selfRecursive1 at stack-trace.js:105:43
+ 49 selfRecursive1 at stack-trace.js:105:43
+ 50 selfRecursive1 at stack-trace.js:105:43
+ 51 selfRecursive1 at stack-trace.js:105:43
+ 52 selfRecursive1 at stack-trace.js:105:43
+ 53 selfRecursive1 at stack-trace.js:105:43
+ 54 selfRecursive1 at stack-trace.js:105:43
+ 55 selfRecursive1 at stack-trace.js:105:43
+ 56 selfRecursive1 at stack-trace.js:105:43
+ 57 selfRecursive1 at stack-trace.js:105:43
+ 58 selfRecursive1 at stack-trace.js:105:43
+ 59 selfRecursive1 at stack-trace.js:105:43
+ 60 selfRecursive1 at stack-trace.js:105:43
+ 61 selfRecursive1 at stack-trace.js:105:43
+ 62 selfRecursive1 at stack-trace.js:105:43
+ 63 selfRecursive1 at stack-trace.js:105:43
+ 64 selfRecursive1 at stack-trace.js:105:43
+ 65 selfRecursive1 at stack-trace.js:105:43
+ 66 selfRecursive1 at stack-trace.js:105:43
+ 67 selfRecursive1 at stack-trace.js:105:43
+ 68 selfRecursive1 at stack-trace.js:105:43
+ 69 selfRecursive1 at stack-trace.js:105:43
+ 70 selfRecursive1 at stack-trace.js:105:43
+ 71 selfRecursive1 at stack-trace.js:105:43
+ 72 selfRecursive1 at stack-trace.js:105:43
+ 73 selfRecursive1 at stack-trace.js:105:43
+ 74 selfRecursive1 at stack-trace.js:105:43
+ 75 selfRecursive1 at stack-trace.js:105:43
+ 76 selfRecursive1 at stack-trace.js:105:43
+ 77 selfRecursive1 at stack-trace.js:105:43
+ 78 selfRecursive1 at stack-trace.js:105:43
+ 79 selfRecursive1 at stack-trace.js:105:43
+ 80 selfRecursive1 at stack-trace.js:105:43
+ 81 selfRecursive1 at stack-trace.js:105:43
+ 82 selfRecursive1 at stack-trace.js:105:43
+ 83 selfRecursive1 at stack-trace.js:105:43
+ 84 selfRecursive1 at stack-trace.js:105:43
+ 85 selfRecursive1 at stack-trace.js:105:43
+ 86 selfRecursive1 at stack-trace.js:105:43
+ 87 selfRecursive1 at stack-trace.js:105:43
+ 88 selfRecursive1 at stack-trace.js:105:43
+ 89 selfRecursive1 at stack-trace.js:105:43
+ 90 selfRecursive1 at stack-trace.js:105:43
+ 91 selfRecursive1 at stack-trace.js:105:43
+ 92 selfRecursive1 at stack-trace.js:105:43
+ 93 selfRecursive1 at stack-trace.js:105:43
+ 94 selfRecursive1 at stack-trace.js:105:43
+ 95 selfRecursive1 at stack-trace.js:105:43
+ 96 selfRecursive1 at stack-trace.js:105:43
+ 97 selfRecursive1 at stack-trace.js:105:43
+ 98 selfRecursive1 at stack-trace.js:105:43
+ 99 selfRecursive1 at stack-trace.js:105:43
+
+--> Stack Trace:
+ 0 selfRecursive2 at stack-trace.js:115:27
+ 1 selfRecursive2 at stack-trace.js:115:27
+ 2 selfRecursive2 at stack-trace.js:115:27
+ 3 selfRecursive2 at stack-trace.js:115:27
+ 4 selfRecursive2 at stack-trace.js:115:27
+ 5 selfRecursive2 at stack-trace.js:115:27
+ 6 selfRecursive2 at stack-trace.js:115:27
+ 7 selfRecursive2 at stack-trace.js:115:27
+ 8 selfRecursive2 at stack-trace.js:115:27
+ 9 selfRecursive2 at stack-trace.js:115:27
+ 10 selfRecursive2 at stack-trace.js:115:27
+ 11 selfRecursive2 at stack-trace.js:115:27
+ 12 selfRecursive2 at stack-trace.js:115:27
+ 13 selfRecursive2 at stack-trace.js:115:27
+ 14 selfRecursive2 at stack-trace.js:115:27
+ 15 selfRecursive2 at stack-trace.js:115:27
+ 16 selfRecursive2 at stack-trace.js:115:27
+ 17 selfRecursive2 at stack-trace.js:115:27
+ 18 selfRecursive2 at stack-trace.js:115:27
+ 19 selfRecursive2 at stack-trace.js:115:27
+ 20 selfRecursive2 at stack-trace.js:115:27
+ 21 selfRecursive2 at stack-trace.js:115:27
+ 22 selfRecursive2 at stack-trace.js:115:27
+ 23 selfRecursive2 at stack-trace.js:115:27
+ 24 selfRecursive2 at stack-trace.js:115:27
+ 25 selfRecursive2 at stack-trace.js:115:27
+ 26 selfRecursive2 at stack-trace.js:115:27
+ 27 selfRecursive2 at stack-trace.js:115:27
+ 28 selfRecursive2 at stack-trace.js:115:27
+ 29 selfRecursive2 at stack-trace.js:115:27
+ 30 selfRecursive2 at stack-trace.js:115:27
+ 31 selfRecursive2 at stack-trace.js:115:27
+ 32 selfRecursive2 at stack-trace.js:115:27
+ 33 selfRecursive2 at stack-trace.js:115:27
+ 34 selfRecursive2 at stack-trace.js:115:27
+ 35 selfRecursive2 at stack-trace.js:115:27
+ 36 selfRecursive2 at stack-trace.js:115:27
+ 37 selfRecursive2 at stack-trace.js:115:27
+ 38 selfRecursive2 at stack-trace.js:115:27
+ 39 selfRecursive2 at stack-trace.js:115:27
+ 40 selfRecursive2 at stack-trace.js:115:27
+ 41 selfRecursive2 at stack-trace.js:115:27
+ 42 selfRecursive2 at stack-trace.js:115:27
+ 43 selfRecursive2 at stack-trace.js:115:27
+ 44 selfRecursive2 at stack-trace.js:115:27
+ 45 selfRecursive2 at stack-trace.js:115:27
+ 46 selfRecursive2 at stack-trace.js:115:27
+ 47 selfRecursive2 at stack-trace.js:115:27
+ 48 selfRecursive2 at stack-trace.js:115:27
+ 49 selfRecursive2 at stack-trace.js:115:27
+ 50 selfRecursive2 at stack-trace.js:115:27
+ 51 selfRecursive2 at stack-trace.js:115:27
+ 52 selfRecursive2 at stack-trace.js:115:27
+ 53 selfRecursive2 at stack-trace.js:115:27
+ 54 selfRecursive2 at stack-trace.js:115:27
+ 55 selfRecursive2 at stack-trace.js:115:27
+ 56 selfRecursive2 at stack-trace.js:115:27
+ 57 selfRecursive2 at stack-trace.js:115:27
+ 58 selfRecursive2 at stack-trace.js:115:27
+ 59 selfRecursive2 at stack-trace.js:115:27
+ 60 selfRecursive2 at stack-trace.js:115:27
+ 61 selfRecursive2 at stack-trace.js:115:27
+ 62 selfRecursive2 at stack-trace.js:115:27
+ 63 selfRecursive2 at stack-trace.js:115:27
+ 64 selfRecursive2 at stack-trace.js:115:27
+ 65 selfRecursive2 at stack-trace.js:115:27
+ 66 selfRecursive2 at stack-trace.js:115:27
+ 67 selfRecursive2 at stack-trace.js:115:27
+ 68 selfRecursive2 at stack-trace.js:115:27
+ 69 selfRecursive2 at stack-trace.js:115:27
+ 70 selfRecursive2 at stack-trace.js:115:27
+ 71 selfRecursive2 at stack-trace.js:115:27
+ 72 selfRecursive2 at stack-trace.js:115:27
+ 73 selfRecursive2 at stack-trace.js:115:27
+ 74 selfRecursive2 at stack-trace.js:115:27
+ 75 selfRecursive2 at stack-trace.js:115:27
+ 76 selfRecursive2 at stack-trace.js:115:27
+ 77 selfRecursive2 at stack-trace.js:115:27
+ 78 selfRecursive2 at stack-trace.js:115:27
+ 79 selfRecursive2 at stack-trace.js:115:27
+ 80 selfRecursive2 at stack-trace.js:115:27
+ 81 selfRecursive2 at stack-trace.js:115:27
+ 82 selfRecursive2 at stack-trace.js:115:27
+ 83 selfRecursive2 at stack-trace.js:115:27
+ 84 selfRecursive2 at stack-trace.js:115:27
+ 85 selfRecursive2 at stack-trace.js:115:27
+ 86 selfRecursive2 at stack-trace.js:115:27
+ 87 selfRecursive2 at stack-trace.js:115:27
+ 88 selfRecursive2 at stack-trace.js:115:27
+ 89 selfRecursive2 at stack-trace.js:115:27
+ 90 selfRecursive2 at stack-trace.js:115:27
+ 91 selfRecursive2 at stack-trace.js:115:27
+ 92 selfRecursive2 at stack-trace.js:115:27
+ 93 selfRecursive2 at stack-trace.js:115:27
+ 94 selfRecursive2 at stack-trace.js:115:27
+ 95 selfRecursive2 at stack-trace.js:115:27
+ 96 selfRecursive2 at stack-trace.js:115:27
+ 97 selfRecursive2 at stack-trace.js:115:27
+ 98 selfRecursive2 at stack-trace.js:115:27
+ 99 selfRecursive2 at stack-trace.js:115:27
+
+--> Stack Trace matches pattern:
+ 0 at eval code
+ 1 eval at [native code]
+ 2 selfRecursive3 at stack-trace.js
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 valueOf at stack-trace.js:146:27
+ 2 getter1 at stack-trace.js:149:11
+ 3 nonInlineable at stack-trace.js:175:17
+ 4 inlineable at stack-trace.js:183:27
+ 5 yetAnotherInlinedCall at stack-trace.js:188:17
+ 6 makeInlinableCall at stack-trace.js:193:34
+ 7 g at stack-trace.js:202:34
+ 8 map at [native code]
+ 9 global code at stack-trace.js:205:16
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 getter2 at stack-trace.js:155:11
+ 2 nonInlineable at stack-trace.js:177:17
+ 3 inlineable at stack-trace.js:183:27
+ 4 yetAnotherInlinedCall at stack-trace.js:188:17
+ 5 makeInlinableCall at stack-trace.js:193:34
+ 6 g at stack-trace.js:202:34
+ 7 map at [native code]
+ 8 global code at stack-trace.js:205:16
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 getter3 at stack-trace.js:167:16
+ 2 nonInlineable at stack-trace.js:179:17
+ 3 inlineable at stack-trace.js:183:27
+ 4 yetAnotherInlinedCall at stack-trace.js:188:17
+ 5 makeInlinableCall at stack-trace.js:193:34
+ 6 g at stack-trace.js:202:34
+ 7 map at [native code]
+ 8 global code at stack-trace.js:205:16
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 valueOf at stack-trace.js:163:27
+ 2 getter3 at stack-trace.js:169:16
+ 3 nonInlineable at stack-trace.js:179:17
+ 4 inlineable at stack-trace.js:183:27
+ 5 yetAnotherInlinedCall at stack-trace.js:188:17
+ 6 makeInlinableCall at stack-trace.js:193:34
+ 7 g at stack-trace.js:202:34
+ 8 map at [native code]
+ 9 global code at stack-trace.js:205:16
+
+--> Stack Trace:
+ 0 h at stack-trace.js:213:24
+ 1 map at [native code]
+ 2 mapTest at stack-trace.js:220:10
+ 3 mapTestDriver at stack-trace.js:226:16
+ 4 global code at stack-trace.js:231:18
+
+--> Stack Trace:
+ 0 map at [native code]
+ 1 h at stack-trace.js:215:21
+ 2 map at [native code]
+ 3 mapTest at stack-trace.js:220:10
+ 4 mapTestDriver at stack-trace.js:226:16
+ 5 global code at stack-trace.js:237:18
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 dfgFunction at stack-trace.js:246:19
+ 2 map at [native code]
+ 3 global code at stack-trace.js:255:18
+
+--> Stack Trace:
+ 0 throwError at stack-trace.js:139:20
+ 1 dfgFunction at stack-trace.js:246:19
+ 2 f at stack-trace.js:264:10
+ 3 global code at stack-trace.js:270:6
+
+--> Stack Trace:
+ 0 willThrow at stack-trace.js:308:28
+ 1 dfg1 at stack-trace.js:319:13
+ 2 dfg2 at stack-trace.js:323:9
+ 3 dfg3 at stack-trace.js:327:9
+ 4 dfgTest at stack-trace.js:293:14
+ 5 global code at stack-trace.js:366:8
+
+--> Stack Trace:
+ 0 willThrowFunc at stack-trace.js:313:69
+ 1 dfg4 at stack-trace.js:331:27
+ 2 dfg5 at stack-trace.js:335:9
+ 3 dfg6 at stack-trace.js:339:9
+ 4 dfgTest at stack-trace.js:293:14
+ 5 global code at stack-trace.js:367:8
+
+--> Stack Trace:
+ 0 inlineableThrow at stack-trace.js:302:40
+ 1 willThrowEventually at stack-trace.js:311:24
+ 2 dfg7 at stack-trace.js:343:13
+ 3 dfg8 at stack-trace.js:347:9
+ 4 dfg9 at stack-trace.js:351:9
+ 5 dfgTest at stack-trace.js:293:14
+ 6 global code at stack-trace.js:368:8
+
+--> Stack Trace:
+ 0 inlineableThrow at stack-trace.js:302:40
+ 1 willThrowEventuallyFunc at stack-trace.js:314:59
+ 2 dfga at stack-trace.js:355:37
+ 3 dfgb at stack-trace.js:359:9
+ 4 dfgc at stack-trace.js:363:9
+ 5 dfgTest at stack-trace.js:293:14
+ 6 global code at stack-trace.js:369:8
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: trunk/Source/_javascript_Core/ChangeLog (184259 => 184260)
--- trunk/Source/_javascript_Core/ChangeLog 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-05-13 05:21:16 UTC (rev 184260)
@@ -1,3 +1,72 @@
+2015-05-12 Filip Pizlo <[email protected]>
+
+ js/dom/stack-trace.html fails with eager compilation
+ https://bugs.webkit.org/show_bug.cgi?id=144853
+
+ Reviewed by Benjamin Poulain.
+
+ All of our escape analyses were mishandling Check(). They were assuming that this is a
+ non-escaping operation. But, if we do for example a Check(Int32:@x) and @x is an escape
+ candidate, then we need to do something: if we eliminate or sink @x, then the check no
+ longer makes any sense since a phantom allocation has no type. This will make us forget
+ that this operation would have exited. This was causing us to not call a valueOf method in
+ js/dom/stack-trace.html with eager compilation enabled, because it was doing something like
+ +o where o had a valueOf method, and o was otherwise sinkable.
+
+ This changes our escape analyses to basically pretend that any Check() that isn't obviously
+ unnecessary is an escape. We don't have to be super careful here. Most checks will be
+ completely eliminated by constant-folding. If that doesn't run in time, then the most
+ common check we will see is CellUse. So, we just recognize some very obvious check kinds
+ that we know would have passed, and for all of the rest we just assume that it's an escape.
+
+ This was super tricky to test. The obvious way to test it is to use +o like
+ stack-trace.html, except that doing so relies on the fact that we still haven't implemented
+ the optimal behavior for op_to_number. So, I take four approaches in testing this patch:
+
+ 1) Use +o. These will test what we want it to test for now, but at some point in the future
+ these tests will just be a good sanity-check that our op_to_number implementation is
+ right.
+
+ 2) Do fancy control flow tricks to fool the profiling into thinking that some arithmetic
+ operation always sees integers even though we eventually feed it an object and that
+ object is a sink candidate.
+
+ 3) Introduce a new jsc.cpp intrinsic called isInt32() which returns true if the incoming
+ value is an int32. This intrinsic is required to be implemented by DFG by
+ unconditionally speculating that the input is int32. This allows us to write much more
+ targetted tests of the underlying issue.
+
+ 4) I made a version of stack-trace.html that runs in run-jsc-stress-tests, so that we can
+ get regression test coverage of this test in eager mode.
+
+ * dfg/DFGArgumentsEliminationPhase.cpp:
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGObjectAllocationSinkingPhase.cpp:
+ (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+ * dfg/DFGVarargsForwardingPhase.cpp:
+ * ftl/FTLExitValue.cpp:
+ (JSC::FTL::ExitValue::dumpInContext):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+ * ftl/FTLOSRExitCompiler.cpp:
+ (JSC::FTL::compileFTLOSRExit):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionIsInt32):
+ * runtime/Intrinsic.h:
+ * tests/stress/sink-arguments-past-invalid-check-dfg.js: Added.
+ * tests/stress/sink-arguments-past-invalid-check-int32-dfg.js: Added.
+ * tests/stress/sink-arguments-past-invalid-check-int32.js: Added.
+ * tests/stress/sink-arguments-past-invalid-check-sneakier.js: Added.
+ * tests/stress/sink-arguments-past-invalid-check.js: Added.
+ * tests/stress/sink-function-past-invalid-check-sneakier.js: Added.
+ * tests/stress/sink-function-past-invalid-check-sneaky.js: Added.
+ * tests/stress/sink-object-past-invalid-check-int32.js: Added.
+ * tests/stress/sink-object-past-invalid-check-sneakier.js: Added.
+ * tests/stress/sink-object-past-invalid-check-sneaky.js: Added.
+ * tests/stress/sink-object-past-invalid-check.js: Added.
+
2015-05-12 Benjamin Poulain <[email protected]>
Fix the iteration count of arith-modulo-node-behaviors.js
Modified: trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -42,11 +42,14 @@
#include "JSCInlines.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/ListDump.h>
namespace JSC { namespace DFG {
namespace {
+bool verbose = false;
+
class ArgumentsEliminationPhase : public Phase {
public:
ArgumentsEliminationPhase(Graph& graph)
@@ -101,6 +104,9 @@
}
}
}
+
+ if (verbose)
+ dataLog("Candidates: ", listDump(m_candidates), "\n");
}
// Look for escaping sites, and remove from the candidates set if we see an escape.
@@ -160,6 +166,21 @@
break;
case Check:
+ m_graph.doToChildren(
+ node,
+ [&] (Edge edge) {
+ switch (edge.useKind()) {
+ case CellUse:
+ case ObjectUse:
+ break;
+
+ default:
+ escape(edge);
+ break;
+ }
+ });
+ break;
+
case MovHint:
case PutHint:
break;
@@ -189,6 +210,9 @@
}
}
}
+
+ if (verbose)
+ dataLog("After escape analysis: ", listDump(m_candidates), "\n");
}
// Anywhere that a candidate is live (in bytecode or in DFG), check if there is a chance of
@@ -331,6 +355,9 @@
// availabilities may become whatever. OSR exit should be able to handle this quite naturally,
// since those availabilities speak of the stack before the optimizing compiler stack frame is
// torn down.
+
+ if (verbose)
+ dataLog("After interference analysis: ", listDump(m_candidates), "\n");
}
void transform()
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -2111,6 +2111,16 @@
return true;
}
+ case CheckInt32Intrinsic: {
+ insertChecks();
+ for (int i = 1; i < argumentCountIncludingThis; ++i) {
+ Node* node = get(virtualRegisterForArgument(i, registerOffset));
+ addToGraph(Phantom, Edge(node, Int32Use));
+ }
+ set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
+ return true;
+ }
+
case FiatInt52Intrinsic: {
if (argumentCountIncludingThis != 2)
return false;
Modified: trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -828,25 +828,45 @@
case NewFunction:
if (!node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid())
sinkCandidate();
- m_graph.doToChildren(
- node,
- [&] (Edge edge) {
- escape(edge.node());
- });
+ escape(node->child1().node());
break;
case CreateActivation:
if (!m_graph.symbolTableFor(node->origin.semantic)->singletonScope()->isStillValid())
sinkCandidate();
+ escape(node->child1().node());
+ break;
+
+ case Check:
m_graph.doToChildren(
node,
[&] (Edge edge) {
- escape(edge.node());
+ bool ok = true;
+
+ switch (edge.useKind()) {
+ case KnownCellUse:
+ case CellUse:
+ case ObjectUse:
+ // All of our allocations will pass this.
+ break;
+
+ case FunctionUse:
+ // Function allocations will pass this.
+ if (edge->op() != NewFunction)
+ ok = false;
+ break;
+
+ default:
+ ok = false;
+ break;
+ }
+
+ if (!ok)
+ escape(edge.node());
});
break;
case MovHint:
- case Check:
case PutHint:
case StoreBarrier:
case StoreBarrierWithNullCheck:
Modified: trunk/Source/_javascript_Core/dfg/DFGVarargsForwardingPhase.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/dfg/DFGVarargsForwardingPhase.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/dfg/DFGVarargsForwardingPhase.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -104,7 +104,30 @@
relevantLocals.append(node->unlinkedLocal());
break;
- case Check:
+ case Check: {
+ bool sawEscape = false;
+ m_graph.doToChildren(
+ node,
+ [&] (Edge edge) {
+ switch (edge.useKind()) {
+ case CellUse:
+ case ObjectUse:
+ if (edge == candidate)
+ lastUserIndex = nodeIndex;
+ break;
+ default:
+ sawEscape = true;
+ break;
+ }
+ });
+ if (sawEscape) {
+ if (verbose)
+ dataLog(" Escape at ", node, "\n");
+ return;
+ }
+ break;
+ }
+
case LoadVarargs:
if (m_graph.uses(node, candidate))
lastUserIndex = nodeIndex;
Modified: trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -114,7 +114,7 @@
out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
return;
case ExitValueMaterializeNewObject:
- out.print("Materialize(", WTF::RawPointer(objectMaterialization()), ":..)");
+ out.print("Materialize(", WTF::RawPointer(objectMaterialization()), ")");
return;
}
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -8052,7 +8052,7 @@
if (!exit.m_materializations.isEmpty()) {
dataLog(" Materializations: \n");
for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
- dataLog(" Materialize(", pointerDump(materialization), ")\n");
+ dataLog(" ", pointerDump(materialization), "\n");
}
}
}
Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -477,6 +477,19 @@
JITCode* jitCode = codeBlock->jitCode()->ftl();
OSRExit& exit = jitCode->osrExit[exitID];
+ if (shouldShowDisassembly() || Options::verboseOSR() || Options::verboseFTLOSRExit()) {
+ dataLog(" Owning block: ", pointerDump(codeBlock), "\n");
+ dataLog(" Origin: ", exit.m_codeOrigin, "\n");
+ if (exit.m_codeOriginForExitProfile != exit.m_codeOrigin)
+ dataLog(" Origin for exit profile: ", exit.m_codeOriginForExitProfile, "\n");
+ dataLog(" Exit values: ", exit.m_values, "\n");
+ if (!exit.m_materializations.isEmpty()) {
+ dataLog(" Materializations:\n");
+ for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+ dataLog(" ", pointerDump(materialization), "\n");
+ }
+ }
+
prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
compileStub(exitID, jitCode, exit, vm, codeBlock);
Modified: trunk/Source/_javascript_Core/jsc.cpp (184259 => 184260)
--- trunk/Source/_javascript_Core/jsc.cpp 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/jsc.cpp 2015-05-13 05:21:16 UTC (rev 184260)
@@ -470,6 +470,7 @@
static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
@@ -620,6 +621,7 @@
putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum | JSC::Function);
putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isFinalTier"), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum | JSC::Function);
putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum | JSC::Function);
+ putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isInt32"), 0, functionIsInt32, CheckInt32Intrinsic, DontEnum | JSC::Function);
putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum | JSC::Function);
addFunction(vm, "effectful42", functionEffectful42, 0);
@@ -1056,6 +1058,14 @@
EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*) { return JSValue::encode(jsUndefined()); }
EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*) { return JSValue::encode(jsUndefined()); }
+EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState* exec)
+{
+ for (size_t i = 0; i < exec->argumentCount(); ++i) {
+ if (!exec->argument(i).isInt32())
+ return JSValue::encode(jsBoolean(false));
+ }
+ return JSValue::encode(jsBoolean(true));
+}
EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState* exec) { return JSValue::encode(exec->argument(0)); }
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (184259 => 184260)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2015-05-13 05:18:01 UTC (rev 184259)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2015-05-13 05:21:16 UTC (rev 184260)
@@ -60,6 +60,7 @@
OSRExitIntrinsic,
IsFinalTierIntrinsic,
SetInt32HeapPredictionIntrinsic,
+ CheckInt32Intrinsic,
FiatInt52Intrinsic,
};
Added: trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-dfg.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-dfg.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-dfg.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,17 @@
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; }
+
+function foo() {
+ globalResult = 0;
+ +arguments;
+ return globalResult;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo();
+ if (result !== 1)
+ throw "Error: bad result: " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32-dfg.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32-dfg.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32-dfg.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,12 @@
+function foo() {
+ return isInt32(arguments);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo();
+ if (result !== false)
+ throw "Error: bad result: " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-int32.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,24 @@
+function foo(p) {
+ var result = 42;
+ var o = arguments;
+ if (p)
+ result = isInt32(o);
+ return result;
+}
+
+noInline(foo);
+
+var result = foo(true);
+if (result !== false)
+ throw "Error: bad result at beginning: " + result;
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false);
+ if (result !== 42)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== false)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-sneakier.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-sneakier.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check-sneakier.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,37 @@
+function bar(o, p) {
+ var o2 = {f: 0};
+ if (p)
+ o2.f = o;
+ return +o2.f;
+}
+
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; };
+
+function foo(p, q) {
+ globalResult = 0;
+ var o = arguments;
+ if (p)
+ bar(o, q);
+ return globalResult;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i) {
+ bar(1, true);
+ bar({}, false);
+}
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false, true);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-arguments-past-invalid-check.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,23 @@
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; }
+
+function foo(p) {
+ globalResult = 0;
+ var o = arguments;
+ if (p)
+ +o;
+ return globalResult;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneakier.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneakier.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneakier.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,35 @@
+function bar(o, p) {
+ if (p)
+ return +o.f;
+ return 42;
+}
+
+var globalResult;
+Function.prototype.valueOf = function() { globalResult = 1; };
+
+function foo(p, q) {
+ globalResult = 0;
+ var o = function() { };
+ var o2 = {f: o};
+ if (p)
+ bar(o2, q);
+ return globalResult;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i)
+ bar({f:42}, true);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false, true);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneaky.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneaky.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-function-past-invalid-check-sneaky.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,13 @@
+function foo(p) {
+ var o = function() { };
+ var q = {f: p ? o : 42};
+ var tmp = q.f + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+ foo(false);
+
+foo(true);
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-int32.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-int32.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-int32.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,24 @@
+function foo(p) {
+ var result = 42;
+ var o = {};
+ if (p)
+ result = isInt32(o);
+ return result;
+}
+
+noInline(foo);
+
+var result = foo(true);
+if (result !== false)
+ throw "Error: bad result at end: " + result;
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false);
+ if (result !== 42)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== false)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneakier.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneakier.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneakier.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,32 @@
+function bar(o, p) {
+ if (p)
+ return +o.f;
+ return 42;
+}
+
+function foo(p, q) {
+ var result = 0;
+ var o = {valueOf: function() { result = 1; }};
+ var o2 = {f: o};
+ if (p)
+ bar(o2, q);
+ return result;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i)
+ bar({f:42}, true);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false, true);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneaky.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneaky.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check-sneaky.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,23 @@
+// https://bugs.webkit.org/show_bug.cgi?id=144945
+//@ skip
+
+function foo(p) {
+ var result = 0;
+ var o = {valueOf: function() { result = 1; }};
+ var q = {f: p ? o : 42};
+ var tmp = q.f + 1;
+ return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+
Added: trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check.js (0 => 184260)
--- trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/sink-object-past-invalid-check.js 2015-05-13 05:21:16 UTC (rev 184260)
@@ -0,0 +1,20 @@
+function foo(p) {
+ var result = 0;
+ var o = {valueOf:function() { result = 1; }};
+ if (p)
+ +o;
+ return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+ var result = foo(false);
+ if (result !== 0)
+ throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+ throw "Error: bad result at end: " + result;
+