⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201562 in webkit


Ignore:
Timestamp:
Jun 1, 2016, 12:32:34 PM (10 years ago)
Author:
ggaren@apple.com
Message:

Dictionary property access should be fast
https://bugs.webkit.org/show_bug.cgi?id=158250

Reviewed by Keith Miller.

We have some remnant code that unnecessarily takes a slow path for
dictionaries. This caused the Dromaeo regression in r201436. Let's fix
that.

  • jit/Repatch.cpp:

(JSC::tryCacheGetByID): Attempt to flatten a dictionary if necessary, but
not too much. This is our idiom in other places.

(JSC::tryCachePutByID): See tryCacheGetByID.

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::setupGetByIdPrototypeCache): See tryCacheGetByID.

  • runtime/JSObject.cpp:

(JSC::JSObject::fillGetterPropertySlot):

  • runtime/JSObject.h:

(JSC::JSObject::fillCustomGetterPropertySlot): The rules for caching a
getter are the same as the rules for caching anything else: We're
allowed to cache even in dictionaries, as long as they're cacheable
dictionaries. Any transition that would change to/from getter/setter
or change other attributes requires a structure transition.

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r201544 r201562  
     12016-05-31  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Dictionary property access should be fast
     4        https://bugs.webkit.org/show_bug.cgi?id=158250
     5
     6        Reviewed by Keith Miller.
     7
     8        We have some remnant code that unnecessarily takes a slow path for
     9        dictionaries. This caused the Dromaeo regression in r201436. Let's fix
     10        that.
     11
     12        * jit/Repatch.cpp:
     13        (JSC::tryCacheGetByID): Attempt to flatten a dictionary if necessary, but
     14        not too much. This is our idiom in other places.
     15
     16        (JSC::tryCachePutByID): See tryCacheGetByID.
     17
     18        * llint/LLIntSlowPaths.cpp:
     19        (JSC::LLInt::setupGetByIdPrototypeCache): See tryCacheGetByID.
     20
     21        * runtime/JSObject.cpp:
     22        (JSC::JSObject::fillGetterPropertySlot):
     23        * runtime/JSObject.h:
     24        (JSC::JSObject::fillCustomGetterPropertySlot): The rules for caching a
     25        getter are the same as the rules for caching anything else: We're
     26        allowed to cache even in dictionaries, as long as they're cacheable
     27        dictionaries. Any transition that would change to/from getter/setter
     28        or change other attributes requires a structure transition.
     29
    1302016-05-31  Yusuke Suzuki  <utatane.tea@gmail.com>
    231
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r200623 r201562  
    298298
    299299        if (slot.isUnset() || slot.slotBase() != baseValue) {
    300             if (structure->typeInfo().prohibitsPropertyCaching() || structure->isDictionary())
     300            if (structure->typeInfo().prohibitsPropertyCaching())
    301301                return GiveUpOnCache;
     302
     303            if (structure->isDictionary()) {
     304                if (structure->hasBeenFlattenedBefore())
     305                    return GiveUpOnCache;
     306                structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseCell));
     307            }
    302308           
    303309            if (slot.isUnset() && structure->typeInfo().getOwnPropertySlotIsImpureForPropertyAbsence())
     
    446452            ASSERT(slot.type() == PutPropertySlot::NewProperty);
    447453
    448             if (!structure->isObject() || structure->isDictionary())
     454            if (!structure->isObject())
    449455                return GiveUpOnCache;
     456
     457            if (structure->isDictionary()) {
     458                if (structure->hasBeenFlattenedBefore())
     459                    return GiveUpOnCache;
     460                structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseValue));
     461            }
    450462
    451463            PropertyOffset offset;
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r201448 r201562  
    20022002NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue getterSetter, unsigned attributes, PropertyOffset offset)
    20032003{
    2004     if (structure()->isDictionary()) {
     2004    if (structure()->isUncacheableDictionary()) {
    20052005        slot.setGetterSlot(this, attributes, jsCast<GetterSetter*>(getterSetter));
    20062006        return;
    20072007    }
     2008
     2009    // This access is cacheable because Structure requires an attributeChangedTransition
     2010    // if this property stops being an accessor.
    20082011    slot.setCacheableGetterSlot(this, attributes, jsCast<GetterSetter*>(getterSetter), offset);
    20092012}
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r201448 r201562  
    12261226ALWAYS_INLINE void JSObject::fillCustomGetterPropertySlot(PropertySlot& slot, JSValue customGetterSetter, unsigned attributes, Structure& structure)
    12271227{
    1228     if (structure.isDictionary()) {
     1228    if (structure.isUncacheableDictionary()) {
    12291229        slot.setCustom(this, attributes, jsCast<CustomGetterSetter*>(customGetterSetter)->getter());
    12301230        return;
    12311231    }
     1232
     1233    // This access is cacheable because Structure requires an attributeChangedTransition
     1234    // if this property stops being an accessor.
    12321235    slot.setCacheableCustom(this, attributes, jsCast<CustomGetterSetter*>(customGetterSetter)->getter());
    12331236}
Note: See TracChangeset for help on using the changeset viewer.