DFG folding of PutById to SimpleReplace should consider the specialized function...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2013 20:51:24 +0000 (20:51 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2013 20:51:24 +0000 (20:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=113093

Reviewed by Geoffrey Garen and Mark Hahnenberg.

Source/JavaScriptCore:

* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFor):

LayoutTests:

* fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function-expected.txt: Added.
* fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.html: Added.
* fast/js/jsc-test-list:
* fast/js/script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js: Added.
(foo):
(baz):
(fuzz):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@146653 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.html [new file with mode: 0644]
LayoutTests/fast/js/jsc-test-list
LayoutTests/fast/js/script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/PutByIdStatus.cpp

index ba64d61..839d4bf 100644 (file)
@@ -1,3 +1,18 @@
+2013-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG folding of PutById to SimpleReplace should consider the specialized function case
+        https://bugs.webkit.org/show_bug.cgi?id=113093
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+
+        * fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function-expected.txt: Added.
+        * fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.html: Added.
+        * fast/js/jsc-test-list:
+        * fast/js/script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js: Added.
+        (foo):
+        (baz):
+        (fuzz):
+
 2013-03-22  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add failing test expectations to the test added by r146644 on Mac.
 2013-03-22  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add failing test expectations to the test added by r146644 on Mac.
diff --git a/LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function-expected.txt b/LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function-expected.txt
new file mode 100644 (file)
index 0000000..0dad93a
--- /dev/null
@@ -0,0 +1,211 @@
+Checks that the DFG CFA does the right things if it proves that a put_by_id is a simple replace when storing to a specialized function property.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+baz!
+PASS bar.call({f:baz}, baz) is "baz"
+fuzz!
+PASS bar.call({f:baz}, fuzz) is "fuzz"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.html b/LayoutTests/fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.html
new file mode 100644 (file)
index 0000000..20d40e3
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
index 943d4a3..854692d 100644 (file)
@@ -99,6 +99,7 @@ fast/js/dfg-branch-logical-not-peephole-around-osr-exit
 fast/js/dfg-branch-not-fail
 fast/js/dfg-captured-var-get-local
 fast/js/dfg-cfa-merge-with-dead-use-at-tail
 fast/js/dfg-branch-not-fail
 fast/js/dfg-captured-var-get-local
 fast/js/dfg-cfa-merge-with-dead-use-at-tail
+fast/js/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement
 fast/js/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof
diff --git a/LayoutTests/fast/js/script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js b/LayoutTests/fast/js/script-tests/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js
new file mode 100644 (file)
index 0000000..e66cf53
--- /dev/null
@@ -0,0 +1,32 @@
+description(
+"Checks that the DFG CFA does the right things if it proves that a put_by_id is a simple replace when storing to a specialized function property."
+);
+
+function foo(o, v) {
+    o.f = v;
+}
+
+// Warm up foo's put_by_id to make it look polymorphic.
+for (var i = 0; i < 100; ++i)
+    foo(i % 2 ? {a: 1} : {b: 2});
+
+function bar(f) {
+    foo(this, f);
+    return this.f();
+}
+
+function baz() {
+    debug("baz!");
+    return "baz";
+}
+
+for (var i = 0; i < 100; ++i)
+    shouldBe("bar.call({f:baz}, baz)", "\"baz\"");
+
+function fuzz() {
+    debug("fuzz!");
+    return "fuzz";
+}
+
+shouldBe("bar.call({f:baz}, fuzz)", "\"fuzz\"");
+
index 43d0015..6676d6b 100644 (file)
@@ -1,3 +1,13 @@
+2013-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG folding of PutById to SimpleReplace should consider the specialized function case
+        https://bugs.webkit.org/show_bug.cgi?id=113093
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+
 2013-03-22  David Kilzer  <ddkilzer@apple.com>
 
         BUILD FIX (r146558): Build testapi.mm with ARC enabled for armv7s
 2013-03-22  David Kilzer  <ddkilzer@apple.com>
 
         BUILD FIX (r146558): Build testapi.mm with ARC enabled for armv7s
index 7d6ba09..b7cffd8 100644 (file)
@@ -147,11 +147,16 @@ PutByIdStatus PutByIdStatus::computeFor(JSGlobalData& globalData, JSGlobalObject
         return PutByIdStatus(TakesSlowPath);
     
     unsigned attributes;
         return PutByIdStatus(TakesSlowPath);
     
     unsigned attributes;
-    JSCell* specificValueIgnored;
-    PropertyOffset offset = structure->get(globalData, ident, attributes, specificValueIgnored);
+    JSCell* specificValue;
+    PropertyOffset offset = structure->get(globalData, ident, attributes, specificValue);
     if (isValidOffset(offset)) {
         if (attributes & (Accessor | ReadOnly))
             return PutByIdStatus(TakesSlowPath);
     if (isValidOffset(offset)) {
         if (attributes & (Accessor | ReadOnly))
             return PutByIdStatus(TakesSlowPath);
+        if (specificValue) {
+            // We need the PutById slow path to verify that we're storing the right value into
+            // the specialized slot.
+            return PutByIdStatus(TakesSlowPath);
+        }
         return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
     }
     
         return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
     }