[JSC] AI should convert IsCellWithType to constant when Structure set is finite
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Nov 2019 18:45:52 +0000 (18:45 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Nov 2019 18:45:52 +0000 (18:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204141

Reviewed by Saam Barati.

JSTests:

* stress/generator-cell-with-type.js: Added.
(shouldBe):
(shouldThrow):
(test):
(i.shouldThrow):

Source/JavaScriptCore:

We should fold IsCellWithType if Structure set is finite since we have a chance to know what JSType is.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

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

JSTests/ChangeLog
JSTests/stress/generator-cell-with-type.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

index c3dcde8..b740188 100644 (file)
@@ -1,3 +1,16 @@
+2019-11-13  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] AI should convert IsCellWithType to constant when Structure set is finite
+        https://bugs.webkit.org/show_bug.cgi?id=204141
+
+        Reviewed by Saam Barati.
+
+        * stress/generator-cell-with-type.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (test):
+        (i.shouldThrow):
+
 2019-11-12  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] JSC GC relies on CodeBlock is not PreciseAllocation
diff --git a/JSTests/stress/generator-cell-with-type.js b/JSTests/stress/generator-cell-with-type.js
new file mode 100644 (file)
index 0000000..dd7bcf3
--- /dev/null
@@ -0,0 +1,43 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+function *generator()
+{
+}
+
+function test(gen)
+{
+    var func = gen.next;
+    shouldBe(gen.next().done, true);
+    return func;
+}
+noInline(test);
+var gen = generator();
+for (var i = 0; i < 1e6; ++i)
+    test(gen);
+
+for (var i = 0; i < 1e6; ++i) {
+    test(gen);
+    shouldThrow(() => {
+        test({
+            __proto__: gen.__proto__
+        });
+    }, `TypeError: |this| should be a generator`);
+}
index d599d26..c3e6159 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-13  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] AI should convert IsCellWithType to constant when Structure set is finite
+        https://bugs.webkit.org/show_bug.cgi?id=204141
+
+        Reviewed by Saam Barati.
+
+        We should fold IsCellWithType if Structure set is finite since we have a chance to know what JSType is.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
 2019-11-12  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Put more things in IsoSubspace
index 32f801a..f0911d6 100644 (file)
@@ -1419,6 +1419,35 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             if (constantWasSet)
                 break;
         }
+
+        if (forNode(node->child1()).m_structure.isFinite()) {
+            bool constantWasSet = false;
+            switch (node->op()) {
+            case IsCellWithType: {
+                bool ok = true;
+                Optional<bool> result;
+                forNode(node->child1()).m_structure.forEach(
+                    [&](RegisteredStructure structure) {
+                        bool matched = structure->typeInfo().type() == node->queriedType();
+                        if (!result)
+                            result = matched;
+                        else {
+                            if (result.value() != matched)
+                                ok = false;
+                        }
+                    });
+                if (ok && result) {
+                    setConstant(node, jsBoolean(result.value()));
+                    constantWasSet = true;
+                }
+                break;
+            }
+            default:
+                break;
+            }
+            if (constantWasSet)
+                break;
+        }
         
         // FIXME: This code should really use AbstractValue::isType() and
         // AbstractValue::couldBeType().