Changeset 223161 in webkit


Ignore:
Timestamp:
Oct 10, 2017 5:53:59 PM (7 years ago)
Author:
sbarati@apple.com
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:
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r223159 r223161  
     12017-10-10  Saam Barati  <sbarati@apple.com>
     2
     3        Prototype structure transition should be a deferred transition
     4        https://bugs.webkit.org/show_bug.cgi?id=177734
     5
     6        Reviewed by Keith Miller.
     7
     8        Absence ObjectPropertyConditions work by verifying both that the Structure
     9        does not have a particular property and that its prototype has
     10        remained constant. However, the prototype transition was firing
     11        the transition watchpoint before setting the object's structure.
     12        This meant that isValid for Absence would never return false because
     13        the prototype changed. Clearly this is wrong. The reason this didn't
     14        break OPCs in general is that we'd also check if we could still watch
     15        the OPC. In this case, we can't still watch it because we're inspecting
     16        a structure with an invalidated transition watchpoint. To fix
     17        this weird quirk of the code, I'm making it so that doing a prototype
     18        transition uses the DeferredStructureTransitionWatchpointFire machinery.
     19       
     20        This patch also fixes some dead code that I left in regarding
     21        poly proto in OPC.
     22
     23        * bytecode/PropertyCondition.cpp:
     24        (JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
     25        * runtime/JSObject.cpp:
     26        (JSC::JSObject::setPrototypeDirect):
     27        * runtime/Structure.cpp:
     28        (JSC::Structure::changePrototypeTransition):
     29        * runtime/Structure.h:
     30
    1312017-10-10  Robin Morisset  <rmorisset@apple.com>
    232
  • trunk/Source/JavaScriptCore/bytecode/PropertyCondition.cpp

    r222827 r223161  
    123123        }
    124124
    125         JSObject* currentPrototype;
    126         if (structure->hasMonoProto())
    127             currentPrototype = structure->storedPrototypeObject();
    128         else {
    129             RELEASE_ASSERT(base);
    130             currentPrototype = jsDynamicCast<JSObject*>(*structure->vm(), base->getPrototypeDirect());
    131         }
    132 
    133         if (currentPrototype != prototype()) {
     125        if (structure->storedPrototypeObject() != prototype()) {
    134126            if (PropertyConditionInternal::verbose) {
    135127                dataLog(
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r223027 r223161  
    16351635   
    16361636    if (structure(vm)->hasMonoProto()) {
    1637         Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype);
     1637        DeferredStructureTransitionWatchpointFire deferred;
     1638        Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype, deferred);
    16381639        setStructure(vm, newStructure);
    16391640    } else
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r222827 r223161  
    546546}
    547547
    548 Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype)
     548Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype, DeferredStructureTransitionWatchpointFire& deferred)
    549549{
    550550    ASSERT(prototype.isObject() || prototype.isNull());
    551551
    552552    DeferGC deferGC(vm.heap);
    553     Structure* transition = create(vm, structure);
     553    Structure* transition = create(vm, structure, &deferred);
    554554
    555555    transition->m_prototype.set(vm, transition, prototype);
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r222827 r223161  
    182182    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, PropertyOffset&);
    183183    static Structure* removePropertyTransition(VM&, Structure*, PropertyName, PropertyOffset&);
    184     static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype);
     184    static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype, DeferredStructureTransitionWatchpointFire&);
    185185    JS_EXPORT_PRIVATE static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
    186186    JS_EXPORT_PRIVATE static Structure* toCacheableDictionaryTransition(VM&, Structure*, DeferredStructureTransitionWatchpointFire* = nullptr);
Note: See TracChangeset for help on using the changeset viewer.