Title: [229987] trunk
Revision
229987
Author
fpi...@apple.com
Date
2018-03-26 14:01:16 -0700 (Mon, 26 Mar 2018)

Log Message

DFG should know that CreateThis can be effectful
https://bugs.webkit.org/show_bug.cgi?id=184013

Reviewed by Saam Barati.

JSTests:

* stress/create-this-property-change.js: Added.
(Foo):
(RealBar):
(get if):
* stress/create-this-structure-change-without-cse.js: Added.
(Foo):
(RealBar):
(get if):
* stress/create-this-structure-change.js: Added.
(Foo):
(RealBar):
(get if):

Source/_javascript_Core:

As shown in the tests added in JSTests, CreateThis can be effectful if the constructor this
is a proxy.

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

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (229986 => 229987)


--- trunk/JSTests/ChangeLog	2018-03-26 21:00:30 UTC (rev 229986)
+++ trunk/JSTests/ChangeLog	2018-03-26 21:01:16 UTC (rev 229987)
@@ -1,3 +1,23 @@
+2018-03-26  Filip Pizlo  <fpi...@apple.com>
+
+        DFG should know that CreateThis can be effectful
+        https://bugs.webkit.org/show_bug.cgi?id=184013
+
+        Reviewed by Saam Barati.
+
+        * stress/create-this-property-change.js: Added.
+        (Foo):
+        (RealBar):
+        (get if):
+        * stress/create-this-structure-change-without-cse.js: Added.
+        (Foo):
+        (RealBar):
+        (get if):
+        * stress/create-this-structure-change.js: Added.
+        (Foo):
+        (RealBar):
+        (get if):
+
 2018-03-22  Yusuke Suzuki  <utatane....@gmail.com>
 
         [DFG] Introduces fused compare and jump

Added: trunk/JSTests/stress/create-this-property-change.js (0 => 229987)


--- trunk/JSTests/stress/create-this-property-change.js	                        (rev 0)
+++ trunk/JSTests/stress/create-this-property-change.js	2018-03-26 21:01:16 UTC (rev 229987)
@@ -0,0 +1,49 @@
+var globalO;
+
+function Foo()
+{
+    this.g = 42;
+}
+
+class RealBar extends Foo {
+    constructor()
+    {
+        var o = globalO;
+        var result = o.f;
+        super();
+        result += o.f;
+        this.result = result;
+    }
+}
+
+var doIntercept = false;
+var didExecuteFGetter = false;
+var Bar = new Proxy(RealBar, {
+    get: function(target, property, receiver) {
+        if (property == "prototype" && doIntercept) {
+            globalO.f = 666;
+            didExecuteFGetter = true;
+        }
+        return Reflect.get(target, property, receiver);
+    }
+});
+
+noInline(RealBar);
+
+for (var i = 0; i < 10000; ++i) {
+    (function() {
+        globalO = {f:43};
+        var result = new Bar().result;
+        if (result != 86)
+            throw "bad result in loop: " + result;
+    })();
+}
+
+doIntercept = true;
+globalO = {f:43};
+var result = new Bar().result;
+if (result != 709)
+    throw "bad result at end: " + result;
+if (!didExecuteFGetter)
+    throw "did not execute f getter";
+

Added: trunk/JSTests/stress/create-this-structure-change-without-cse.js (0 => 229987)


--- trunk/JSTests/stress/create-this-structure-change-without-cse.js	                        (rev 0)
+++ trunk/JSTests/stress/create-this-structure-change-without-cse.js	2018-03-26 21:01:16 UTC (rev 229987)
@@ -0,0 +1,51 @@
+var globalO;
+
+function Foo()
+{
+    this.f = 42;
+}
+
+class RealBar extends Foo {
+    constructor()
+    {
+        var o = globalO;
+        var result = o.f;
+        super();
+        result += o.f;
+        this.result = result;
+    }
+}
+
+var doIntercept = false;
+var didExecuteFGetter = false;
+var Bar = new Proxy(RealBar, {
+    get: function(target, property, receiver) {
+        if (property == "prototype" && doIntercept) {
+            globalO.__defineGetter__("f", function() {
+                didExecuteFGetter = true;
+                return 666;
+            });
+        }
+        return Reflect.get(target, property, receiver);
+    }
+});
+
+noInline(RealBar);
+
+for (var i = 0; i < 10000; ++i) {
+    (function() {
+        globalO = {f:43};
+        var result = new Bar().result;
+        if (result != 86)
+            throw "bad result in loop: " + result;
+    })();
+}
+
+doIntercept = true;
+globalO = {f:43};
+var result = new Bar().result;
+if (result != 709)
+    throw "bad result at end: " + result;
+if (!didExecuteFGetter)
+    throw "did not execute f getter";
+

Added: trunk/JSTests/stress/create-this-structure-change.js (0 => 229987)


--- trunk/JSTests/stress/create-this-structure-change.js	                        (rev 0)
+++ trunk/JSTests/stress/create-this-structure-change.js	2018-03-26 21:01:16 UTC (rev 229987)
@@ -0,0 +1,51 @@
+var globalO;
+
+function Foo()
+{
+    this.g = 42;
+}
+
+class RealBar extends Foo {
+    constructor()
+    {
+        var o = globalO;
+        var result = o.f;
+        super();
+        result += o.f;
+        this.result = result;
+    }
+}
+
+var doIntercept = false;
+var didExecuteFGetter = false;
+var Bar = new Proxy(RealBar, {
+    get: function(target, property, receiver) {
+        if (property == "prototype" && doIntercept) {
+            globalO.__defineGetter__("f", function() {
+                didExecuteFGetter = true;
+                return 666;
+            });
+        }
+        return Reflect.get(target, property, receiver);
+    }
+});
+
+noInline(RealBar);
+
+for (var i = 0; i < 10000; ++i) {
+    (function() {
+        globalO = {f:43};
+        var result = new Bar().result;
+        if (result != 86)
+            throw "bad result in loop: " + result;
+    })();
+}
+
+doIntercept = true;
+globalO = {f:43};
+var result = new Bar().result;
+if (result != 709)
+    throw "bad result at end: " + result;
+if (!didExecuteFGetter)
+    throw "did not execute f getter";
+

Modified: trunk/Source/_javascript_Core/ChangeLog (229986 => 229987)


--- trunk/Source/_javascript_Core/ChangeLog	2018-03-26 21:00:30 UTC (rev 229986)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-03-26 21:01:16 UTC (rev 229987)
@@ -1,3 +1,18 @@
+2018-03-26  Filip Pizlo  <fpi...@apple.com>
+
+        DFG should know that CreateThis can be effectful
+        https://bugs.webkit.org/show_bug.cgi?id=184013
+
+        Reviewed by Saam Barati.
+
+        As shown in the tests added in JSTests, CreateThis can be effectful if the constructor this
+        is a proxy.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
 2018-03-25  Saam Barati  <sbar...@apple.com>
 
         Fix typo in JSC option name

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (229986 => 229987)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-03-26 21:00:30 UTC (rev 229986)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-03-26 21:01:16 UTC (rev 229987)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -2274,6 +2274,7 @@
                 }
             }
         }
+        clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(m_graph, SpecFinalObject);
         break;
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (229986 => 229987)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-03-26 21:00:30 UTC (rev 229986)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-03-26 21:01:16 UTC (rev 229987)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -272,14 +272,6 @@
         write(MathDotRandomState);
         return;
 
-    case HasGenericProperty:
-    case HasStructureProperty:
-    case GetPropertyEnumerator: {
-        read(World);
-        write(Heap);
-        return;
-    }
-
     case GetEnumerableLength: {
         read(Heap);
         write(SideState);
@@ -286,14 +278,6 @@
         return;
     }
 
-    case GetDirectPname: {
-        // This reads and writes heap because it can end up calling a generic getByVal 
-        // if the Structure changed, which could in turn end up calling a getter.
-        read(World);
-        write(Heap);
-        return;
-    }
-
     case ToIndexString:
     case GetEnumeratorStructurePname:
     case GetEnumeratorGenericPname: {
@@ -537,11 +521,6 @@
         write(HeapObjectCount);
         return;
 
-    case ToObject:
-        read(World);
-        write(Heap);
-        return;
-
     case CallObjectConstructor:
         read(HeapObjectCount);
         write(HeapObjectCount);
@@ -548,7 +527,6 @@
         return;
 
     case ToThis:
-    case CreateThis:
         read(MiscFields);
         read(HeapObjectCount);
         write(HeapObjectCount);
@@ -645,6 +623,15 @@
     case PutDynamicVar:
     case ResolveScopeForHoistingFuncDeclInEval:
     case ResolveScope:
+    case ToObject:
+    case HasGenericProperty:
+    case HasStructureProperty:
+    case GetPropertyEnumerator:
+    case GetDirectPname:
+    case InstanceOfCustom:
+    case ToNumber:
+    case NumberToStringWithRadix:
+    case CreateThis:
         read(World);
         write(Heap);
         return;
@@ -1031,11 +1018,6 @@
         def(HeapLocation(InstanceOfLoc, JSCell_structureID, node->child1(), node->child2()), LazyNode(node));
         return;
 
-    case InstanceOfCustom:
-        read(World);
-        write(Heap);
-        return;
-
     case PutStructure:
         read(JSObject_butterfly);
         write(JSCell_structureID);
@@ -1571,12 +1553,6 @@
         def(PureValue(node));
         return;
 
-    case ToNumber: {
-        read(World);
-        write(Heap);
-        return;
-    }
-        
     case ToString:
     case CallStringConstructor:
         switch (node->child1().useKind()) {
@@ -1719,12 +1695,6 @@
         def(PureValue(node));
         return;
 
-    case NumberToStringWithRadix:
-        // If the radix is invalid, NumberToStringWithRadix can throw an error.
-        read(World);
-        write(Heap);
-        return;
-
     case NumberToStringWithValidRadixConstant:
         def(PureValue(node, node->validRadixConstant()));
         return;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to