Diff
Modified: trunk/LayoutTests/ChangeLog (129155 => 129156)
--- trunk/LayoutTests/ChangeLog 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/LayoutTests/ChangeLog 2012-09-20 19:51:58 UTC (rev 129156)
@@ -1,3 +1,13 @@
+2012-09-20 Geoffrey Garen <[email protected]>
+
+ Refactored the interpreter and JIT so they don't dictate closure layout
+ https://bugs.webkit.org/show_bug.cgi?id=97221
+
+ Reviewed by Oliver Hunt.
+
+ * fast/js/dfg-arguments-alias-activation-expected.txt: Added.
+ * fast/js/dfg-arguments-alias-activation.html: Added.
+
2012-09-20 Tony Chang <[email protected]>
Implement absolutely positioned flex items
Added: trunk/LayoutTests/fast/js/dfg-arguments-alias-activation-expected.txt (0 => 129156)
--- trunk/LayoutTests/fast/js/dfg-arguments-alias-activation-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-arguments-alias-activation-expected.txt 2012-09-20 19:51:58 UTC (rev 129156)
@@ -0,0 +1,403 @@
+This tests verifies access to captured arguments via an optimized-away arguments object.
+
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: f(1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+PASS: g(0, 1) should be 1 and is.
+
Added: trunk/LayoutTests/fast/js/dfg-arguments-alias-activation.html (0 => 129156)
--- trunk/LayoutTests/fast/js/dfg-arguments-alias-activation.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-arguments-alias-activation.html 2012-09-20 19:51:58 UTC (rev 129156)
@@ -0,0 +1,39 @@
+<p>This tests verifies access to captured arguments via an optimized-away arguments object.
+</p>
+<pre id="console"></pre>
+
+<script>
+function log(s)
+{
+ document.getElementById("console").appendChild(document.createTextNode(s + "\r\n"));
+}
+
+function shouldBe(a, aDescription, b)
+{
+ if (a == b) {
+ log("PASS: " + aDescription + " should be " + b + " and is.");
+ return;
+ }
+ log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
+}
+
+if (window.testRunner) {
+ testRunner.dumpAsText();
+}
+
+// In-bounds of declared and passed arguments.
+function f(x) {
+ return arguments[0] || function() { return x; };
+}
+
+// Out-of-bounds of declared arguments, in-bounds of passed arguments.
+function g(x) {
+ return arguments[1] || function() { return x; };
+}
+
+for (var i = 0; i < 200; ++i)
+ shouldBe(f(1), "f(1)", 1);
+
+for (var i = 0; i < 200; ++i)
+ shouldBe(g(0, 1), "g(0, 1)", 1);
+</script>
Modified: trunk/Source/_javascript_Core/ChangeLog (129155 => 129156)
--- trunk/Source/_javascript_Core/ChangeLog 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-09-20 19:51:58 UTC (rev 129156)
@@ -1,3 +1,61 @@
+2012-09-20 Geoffrey Garen <[email protected]>
+
+ Refactored the interpreter and JIT so they don't dictate closure layout
+ https://bugs.webkit.org/show_bug.cgi?id=97221
+
+ Reviewed by Oliver Hunt.
+
+ Capture may change the location of an argument for space efficiency. This
+ patch removes static assumptions about argument location from the interpreter
+ and JIT.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::argumentIndexAfterCapture):
+ (JSC::ExecState::argumentAfterCapture): Factored out a helper function
+ so the compiler could share this logic.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BracketAccessorNode::emitBytecode): Don't emit optimized bracket
+ access on arguments if a parameter has been captured by name. This case is
+ rare and, where I've seen it in the wild, the optimization mostly failed
+ anyway due to arguments escape, so I didn't feel like writing and testing
+ five copies of the code that would handle it in the baseline engines.
+
+ The DFG can still synthesize this optimization even if we don't emit the
+ optimized bytecode for it.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::symbolTableFor):
+ (AssemblyHelpers): Use the right helper function to account for the fact
+ that a parameter may have been captured by name and moved.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): ASSERT that we haven't inlined
+ a .apply on captured arguments. Once we do start inlining such things,
+ we'll need to do a little bit of math here to get them right.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Added support for bracket access on
+ an arguments object where arguments have also been captured by name. We
+ load the true index of the argument from a side vector. Arguments elision
+ is very powerful in the DFG, so I wanted to keep it working, even in this
+ rare case.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::loadVarargs): Use the right helper function to account for the fact
+ that a parameter may have been captured by name and moved.
+
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileLoadVarargs): Don't use the inline copy loop if some
+ of our arguments have moved, since it would copy stale values. (We still
+ optimize the actual call, and elide the arguments object.)
+
2012-09-20 Gabor Rapcsanyi <[email protected]>
[Qt] r129045 broke the ARM build
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (129155 => 129156)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-09-20 19:51:58 UTC (rev 129156)
@@ -432,6 +432,8 @@
unsigned instructionCount() { return m_instructions.size(); }
+ int argumentIndexAfterCapture(size_t argument);
+
#if ENABLE(JIT)
void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck)
{
@@ -1520,7 +1522,19 @@
return baselineCodeBlock;
}
+ inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
+ {
+ if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
+ return CallFrame::argumentOffset(argument);
+ const SlowArgument* slowArguments = symbolTable()->slowArguments();
+ if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
+ return CallFrame::argumentOffset(argument);
+
+ ASSERT(slowArguments[argument].status == SlowArgument::Captured);
+ return slowArguments[argument].indexIfCaptured;
+ }
+
inline Register& ExecState::r(int index)
{
CodeBlock* codeBlock = this->codeBlock();
@@ -1552,15 +1566,7 @@
if (!codeBlock())
return this[argumentOffset(argument)].jsValue();
- if (argument >= static_cast<size_t>(codeBlock()->symbolTable()->parameterCount()))
- return this[argumentOffset(argument)].jsValue();
-
- const SlowArgument* slowArguments = codeBlock()->symbolTable()->slowArguments();
- if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
- return this[argumentOffset(argument)].jsValue();
-
- ASSERT(slowArguments[argument].status == SlowArgument::Captured);
- return this[slowArguments[argument].indexIfCaptured].jsValue();
+ return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
}
#if ENABLE(DFG_JIT)
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -320,7 +320,9 @@
RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_base->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())) {
+ if (m_base->isResolveNode()
+ && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())
+ && !generator.symbolTable().slowArguments()) {
RegisterID* property = generator.emitNode(m_subscript);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
Modified: trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -584,8 +584,8 @@
node.convertToGetLocalUnlinked(
static_cast<VirtualRegister>(
node.codeOrigin.inlineCallFrame->stackOffset +
- argumentToOperand(index + 1)));
-
+ m_graph.baselineCodeBlockFor(node.codeOrigin)->argumentIndexAfterCapture(index)));
+
NodeIndex checkNodeIndex = m_graph.size();
m_graph.append(check);
insertionSet.append(indexInBlock, checkNodeIndex);
Modified: trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h (129155 => 129156)
--- trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h 2012-09-20 19:51:58 UTC (rev 129156)
@@ -343,6 +343,25 @@
return argumentsRegisterFor(codeOrigin.inlineCallFrame);
}
+ SharedSymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
+ {
+ return baselineCodeBlockFor(codeOrigin)->symbolTable();
+ }
+
+ int offsetOfLocals(const CodeOrigin& codeOrigin)
+ {
+ if (!codeOrigin.inlineCallFrame)
+ return 0;
+ return codeOrigin.inlineCallFrame->stackOffset * sizeof(Register);
+ }
+
+ int offsetOfArgumentsIncludingThis(const CodeOrigin& codeOrigin)
+ {
+ if (!codeOrigin.inlineCallFrame)
+ return CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register);
+ return (codeOrigin.inlineCallFrame->stackOffset + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
+ }
+
Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
static const double twoToThe32;
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -2714,6 +2714,7 @@
case op_call_varargs: {
ASSERT(m_inlineStackTop->m_inlineCallFrame);
ASSERT(currentInstruction[3].u.operand == m_inlineStackTop->m_codeBlock->argumentsRegister());
+ ASSERT(!m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments());
// It would be cool to funnel this into handleCall() so that it can handle
// inlining. But currently that won't be profitable anyway, since none of the
// uses of call_varargs will be inlineable. So we set this up manually and
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -4202,23 +4202,50 @@
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, indexIfCaptured)),
+ resultPayloadGPR);
+
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ resultTagGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ resultPayloadGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultPayloadGPR);
- size_t baseOffset =
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
+ slowArgument.link(&m_jit);
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
break;
}
@@ -4252,21 +4279,46 @@
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, indexIfCaptured)),
+ resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ resultTagGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ resultPayloadGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultPayloadGPR);
- size_t baseOffset =
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
if (node.codeOrigin.inlineCallFrame) {
@@ -4284,6 +4336,7 @@
m_jit.argumentsRegisterFor(node.codeOrigin), indexGPR));
}
+ slowArgument.link(&m_jit);
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -4122,7 +4122,7 @@
GPRTemporary result(this);
GPRReg indexGPR = index.gpr();
GPRReg resultGPR = result.gpr();
-
+
if (!isEmptySpeculation(
m_state.variables().operand(
m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
@@ -4150,18 +4150,40 @@
resultGPR,
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
-
+
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, indexIfCaptured)),
+ resultGPR);
+ m_jit.signExtend32ToPtr(resultGPR, resultGPR);
+ m_jit.loadPtr(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ resultGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultGPR);
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.loadPtr(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight,
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
resultGPR);
+ slowArgument.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex);
break;
}
@@ -4194,15 +4216,36 @@
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, indexIfCaptured)),
+ resultGPR);
+ m_jit.signExtend32ToPtr(resultGPR, resultGPR);
+ m_jit.loadPtr(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ resultGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultGPR);
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.loadPtr(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight,
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
resultGPR);
if (node.codeOrigin.inlineCallFrame) {
@@ -4220,6 +4263,7 @@
indexGPR));
}
+ slowArgument.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex);
break;
}
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -202,7 +202,7 @@
newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
newCallFrame->setThisValue(thisValue);
for (size_t i = 0; i < callFrame->argumentCount(); ++i)
- newCallFrame->setArgument(i, callFrame->argument(i));
+ newCallFrame->setArgument(i, callFrame->argumentAfterCapture(i));
return newCallFrame;
}
Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/jit/JITCall.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -66,7 +66,11 @@
JumpList slowCase;
JumpList end;
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
+ bool canOptimize = m_codeBlock->usesArguments()
+ && arguments == m_codeBlock->argumentsRegister()
+ && !m_codeBlock->symbolTable()->slowArguments();
+
+ if (canOptimize) {
emitGetVirtualRegister(arguments, regT0);
slowCase.append(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue()))));
@@ -103,7 +107,7 @@
end.append(jump());
}
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
slowCase.link(this);
JITStubCall stubCall(this, cti_op_load_varargs);
@@ -112,7 +116,7 @@
stubCall.addArgument(Imm32(firstFreeRegister));
stubCall.call(regT1);
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
end.link(this);
}
Modified: trunk/Source/_javascript_Core/jit/JITCall32_64.cpp (129155 => 129156)
--- trunk/Source/_javascript_Core/jit/JITCall32_64.cpp 2012-09-20 19:49:33 UTC (rev 129155)
+++ trunk/Source/_javascript_Core/jit/JITCall32_64.cpp 2012-09-20 19:51:58 UTC (rev 129156)
@@ -141,7 +141,11 @@
JumpList slowCase;
JumpList end;
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
+ bool canOptimize = m_codeBlock->usesArguments()
+ && arguments == m_codeBlock->argumentsRegister()
+ && !m_codeBlock->symbolTable()->slowArguments();
+
+ if (canOptimize) {
emitLoadTag(arguments, regT1);
slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
@@ -180,7 +184,7 @@
end.append(jump());
}
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
slowCase.link(this);
JITStubCall stubCall(this, cti_op_load_varargs);
@@ -189,7 +193,7 @@
stubCall.addArgument(Imm32(firstFreeRegister));
stubCall.call(regT3);
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
end.link(this);
}