Title: [223161] trunk/Source/_javascript_Core
Revision
223161
Author
sbar...@apple.com
Date
2017-10-10 17:53:59 -0700 (Tue, 10 Oct 2017)

Log Message

Prototype structure transition should be a deferred transition
https://bugs.webkit.org/show_bug.cgi?id=177734

Reviewed by Keith Miller.

Absence ObjectPropertyConditions work by verifying both that the Structure
does not have a particular property and that its prototype has
remained constant. However, the prototype transition was firing
the transition watchpoint before setting the object's structure.
This meant that isValid for Absence would never return false because
the prototype changed. Clearly this is wrong. The reason this didn't
break OPCs in general is that we'd also check if we could still watch
the OPC. In this case, we can't still watch it because we're inspecting
a structure with an invalidated transition watchpoint. To fix
this weird quirk of the code, I'm making it so that doing a prototype
transition uses the DeferredStructureTransitionWatchpointFire machinery.

This patch also fixes some dead code that I left in regarding
poly proto in OPC.

* bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
* runtime/JSObject.cpp:
(JSC::JSObject::setPrototypeDirect):
* runtime/Structure.cpp:
(JSC::Structure::changePrototypeTransition):
* runtime/Structure.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (223160 => 223161)


--- trunk/Source/_javascript_Core/ChangeLog	2017-10-11 00:37:49 UTC (rev 223160)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-10-11 00:53:59 UTC (rev 223161)
@@ -1,3 +1,33 @@
+2017-10-10  Saam Barati  <sbar...@apple.com>
+
+        Prototype structure transition should be a deferred transition
+        https://bugs.webkit.org/show_bug.cgi?id=177734
+
+        Reviewed by Keith Miller.
+
+        Absence ObjectPropertyConditions work by verifying both that the Structure 
+        does not have a particular property and that its prototype has
+        remained constant. However, the prototype transition was firing
+        the transition watchpoint before setting the object's structure.
+        This meant that isValid for Absence would never return false because
+        the prototype changed. Clearly this is wrong. The reason this didn't
+        break OPCs in general is that we'd also check if we could still watch
+        the OPC. In this case, we can't still watch it because we're inspecting
+        a structure with an invalidated transition watchpoint. To fix
+        this weird quirk of the code, I'm making it so that doing a prototype
+        transition uses the DeferredStructureTransitionWatchpointFire machinery.
+        
+        This patch also fixes some dead code that I left in regarding
+        poly proto in OPC.
+
+        * bytecode/PropertyCondition.cpp:
+        (JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::setPrototypeDirect):
+        * runtime/Structure.cpp:
+        (JSC::Structure::changePrototypeTransition):
+        * runtime/Structure.h:
+
 2017-10-10  Robin Morisset  <rmoris...@apple.com>
 
         Avoid allocating useless landingBlocks in DFGByteCodeParser::handleInlining()

Modified: trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp (223160 => 223161)


--- trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2017-10-11 00:37:49 UTC (rev 223160)
+++ trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2017-10-11 00:53:59 UTC (rev 223161)
@@ -122,15 +122,7 @@
             return false;
         }
 
-        JSObject* currentPrototype;
-        if (structure->hasMonoProto())
-            currentPrototype = structure->storedPrototypeObject();
-        else {
-            RELEASE_ASSERT(base);
-            currentPrototype = jsDynamicCast<JSObject*>(*structure->vm(), base->getPrototypeDirect());
-        }
-
-        if (currentPrototype != prototype()) {
+        if (structure->storedPrototypeObject() != prototype()) {
             if (PropertyConditionInternal::verbose) {
                 dataLog(
                     "Invalid because the prototype is ", structure->storedPrototype(), " even though "

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (223160 => 223161)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2017-10-11 00:37:49 UTC (rev 223160)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2017-10-11 00:53:59 UTC (rev 223161)
@@ -1634,7 +1634,8 @@
         prototype.asCell()->didBecomePrototype();
     
     if (structure(vm)->hasMonoProto()) {
-        Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype);
+        DeferredStructureTransitionWatchpointFire deferred;
+        Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype, deferred);
         setStructure(vm, newStructure);
     } else
         putDirect(vm, structure(vm)->polyProtoOffset(), prototype);

Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (223160 => 223161)


--- trunk/Source/_javascript_Core/runtime/Structure.cpp	2017-10-11 00:37:49 UTC (rev 223160)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp	2017-10-11 00:53:59 UTC (rev 223161)
@@ -545,12 +545,12 @@
     return transition;
 }
 
-Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype)
+Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype, DeferredStructureTransitionWatchpointFire& deferred)
 {
     ASSERT(prototype.isObject() || prototype.isNull());
 
     DeferGC deferGC(vm.heap);
-    Structure* transition = create(vm, structure);
+    Structure* transition = create(vm, structure, &deferred);
 
     transition->m_prototype.set(vm, transition, prototype);
 

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (223160 => 223161)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2017-10-11 00:37:49 UTC (rev 223160)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2017-10-11 00:53:59 UTC (rev 223161)
@@ -181,7 +181,7 @@
     static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
     JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, PropertyOffset&);
     static Structure* removePropertyTransition(VM&, Structure*, PropertyName, PropertyOffset&);
-    static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype);
+    static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype, DeferredStructureTransitionWatchpointFire&);
     JS_EXPORT_PRIVATE static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
     JS_EXPORT_PRIVATE static Structure* toCacheableDictionaryTransition(VM&, Structure*, DeferredStructureTransitionWatchpointFire* = nullptr);
     static Structure* toUncacheableDictionaryTransition(VM&, Structure*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to